diff --git a/.claude/rules/skill-guidance.md b/.claude/rules/skill-guidance.md index 57a0b4efd..a58559fe4 100644 --- a/.claude/rules/skill-guidance.md +++ b/.claude/rules/skill-guidance.md @@ -5,44 +5,62 @@ globs: '*' # Available Skills -This project has guided skills for common workflows. **Proactively suggest the relevant skill** when a user's request matches one of these: +This project has guided skills for `apps/lfx` (the primary app). **Always route through `/lfx` as the entry point** — it classifies intent and delegates to the right specialist skill. -| Skill | When to Suggest | -| ------------ | ----------------------------------------------------------------------------------------------------------------------------- | -| `/setup` | Getting started, first-time setup, broken environments, install failures, missing env vars, 1Password, how to run the app | -| `/develop` | Add a feature, fix a bug, modify code, create components/services/endpoints/types, refactor, build, implement any code change | -| `/preflight` | Before submitting a PR, check if code is ready, validate changes, verify a branch, finished development, review readiness | +--- + +## Entry Point -## Trigger Phrases +| Skill | When to Suggest | +| ------ | ------------------------------------------------------------------------------------------ | +| `/lfx` | **Always** — any request related to `apps/lfx` development, research, setup, or validation | -**`/setup`** — match any of these intents: +**`/lfx` is the default entry point for ALL work.** It auto-detects what the user needs and routes to the right specialist skill. Users never need to know about the specialist skills below. -- "How do I set up?", "Getting started", "First time here" -- "yarn install fails", "corepack error", "node version" -- "env vars", "1Password", "app won't start" -- "broken environment", "fresh install", "missing dependencies" +### Trigger Phrases -**`/develop`** — match any of these intents: +- Any code change: "Add a feature", "Fix this bug", "Build a component", "Implement this Figma URL" +- Research: "What endpoints exist?", "How does X work?", "Does the API support Y?" +- Validation: "Ready for PR", "Check my code", "Preflight" +- Setup: "Set up my environment", "Install", "Getting started" -- "Add a feature", "Create a component", "Build an endpoint" -- "Fix this bug", "Modify the service", "Update the page" -- "Refactor", "Implement", "Change the behavior" -- "New interface", "Add a filter", "Create a form" -- Describes any code change, feature request, or bug fix +--- -**`/preflight`** — match any of these intents: +## Specialist Skills (routed by `/lfx` — rarely invoked directly) -- "Ready for PR", "Check my code", "Validate changes" -- "Before I submit", "Is my branch ready?", "Review my work" -- "Run checks", "Lint and build", "Pre-PR validation" -- Any indication that development work is finished +| Skill | Purpose | +| ---------------------- | ------------------------------------------------------------------------------ | +| `/lfx-coordinator` | Plans and delegates code changes — routes to builder skills | +| `/lfx-design` | Builds base UI components (buttons, inputs, cards) from Figma | +| `/lfx-research` | Read-only exploration — upstream API validation, codebase discovery | +| `/lfx-backend-builder` | Generates Express proxy endpoints, services, controllers, routes, shared types | +| `/lfx-ui-builder` | Generates Angular frontend components, services, pages | +| `/lfx-preflight` | Pre-PR validation — lint, build, license headers | +| `/lfx-setup` | Environment setup — prerequisites, install, env vars, dev server | -## For Cowork Sessions +## Skill Hierarchy -Non-developer contributors use these skills as guided workflows. Follow these rules: +```text +/lfx (entry point — classifies intent, routes) + ├── /lfx-coordinator (plans + delegates code changes) + │ ├── /lfx-research (read-only exploration) + │ ├── /lfx-design (base UI components) + │ ├── /lfx-ui-builder (feature components) + │ └── /lfx-backend-builder (Express proxy code) + ├── /lfx-research (direct research without building) + ├── /lfx-preflight (pre-PR validation) + └── /lfx-setup (environment setup) +``` + +**Key rules:** + +- `/lfx` routes via Agent subagents — never inline Skill calls +- `/lfx-coordinator` delegates via Agent subagents — never writes code itself +- Builder skills (`/lfx-design`, `/lfx-ui-builder`, `/lfx-backend-builder`) are the only skills that write code +- No skill should call Figma MCP tools inline — only `/lfx-design` calls them within its Agent subprocess + +## For Cowork Sessions -- If the user describes a feature they want to build, suggest `/develop` — it walks them through the full process step-by-step -- If the user asks about setup or getting started, suggest `/setup` -- After any development work is complete, remind them to run `/preflight` before creating a PR -- If you are unsure which skill applies, ask the user what they're trying to accomplish -- When a skill references architecture docs in `docs/`, read those docs before generating code — they are the source of truth +- Contributor describes any task → suggest `/lfx` +- After development work → remind to run `/lfx-preflight` (or let `/lfx` suggest it) +- When a skill references architecture docs in `docs/`, read those docs before generating code diff --git a/.claude/settings.json b/.claude/settings.json index 9c46fc3a1..09033d4fa 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -11,5 +11,8 @@ ] } ] + }, + "enabledPlugins": { + "figma@claude-plugins-official": true } } diff --git a/.claude/skills/develop/SKILL.md b/.claude/skills/develop/SKILL.md deleted file mode 100644 index c9503d75d..000000000 --- a/.claude/skills/develop/SKILL.md +++ /dev/null @@ -1,248 +0,0 @@ ---- -name: develop -description: > - Guided development workflow for building, fixing, updating, or refactoring - code — components, services, backend endpoints, shared types, or full features. - Use whenever someone wants to add a feature, fix a bug, modify existing code, - create something new, refactor, or implement any code change. -allowed-tools: Bash, Read, Write, Edit, Glob, Grep, AskUserQuestion ---- - -# LFX One Development Guide - -You are helping a contributor build within the LFX One codebase. This skill handles all development work: creating new features, fixing bugs, modifying existing code, refactoring, and full end-to-end feature builds. - -**Important:** You are integrating features within existing architecture — not making architectural decisions. If the work requires changes to routing, auth, middleware, or infrastructure, flag it for a code owner. - -## Step 1: Start from Latest Main & Track Work - -Follow the "Starting New Work" rule in `development-rules.md` — checkout `main`, pull latest, and create a feature branch before writing any code. - -### JIRA Ticket - -Before writing code, ensure the work is tracked: - -1. **Check for an existing JIRA ticket** in the `LFXV2` project -2. **Create one if needed** — assign to the current user and current sprint -3. **Branch name must include the ticket:** `feat/LFXV2-`, `fix/LFXV2-`, etc. -4. Reference `.claude/rules/commit-workflow.md` for naming conventions - -## Step 2: Plan the Feature (Ideation) - -Ask the contributor what they're building. Before writing any code, create a plan that answers: - -1. **What is the feature?** — Describe the user-facing behavior -2. **What data does it need?** — Identify the API endpoints, request/response shapes, and data flow -3. **What upstream APIs are required?** — List which microservice endpoints the feature depends on -4. **Do the upstream microservices already support this?** — This is critical (see Step 3) -5. **What frontend components are needed?** — Pages, shared components, services - -### Scope for PR Size - -Before jumping into code, assess whether the planned work fits in a single PR. PRs that exceed ~1000 lines of diff become significantly harder to review, more likely to introduce bugs, and slower to merge. - -- **If the feature touches multiple layers** (types + backend + frontend) and the total diff is approaching the limit, consider splitting by layer — e.g., shared types first, then backend, then frontend. If all layers fit comfortably under 1000 lines, keep them in one PR. -- **If the feature has independent sub-features**, split them. A "committee management" feature might break into: list view, create form, edit/delete — each independently deliverable. -- **Separate refactors from features** — if existing code needs restructuring to support the new feature, do the refactor PR first. -- **Generated/mechanical changes get their own PR** — bulk renames, formatting, dependency bumps, or migration outputs should not be mixed with hand-written logic. - -If the plan looks like it will exceed 1000 lines, **propose a PR sequence to the contributor before writing code**. Each PR should deliver a cohesive, independently reviewable piece. - -### Determine Workflows - -Based on the plan, determine which workflow(s) apply: - -| Workflow | When to Use | -| ---------------------- | ------------------------------------------------------------------------- | -| **Shared Types** | New interfaces, enums, or constants needed | -| **Backend Endpoint** | New API route with controller + service in this repo | -| **Frontend Service** | New Angular service or methods on an existing one | -| **Frontend Component** | New Angular component (page, module-specific, shared, or PrimeNG wrapper) | -| **Full Feature** | End-to-end integration (combines multiple workflows above) | - -**Build order is strict:** Shared Types → Backend → Frontend Service → Frontend Component. Never skip ahead. - -### Modifying Existing Features - -If the work is a bug fix, enhancement, or refactoring of existing code: - -1. **Read existing code first** — understand what's there before changing it -2. **Trace the data flow end-to-end** — from API call through service to component template -3. **Identify the minimal change** with the smallest blast radius -4. **Follow the same build order** for any new files needed (types → backend → frontend) - -## Step 3: Validate Backend Support (Backend First) - -**Before writing any frontend code**, verify that the upstream microservice APIs needed for this feature actually exist and support the required operations. - -### Check the Upstream API Contract - -The LFX One backend is a thin proxy layer — it proxies requests to external Go microservices. The feature can only work if those microservices expose the endpoints you need. - -| Domain | External Repo | Key Areas to Check | -| ----------------- | --------------------------------------------------------------------------------------------- | ------------------------------------------------- | -| **Queries** | [lfx-v2-query-service](https://github.com/linuxfoundation/lfx-v2-query-service) | Resource types, query params, pagination, filters | -| **Projects** | [lfx-v2-project-service](https://github.com/linuxfoundation/lfx-v2-project-service) | Project CRUD, slugs, membership | -| **Meetings** | [lfx-v2-meeting-service](https://github.com/linuxfoundation/lfx-v2-meeting-service) | Meeting CRUD, RSVPs, recordings, calendar | -| **Mailing Lists** | [lfx-v2-mailing-list-service](https://github.com/linuxfoundation/lfx-v2-mailing-list-service) | Groups.io integration, subscriptions | -| **Committees** | [lfx-v2-committee-service](https://github.com/linuxfoundation/lfx-v2-committee-service) | Committee CRUD, membership, roles | -| **Voting** | [lfx-v2-voting-service](https://github.com/linuxfoundation/lfx-v2-voting-service) | Poll CRUD, casting votes, results | -| **Surveys** | [lfx-v2-survey-service](https://github.com/linuxfoundation/lfx-v2-survey-service) | Survey CRUD, responses, NPS analytics | - -```bash -# Read the OpenAPI spec for the full API contract -gh api repos/linuxfoundation//contents/gen/http/openapi3.yaml \ - --jq '.content' | base64 -d - -# Browse the Goa DSL design files -gh api repos/linuxfoundation//contents/design --jq '.[].name' - -# Read a specific Goa design file -gh api repos/linuxfoundation//contents/design/.go \ - --jq '.content' | base64 -d -``` - -### If the API Does NOT Exist - -**STOP. Do not proceed to frontend work.** Instead: - -1. **Switch to the upstream microservice repo** — clone it and check if it has its own Claude Code skills (`/develop`, etc.) that should be used for building there -2. **Build the required API endpoints** in the upstream repo first, following that repo's conventions and skills -3. **Get the upstream changes merged and deployed** (or at minimum, confirm the API contract is finalized) -4. **Then return to this repo** to build the proxy layer and frontend - -### If the API Exists - -Confirm: - -- The endpoint paths and HTTP methods match what you need -- The request/response schemas have the fields your feature requires -- Query parameters support the filtering/pagination your UI needs - -Then proceed to Step 4. - -> **Critical rule: NO mock data, NO placeholder APIs, NO fake responses.** Every API call in the frontend must connect to a real, working backend endpoint. If the data doesn't flow end-to-end, the feature is not ready to be built. Do not stub services, hardcode responses, or create temporary mocks to "unblock" frontend work. - -## Step 4: Required Reading - -Read the relevant architecture docs **before generating code**. These are the source of truth. - -### Always Read - -- **`CLAUDE.md`** → "Component Organization Pattern" section — class structure ordering, signal patterns - -### For Frontend Work - -- **`docs/architecture/frontend/component-architecture.md`** — Component placement, module structure, PrimeNG wrapper strategy -- **`docs/architecture/frontend/angular-patterns.md`** — Signals, change detection, template syntax, inject() pattern -- **`docs/architecture/frontend/styling-system.md`** — CSS layers, Tailwind configuration -- **`docs/architecture/frontend/state-management.md`** — Service-based state, signal architecture -- **`docs/architecture/frontend/drawer-pattern.md`** — Drawer components with lazy loading and charts (if building a drawer) - -### For Backend Work - -- **`docs/architecture/backend/ssr-server.md`** — Server architecture, route registration -- **`docs/architecture/backend/logging-monitoring.md`** — Logger service usage, operation lifecycle, log levels -- **`docs/architecture/backend/error-handling-architecture.md`** — Error classification, response format -- **`docs/architecture/backend/server-helpers.md`** — Helper patterns, validation, pagination helpers -- **`docs/architecture/backend/pagination.md`** — Cursor-based pagination patterns (if endpoint returns lists) - -### For Shared Package Work - -- **`docs/architecture/shared/package-architecture.md`** — Package structure, exports, utilities, validators - -## Step 5: Check What Exists - -Before creating anything, check what already exists to avoid duplicates: - -```bash -# Frontend -ls apps/lfx-one/src/app/modules/ # Feature modules -ls apps/lfx-one/src/app/shared/components/ # Shared components -ls apps/lfx-one/src/app/shared/services/ # Frontend services - -# Backend -ls apps/lfx-one/src/server/controllers/ # Controllers -ls apps/lfx-one/src/server/services/ # Backend services -ls apps/lfx-one/src/server/routes/ # Route files - -# Shared package -ls packages/shared/src/interfaces/ # Interfaces -ls packages/shared/src/enums/ # Enums -ls packages/shared/src/constants/ # Constants -``` - -If related code already exists, **read it first** and extend it rather than creating new files. - -## Step 6: Read an Existing Example - -Read a representative file in the target area to match the team's current patterns. Pick something in the same module or domain as the work being done. - -## Step 7: Build - -Follow the workflow(s) identified in Step 2. The sections below provide key conventions for each — **read the linked reference file** for full details, examples, and checklists. - -> **Reminder:** Build in strict order — Shared Types → Backend → Frontend Service → Frontend Component. Never build frontend code against APIs that don't exist yet. No mock data, no placeholder services, no hardcoded responses. - ---- - -### Shared Types - -**Location:** `packages/shared/src/interfaces/`, `enums/`, or `constants/` - -Key rules: License headers, TypeScript interfaces (not union types), correct file suffixes, barrel exports, never define interfaces locally. - -**Read `references/shared-types.md`** for full conventions and checklist. - ---- - -### Backend Endpoint - -Creates three files: **service** → **controller** → **route**. - -Key rules: `MicroserviceProxyService` for API calls, `logger` service for logging, `next(error)` for errors, snake_case operation names, `server.ts` registration requires code owner. - -**Read `references/backend-endpoint.md`** for full patterns, examples, and checklist. - ---- - -### Frontend Service - -**Location:** `apps/lfx-one/src/app/shared/services/.service.ts` - -Key rules: `providedIn: 'root'`, `inject(HttpClient)`, `catchError` for GETs, `take(1)` for writes, signals can't use rxjs pipes. - -**Read `references/frontend-service.md`** for full patterns, examples, and checklist. - ---- - -### Frontend Component - -Key rules: Standalone with direct imports, correct placement per category, 11-section class structure, `@if`/`@for` templates, `data-testid` attributes, `flex + gap` not `space-y`. - -**Read `references/frontend-component.md`** for full placement table, examples, and checklist. - ---- - -## Step 8: Validate - -Run the full validation suite: - -```bash -yarn lint # Check for linting errors -yarn format # Apply formatting -yarn build # Verify build succeeds -``` - -Fix any issues before finishing. - -## Step 9: Summary & Next Steps - -Provide a clear summary: - -- All files created or modified -- Any new shared types and their import paths -- Any actions needed from code owners (route registration, routing changes, etc.) -- How to use the new code (inject services, import components, etc.) - -**Next step:** Run `/preflight` to validate everything before submitting a PR. diff --git a/.claude/skills/develop/evals/evals.json b/.claude/skills/develop/evals/evals.json deleted file mode 100644 index 8a7942e7a..000000000 --- a/.claude/skills/develop/evals/evals.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "prompt": "Create a new backend API endpoint to fetch notifications", - "expected_behavior": "Should follow the full develop workflow: start from main, validate upstream API, create shared types, build service → controller → route, then suggest frontend work. Should read architecture docs before generating code." - }, - { - "prompt": "Add a filter dropdown to the meetings page", - "expected_behavior": "Should identify this as a frontend modification, read existing meetings module code first, trace the data flow, identify minimal change needed, and follow component conventions. Should check if backend supports filtering." - }, - { - "prompt": "Fix the bug where committee list shows duplicates", - "expected_behavior": "Should identify this as a modify-existing workflow, read existing committee code first, trace the data flow end-to-end, find the root cause, and apply the minimal fix. Should not create new files unnecessarily." - } -] diff --git a/.claude/skills/develop/references/backend-endpoint.md b/.claude/skills/develop/references/backend-endpoint.md deleted file mode 100644 index 39f537f15..000000000 --- a/.claude/skills/develop/references/backend-endpoint.md +++ /dev/null @@ -1,116 +0,0 @@ -# Backend Endpoint Reference - -## Three-File Pattern - -Every backend endpoint creates three files: **service** → **controller** → **route**. - -The upstream API contract should already be validated in Step 3 of the develop skill. Use the confirmed endpoint paths, request/response schemas, and query parameters when building the proxy layer below. - ---- - -## Service (`src/server/services/.service.ts`) - -- Uses `MicroserviceProxyService` for ALL external API calls -- API reads: `/query/resources`, writes: `/itx/...` -- **Authentication: Default to the user's bearer token** (passed via `req.bearerToken` from the OIDC session) for all authenticated routes. Only use M2M tokens when the upstream service requires service credentials **and** the route has already enforced authorization using the user token (for example, privileged upstream reads that temporarily swap `req.bearerToken` to an M2M token and then restore it). For public endpoints (`/public/api/...`) with no user session, use M2M tokens. See the "Authentication: User Tokens vs M2M Tokens" section in development rules. -- `logger.debug()` for step-by-step tracing, `logger.info()` for significant operations -- `logger.warning()` for recoverable errors (returning null/empty) -- NEVER use `serverLogger` directly — always use `logger` from `./services/logger.service` - -### Service Example Pattern - -```typescript -import { QueryServiceResponse } from '@lfx-one/shared/interfaces'; -import { Request } from 'express'; - -import { logger } from './logger.service'; -import { MicroserviceProxyService } from './microservice-proxy.service'; - -class MyService { - private microserviceProxy: MicroserviceProxyService; - - constructor() { - this.microserviceProxy = new MicroserviceProxyService(); - } - - public async getItems(req: Request): Promise { - logger.debug(req, 'get_items', 'Fetching items from upstream', {}); - - const { resources } = await this.microserviceProxy.proxyRequest>(req, 'LFX_V2_SERVICE', '/query/resources', 'GET', { - resource_type: 'my_items', - }); - - logger.debug(req, 'get_items', 'Fetched items', { count: resources.length }); - return resources.map((r: any) => r.data); - } -} -``` - ---- - -## Controller (`src/server/controllers/.controller.ts`) - -- `logger.startOperation()` → `try/catch` → `logger.success()` or `next(error)` -- Pass errors to `next(error)` — NEVER use `res.status(500).json()` -- Operation names in snake_case (e.g., `get_items`, `create_item`) -- Use `validateUidParameter` from helpers for parameter validation - -### Controller Example Pattern - -```typescript -import { logger } from '../services/logger.service'; -import { myService } from '../services/my.service'; - -export const getItems = async (req: Request, res: Response, next: NextFunction) => { - const startTime = logger.startOperation(req, 'get_items', {}); - - try { - const items = await myService.getItems(req); - logger.success(req, 'get_items', startTime, { count: items.length }); - return res.json(items); - } catch (error) { - logger.error(req, 'get_items', startTime, error, {}); - return next(error); - } -}; -``` - ---- - -## Route (`src/server/routes/.route.ts`) - -- Express Router with controller method bindings -- Follow the pattern from an existing route file - -### Route Example Pattern - -```typescript -import { Router } from 'express'; -import { getItems, createItem } from '../controllers/my.controller'; - -const router = Router(); - -router.get('/items', getItems); -router.post('/items', createItem); - -export default router; -``` - ---- - -## Route Registration - -**IMPORTANT:** The route must be registered in `server.ts`, which is a protected file. -Tell the contributor: - -> "The route file is created, but it needs to be registered in `server.ts`. Since that's a protected infrastructure file, please ask a code owner to add the route registration." - -## Checklist - -- [ ] Service uses `MicroserviceProxyService` (not raw `fetch`/`axios`) -- [ ] Service uses `logger` service (not `serverLogger`) -- [ ] Controller uses `logger.startOperation()` / `logger.success()` / `logger.error()` -- [ ] Controller passes errors to `next(error)` (not `res.status(500)`) -- [ ] Route file follows existing patterns -- [ ] Contributor is informed about `server.ts` registration -- [ ] All files have license headers diff --git a/.claude/skills/develop/references/frontend-component.md b/.claude/skills/develop/references/frontend-component.md deleted file mode 100644 index 8a86f36d0..000000000 --- a/.claude/skills/develop/references/frontend-component.md +++ /dev/null @@ -1,113 +0,0 @@ -# Frontend Component Reference - -## Placement - -Determine the component category and place it accordingly: - -| Category | Location | -| ------------------------------- | ----------------------------------------------- | -| Route/page component | `modules///` | -| Module-specific component | `modules//components//` | -| Shared component (cross-module) | `shared/components//` | -| PrimeNG wrapper component | `shared/components//` | - -Check `docs/architecture/frontend/component-architecture.md` for detailed placement guidelines. - -A new module can be created if the feature represents a distinct domain, but prefer existing modules when the feature fits. - -## Files - -Generate three files (`.component.ts`, `.component.html`, `.component.scss`), each with the license header. - -## Class Structure (from CLAUDE.md) - -1. Private injections (`inject()`, `readonly`) -2. Public fields from inputs/dialog data -3. Forms -4. Model signals (`model()`) -5. WritableSignals (`signal()`) -6. Computed/toSignal signals (via private init functions) -7. Constructor -8. Public methods -9. Protected methods -10. Private initializer functions -11. Private helper methods - -## Key Rules - -- Standalone components with direct imports (no barrel exports) -- Signals: `signal()`, `input()`, `output()`, `computed()`, `model()` — never constructor DI -- Templates: `@if`/`@for` syntax, `data-testid` attributes, `flex + flex-col + gap-*` (never `space-y-*`) -- Do not nest ternary expressions -- For PrimeNG wrappers, follow the wrapper strategy in the component architecture doc - -## Example Pattern - -```typescript -@Component({ - selector: 'lfx-my-component', - standalone: true, - imports: [CommonModule, ButtonModule], - templateUrl: './my-component.component.html', - styleUrl: './my-component.component.scss', -}) -export class MyComponentComponent { - // 1. Private injections - private readonly myService = inject(MyService); - - // 2. Public fields from inputs - public readonly itemId = input.required(); - - // 4. Model signals - public visible = model(false); - - // 5. WritableSignals - public loading = signal(false); - - // 6. Computed/toSignal - public item: Signal = this.initItem(); - - // 8. Public methods - public onSave(): void { - // ... - } - - // 10. Private initializer functions - private initItem(): Signal { - return toSignal( - toObservable(this.itemId).pipe( - filter((id) => !!id), - switchMap((id) => this.myService.getItem(id)) - ), - { initialValue: null } - ); - } -} -``` - -## Template Rules - -```html - -@if (loading()) { - -} @else { -
- @for (item of items(); track item.id) { -
{{ item.name }}
- } -
-} -``` - -## Checklist - -- [ ] Component is standalone with direct imports -- [ ] Correct placement per category table -- [ ] All three files created (`.ts`, `.html`, `.scss`) with license headers -- [ ] Class structure follows the 11-section order -- [ ] Uses `@if`/`@for` (not `*ngIf`/`*ngFor`) -- [ ] Uses `flex + gap-*` (not `space-y-*`) -- [ ] Has `data-testid` attributes on key elements -- [ ] Selector prefixed with `lfx-` -- [ ] No nested ternary expressions diff --git a/.claude/skills/develop/references/frontend-service.md b/.claude/skills/develop/references/frontend-service.md deleted file mode 100644 index f7592341d..000000000 --- a/.claude/skills/develop/references/frontend-service.md +++ /dev/null @@ -1,54 +0,0 @@ -# Frontend Service Reference - -## Location - -`apps/lfx-one/src/app/shared/services/.service.ts` - -> **Prerequisite:** The backend endpoint must already exist (validated in Step 3, built earlier if needed). Do not create a frontend service that calls an API endpoint that doesn't exist — no mock data, no placeholder URLs. - -## Conventions - -- `@Injectable({ providedIn: 'root' })` — always tree-shakeable -- `inject(HttpClient)` — never constructor-based DI -- **GET requests:** `catchError(() => of(defaultValue))` for graceful error handling -- **POST/PUT/DELETE requests:** `take(1)` and let errors propagate to the component -- **Shared state:** Use `signal()` for data consumed by multiple components -- **Signals can't use rxjs pipes** — use `computed()` or `toSignal()` for reactive transforms -- **Interfaces:** Import from `@lfx-one/shared/interfaces`, never define locally -- **API paths:** Use relative paths (e.g., `/api/items`) — the proxy handles routing - -## Example Pattern - -```typescript -import { HttpClient } from '@angular/common/http'; -import { Injectable, inject, signal } from '@angular/core'; -import { catchError, of, take } from 'rxjs'; -import { MyItem } from '@lfx-one/shared/interfaces'; - -@Injectable({ providedIn: 'root' }) -export class MyService { - private readonly http = inject(HttpClient); - - // Shared state - public items = signal([]); - - public getItems() { - return this.http.get('/api/items').pipe(catchError(() => of([] as MyItem[]))); - } - - public createItem(payload: Partial) { - return this.http.post('/api/items', payload).pipe(take(1)); - } -} -``` - -## Checklist - -- [ ] Uses `@Injectable({ providedIn: 'root' })` -- [ ] Uses `inject(HttpClient)` (not constructor DI) -- [ ] GET requests have `catchError` with sensible default -- [ ] POST/PUT/DELETE use `take(1)` -- [ ] Interfaces imported from `@lfx-one/shared/interfaces` -- [ ] API paths are relative (`/api/...`) -- [ ] No mock data or placeholder URLs -- [ ] File has license header diff --git a/.claude/skills/develop/references/shared-types.md b/.claude/skills/develop/references/shared-types.md deleted file mode 100644 index f87246865..000000000 --- a/.claude/skills/develop/references/shared-types.md +++ /dev/null @@ -1,48 +0,0 @@ -# Shared Types Reference - -## Location - -All shared types live in `packages/shared/src/`: - -- **Interfaces:** `interfaces/.interface.ts` -- **Enums:** `enums/.enum.ts` -- **Constants:** `constants/.constants.ts` - -## Conventions - -- License header required on all new files -- Prefer `interface` for shared object shapes; use `type` for literal unions and discriminated unions -- Use `as const` for constant objects to get literal types -- Export from the barrel file (`index.ts`) in the same directory -- Shared types used across modules belong in `@lfx-one/shared/interfaces` — purely local UI types (e.g., component-internal state) may be defined locally when they have no reuse potential - -## File Naming - -```text -packages/shared/src/ -├── interfaces/ -│ ├── my-feature.interface.ts # TypeScript interfaces -│ └── index.ts # Barrel export -├── enums/ -│ ├── my-feature.enum.ts # Enumerations -│ └── index.ts -└── constants/ - ├── my-feature.constants.ts # Constant objects with `as const` - └── index.ts -``` - -## Usage - -```typescript -import { MyInterface } from '@lfx-one/shared/interfaces'; -import { MyEnum } from '@lfx-one/shared/enums'; -import { MY_CONSTANT } from '@lfx-one/shared/constants'; -``` - -## Checklist - -- [ ] File has license header -- [ ] File uses correct suffix (`.interface.ts`, `.enum.ts`, `.constants.ts`) -- [ ] Exported from barrel `index.ts` -- [ ] Interfaces use `interface`, not `type` unions -- [ ] Constants use `as const` for literal types diff --git a/.claude/skills/lfx-backend-builder/SKILL.md b/.claude/skills/lfx-backend-builder/SKILL.md new file mode 100644 index 000000000..b75a2f6dc --- /dev/null +++ b/.claude/skills/lfx-backend-builder/SKILL.md @@ -0,0 +1,191 @@ +--- +name: lfx-backend-builder +description: > + Generate Express proxy code for apps/lfx — services, controllers, routes, and + shared TypeScript types. Encodes the controller-service-route pattern, logger + service usage, LfxService conventions, and shared package structure. +allowed-tools: Bash, Read, Write, Edit, Glob, Grep, AskUserQuestion +--- + + + + +# LFX Backend Code Generation + +You generate Express proxy code and shared TypeScript types for `apps/lfx`. This skill handles the backend layer — the thin proxy between the Angular frontend and the upstream Go microservices. + +**Prerequisites:** The upstream API contract must be validated before generating proxy code. No mock data, no placeholder responses. + +## Input Validation + +| Required | If Missing | +| ---------------------------------------------------- | ---------------------------------------- | +| Specific task (what to build/modify) | Stop and ask | +| Absolute repo path | Stop and ask | +| Upstream API endpoint (path, method, response shape) | Stop — cannot build a proxy without this | + +**If invoked with a `FIX:` prefix**, read the error, find the file, apply the fix, re-validate. + +## Read Before Generating — MANDATORY + +1. **Read the target file** (if modifying) +2. **Read an existing example** in the same domain +3. **Read the relevant interface file** in `packages/shared/src/interfaces/` + +```bash +ls apps/lfx/src/server/services/ +ls apps/lfx/src/server/controllers/ +ls packages/shared/src/interfaces/ +``` + +## Build Order + +**Strict order — do not skip ahead:** + +```text +Shared Types → Service → Controller → Route +``` + +--- + +### 1. Shared Types (`packages/shared/src/interfaces/.interface.ts`) + +```typescript +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +export interface MyItem { + uid: string; + name: string; + description?: string; + created_at: string; +} +``` + +- License header required +- `interface` for object shapes, `type` for literal unions +- `as const` for constant objects +- Export from barrel `index.ts` in the same directory +- File suffixes: `.interface.ts`, `.enum.ts`, `.constants.ts` + +--- + +### 2. Service (`apps/lfx/src/server/services/.service.ts`) + +```typescript +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import { Request } from 'express'; + +import { logger } from './logger.service'; +import { lfxService } from './lfx.service'; + +class MyService { + public async getItems(req: Request): Promise { + logger.debug(req, 'get_items', 'Fetching items from upstream', {}); + + const items = await lfxService.get(req, '/my-items'); + + logger.debug(req, 'get_items', 'Fetched items', { count: items.length }); + return items; + } +} + +export const myService = new MyService(); +``` + +Service rules: + +- `LfxService` (via `lfxService` singleton) for ALL external API calls — never raw `fetch` or `axios` +- Default to user bearer token (`req.bearerToken`) — M2M tokens only for `/public/api/` endpoints +- `logger.debug()` for step-by-step tracing +- `logger.info()` for significant operations (transformations, enrichments) +- `logger.warning()` for recoverable errors (returning null/empty) +- Never use `serverLogger` directly — always `logger` from `./logger.service` + +--- + +### 3. Controller (`apps/lfx/src/server/controllers/.controller.ts`) + +```typescript +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import { NextFunction, Request, Response } from 'express'; + +import { logger } from '../services/logger.service'; +import { myService } from '../services/my.service'; + +export const getItems = async (req: Request, res: Response, next: NextFunction) => { + const startTime = logger.startOperation(req, 'get_items', {}); + + try { + const items = await myService.getItems(req); + logger.success(req, 'get_items', startTime, { count: items.length }); + return res.json(items); + } catch (error) { + logger.error(req, 'get_items', startTime, error, {}); + return next(error); + } +}; +``` + +Controller rules: + +- `logger.startOperation()` → `try/catch` → `logger.success()` or `next(error)` +- Never `res.status(500).json()` — always `next(error)` +- Operation names in `snake_case` +- One `startOperation` per HTTP endpoint + +--- + +### 4. Route (`apps/lfx/src/server/routes/.route.ts`) + +```typescript +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import { Router } from 'express'; + +import { getItems, createItem } from '../controllers/my.controller'; + +const router = Router(); + +router.get('/items', getItems); +router.post('/items', createItem); + +export default router; +``` + +--- + +### 5. Route Registration + +`server.ts` is a **protected file**. Always tell the contributor: + +> "The route file is created. It needs to be registered in `apps/lfx/src/server/server.ts` — a protected infrastructure file. Include this change in your PR for code owner review." + +## Checklist + +- [ ] Shared types created/updated in `packages/shared/src/interfaces/` +- [ ] Shared types exported from barrel `index.ts` +- [ ] Service uses `LfxService` (not raw fetch/axios) +- [ ] Service uses `logger` (not `serverLogger`) +- [ ] Controller uses `logger.startOperation()` / `logger.success()` / `logger.error()` +- [ ] Controller passes errors to `next(error)` (never `res.status(500)`) +- [ ] License headers on all files +- [ ] Contributor informed about `server.ts` registration + +## Scope Boundaries + +**This skill DOES:** + +- Generate Express proxy services, controllers, and routes for `apps/lfx` +- Create/update shared TypeScript types in `packages/shared` + +**This skill does NOT:** + +- Generate Angular frontend code — use `/lfx-ui-builder` or `/lfx-design` +- Modify `apps/lfx-one` — use the existing `/develop` skill for that +- Modify `server.ts` directly — flag for code owner diff --git a/.claude/skills/lfx-coordinator/SKILL.md b/.claude/skills/lfx-coordinator/SKILL.md new file mode 100644 index 000000000..88a1b7f79 --- /dev/null +++ b/.claude/skills/lfx-coordinator/SKILL.md @@ -0,0 +1,257 @@ +--- +name: lfx-coordinator +description: > + Guided development workflow for building, fixing, updating, or refactoring + code in apps/lfx. Researches inline, then delegates code generation to + specialized skills. Use whenever someone wants to add a feature, fix a bug, + modify existing code, create something new, refactor, or implement any code change. +allowed-tools: Bash, Read, Glob, Grep, AskUserQuestion, Agent +--- + + + + +# LFX Development Coordinator + +You coordinate development in `apps/lfx`. You are a **planning and delegation layer only**. + +**CRITICAL CONSTRAINT: You NEVER write, edit, or generate code. Not even one line. Not even "simple" token updates to styles.css. ALL code changes — without exception — are delegated to `/lfx-backend-builder`, `/lfx-ui-builder`, or `/lfx-design` via Agent subagents. You do not have Write, Edit, or Skill tools. If you find yourself about to produce code or invoke a Skill directly, STOP and use the Agent tool instead.** + +**CRITICAL CONSTRAINT: You NEVER call Figma MCP tools (`mcp__plugin_figma_figma__get_design_context`, `mcp__plugin_figma_figma__get_screenshot`, etc.) directly. When a Figma URL is provided, pass the raw URL to `/lfx-design` via Agent subagent — the design skill will fetch the Figma context itself. Calling Figma MCP inline floods your context with React reference code and screenshots that only the design skill needs.** + +**CONTEXT PROTECTION: NEVER invoke skills inline (via Skill tool). ALWAYS spawn Agent subagents. NEVER call external MCP tools (Figma, etc.) that produce large outputs. Inline skill invocation and large MCP responses flood your context window, causing context bloat and degraded performance. Agent subagents run in isolated contexts — only the summary returns to you.** + +## Input Validation + +Auto-detect as much as possible — minimize questions to the user. + +| Required | How to Get It | +| ----------------- | ----------------------------------------------------------------------- | +| What to build/fix | If unclear, ask: "What feature or fix do you need?" | +| Which domain | Auto-detect: "committee member" → committees, "meeting RSVP" → meetings | +| Branch | Auto-derive from JIRA ticket (LFXV2-456 → `feat/LFXV2-456-description`) | + +**Reject vague requests** — ask: "Could you tell me specifically what you'd like to add or change?" + +## Workflow + +```text +Step 1: Setup — check/create branch, verify JIRA ticket +Step 2: Plan — scope the work, identify build order +Step 3: Research — gather context inline (5–10 tool calls max) +Step 4: Delegation — output plan, PAUSE for approval +Step 5: Build — invoke skills via Agent subagents (NEVER inline Skill) +Step 6: Validate — run format, lint, build +Step 7: Summary — report results, suggest /lfx-preflight +``` + +## Step 1: Setup + +```bash +# Confirm we're in the right repo +[ -f apps/lfx/angular.json ] || echo "ERROR: apps/lfx not found" + +# Check/create branch +git branch --show-current +``` + +Verify JIRA ticket exists. Branch format: `feat/LFXV2-`. Always resolve absolute paths before delegating. + +## Figma URL Detection + +When a user provides a Figma URL (e.g., `figma.com/design/...`), this means they want a component built from the Coherence UI Kit. + +**HARD RULE: NEVER call `mcp__plugin_figma_figma__get_design_context` or any Figma MCP tool yourself.** The `/lfx-design` skill will call Figma MCP in its own isolated context. Your only job is to pass the URL through. + +**Check if the Figma MCP is available** by looking for `mcp__plugin_figma_figma__get_design_context` in the available tools. If it is NOT available: + +```text +═══════════════════════════════════════════ +FIGMA MCP NOT CONFIGURED +═══════════════════════════════════════════ + +I detected a Figma URL but the Figma MCP server isn't set up yet. +Run /lfx-setup and select the Figma MCP option to configure it. + +This is a one-time setup — once configured, I can pull +design specs directly from Figma to build components. +═══════════════════════════════════════════ +``` + +If it IS available, **immediately** delegate to `/lfx-design` via Agent subagent, passing the full Figma URL. Do NOT fetch the design context yourself — the design skill handles this in its own context: + +```text +# CORRECT — pass URL, let the subagent fetch Figma context +Agent(prompt: "Invoke /lfx-design to build a component from this Figma URL: . Repo: /Users/.../lfx-v2-ui", subagent_type: "general-purpose") + +# WRONG — DO NOT do this +mcp__plugin_figma_figma__get_design_context(fileKey: "...", nodeId: "...") # ← NEVER call this yourself +``` + +## Step 2: Plan + +- What APIs does the feature need? +- Build order: **Shared Types → Backend Endpoint → Frontend Service → Frontend Component** +- New base UI components (buttons, inputs, cards)? → `/lfx-design` +- Feature-level components (pages, forms)? → `/lfx-ui-builder` +- Figma URL provided? → `/lfx-design` with Figma URL (skill will use MCP to fetch design context) + +## Step 3: Research (inline — NOT via Skill delegation) + +```bash +# Check shared types +ls packages/shared/src/interfaces/ + +# Check existing modules and components +ls apps/lfx/src/app/modules/ +ls apps/lfx/src/app/shared/components/ + +# Check upstream Go API contract +gh api repos/linuxfoundation//contents/gen/http/openapi3.yaml \ + --jq '.content' | base64 -d | head -150 + +# Find the upstream service from existing proxy code (if porting from lfx-one) +grep -r "proxyRequest" apps/lfx-one/src/server/services/.service.ts | head -5 +``` + +**Upstream service mapping:** + +| Domain | Repo | +| ------------- | ----------------------------- | +| Projects | `lfx-v2-project-service` | +| Meetings | `lfx-v2-meeting-service` | +| Mailing Lists | `lfx-v2-mailing-list-service` | +| Committees | `lfx-v2-committee-service` | +| Voting | `lfx-v2-voting-service` | +| Surveys | `lfx-v2-survey-service` | + +**Keep research focused — 5–10 tool calls max.** + +## Step 4: Delegation Plan (PAUSE for approval) + +```text +═══════════════════════════════════════════ +HERE'S WHAT I'M GOING TO DO +═══════════════════════════════════════════ + + 1. [Plain-language step] + 2. [Plain-language step] + 3. [Plain-language step] + +Shall I proceed? + +TECHNICAL DETAILS +───────────────── +Findings: + - [what exists] + - [what's missing] + - [pattern to follow] + +Delegations: + 1. /lfx-backend-builder → [shared types + proxy endpoint] + 2. /lfx-ui-builder → [feature component or service] + OR /lfx-design → [new base UI component] + +Risk flags: + - [protected files needing code owner review] + - [missing upstream API — blocks frontend work] +═══════════════════════════════════════════ +``` + +**Wait for user approval before proceeding.** + +## Step 5: Build — DELEGATE VIA AGENT SUBAGENTS, NEVER IMPLEMENT + +**HARD RULE: The coordinator NEVER generates code. Not a single line. Not even "simple" changes like updating styles.css. ALL code changes go through sub-skills via Agent subagents.** + +**HARD RULE: NEVER use the Skill tool directly. ALWAYS use Agent subagents.** Inline Skill invocation floods your context with generated code. Agent subagents run in isolated contexts — only a summary returns. + +If you catch yourself about to use Write, Edit, Skill, or generate code inline — STOP. Use the Agent tool instead. + +Tell the user: **"Handing off to specialist skills via subagents..."** + +Then IMMEDIATELY invoke the Agent tool. Your very next action after saying this MUST be an Agent tool call. Do not read files "to prepare", do not draft code, do not do anything except call Agent. + +**ALL delegations use Agent subagents — both parallel and sequential:** + +```text +# For independent work — launch multiple Agent calls in ONE message: +Agent(prompt: "Invoke /lfx-design to build ComponentA...", subagent_type: "general-purpose") +Agent(prompt: "Invoke /lfx-design to build ComponentB...", subagent_type: "general-purpose") + +# For sequential/dependent work — still use Agent, just wait between calls: +Agent(prompt: "Invoke /lfx-design to build Spinner...", subagent_type: "general-purpose") +# wait for result +Agent(prompt: "Invoke /lfx-design to build Button (uses Spinner)...", subagent_type: "general-purpose") +``` + +**Why Agent, not Skill?** + +- Agent = subprocess with isolated context → coordinator stays lean +- Skill = inline execution → all generated code fills coordinator's context → bloat → degraded performance +- The coordinator never needs to see generated code — only whether it succeeded + +### Args must include + +| Required | Why | +| --------------------------------------------------------------- | ------------------------------------------- | +| Specific task description | The skill needs to know what to build | +| **Absolute repo path** (`/Users/asithadesilva/Sites/lfx-v2-ui`) | Skills don't inherit your working directory | +| File paths to create or modify | Prevents guessing | +| Types/interfaces to use | Ensures consistency across parallel skills | +| Example file to follow | Gives the skill a concrete pattern | + +## Step 6: Validate + +```bash +cd /Users/asithadesilva/Sites/lfx-v2-ui +yarn format && yarn lint && yarn build --filter=lfx +``` + +### Handling Failures + +1. Read the error — identify file and line +2. Re-invoke via Agent subagent: `Agent(prompt: "Invoke /lfx-ui-builder to FIX: . File: .", subagent_type: "general-purpose")` +3. Re-run validation +4. **Max 2 fix cycles** — if still failing, report to user in plain language + +## Step 7: Summary + +```text +═══════════════════════════════════════════ +WHAT WAS DONE +═══════════════════════════════════════════ + +You asked: "[original request]" + +What changed: + - [Plain-language description of each change] + +What happens next: + - Run /lfx-preflight to validate before PR + +TECHNICAL DETAILS +───────────────── +Files changed: + packages/shared/src/... + apps/lfx/src/... + +Validation: ✓ format ✓ lint ✓ build +Code owner actions needed: [none / list] +═══════════════════════════════════════════ +``` + +## Scope Boundaries + +**This skill DOES:** + +- Plan and scope features for `apps/lfx` +- Research codebase and APIs inline +- Delegate code generation to specialist skills +- Validate builds + +**This skill does NOT:** + +- Write or edit files (no Write/Edit tools) +- Generate code — always delegates +- Apply to `apps/lfx-one` — use the existing `/develop` skill for that diff --git a/.claude/skills/lfx-design/SKILL.md b/.claude/skills/lfx-design/SKILL.md new file mode 100644 index 000000000..cf777f7ce --- /dev/null +++ b/.claude/skills/lfx-design/SKILL.md @@ -0,0 +1,385 @@ +--- +name: lfx-design +description: > + Component builder for the apps/lfx design system. Generates custom Tailwind v4 + components with correct token usage, signal input/output patterns, Storybook stories, + and accessibility attributes. Only applies to base UI components in + apps/lfx/src/app/shared/components/. +allowed-tools: Bash, Read, Write, Edit, Glob, Grep, AskUserQuestion, mcp__plugin_figma_figma__get_design_context, mcp__plugin_figma_figma__get_screenshot +--- + + + + +# LFX Design System Component Builder + +You generate custom Tailwind v4 base UI components for `apps/lfx`. Every component is a building block of the LFX design system — consistent, accessible, and built on established design tokens from the Coherence UI Kit in Figma. + +**This skill only generates base UI components** (buttons, inputs, cards, badges, chips, tooltips, etc.). For feature-level components (pages, forms, data tables with business logic), use `/lfx-ui-builder`. + +## Figma-to-Code Workflow + +All components in this design system are built from the **Coherence UI Kit** in Figma. When a Figma URL or node ID is provided, use the Figma MCP to extract the design spec before writing any code. + +### Step 1 — Fetch the design context + +```text +mcp__plugin_figma_figma__get_design_context( + fileKey: "", + nodeId: "", + clientFrameworks: "angular", + clientLanguages: "typescript,html,css" +) +``` + +**URL parsing:** Given `https://figma.com/design/:fileKey/:fileName?node-id=:nodeId`, extract `fileKey` and convert `nodeId` dashes to colons (e.g., `299-87` → `299:87`). + +### Step 2 — Interpret the Figma output + +The MCP returns React+Tailwind reference code and a screenshot. **Do NOT copy the React code.** Instead, extract: + +- **Variants and their visual differences** (colors, sizes, states) +- **Spacing values** — map Figma `spacing/spacing-*` to standard Tailwind utilities +- **Colors** — map Figma `neutral/neutral-*`, `info/info-*`, etc. to our `@theme` tokens +- **Typography** — map `font-size/text-*` and `line-height/leading-*` to Tailwind utilities +- **Border radius** — map `border-radius/rounded-*` to Tailwind utilities +- **Icons** — Font Awesome icon names appear as text content in the Figma output + +### Step 3 — Map to our token system + +| Figma token | Our Tailwind class | +| ------------------------------------- | --------------------- | +| `var(--neutral/neutral-900, #0f172b)` | `text-neutral-900` | +| `var(--info/info-500, #009aff)` | `bg-info-500` | +| `var(--spacing/spacing-4, 4px)` | `gap-1` or `p-1` | +| `var(--spacing/spacing-6, 6px)` | `gap-1.5` or `p-1.5` | +| `var(--spacing/spacing-8, 8px)` | `gap-2` or `p-2` | +| `var(--spacing/spacing-10, 10px)` | `gap-2.5` or `px-2.5` | +| `var(--font-size/text-xs, 12px)` | `text-xs` | +| `var(--font-size/text-sm, 14px)` | `text-sm` | +| `var(--line-height/leading-text-xs)` | `leading-4` | +| `var(--line-height/leading-text-sm)` | `leading-5` | +| `var(--border-radius/rounded-full)` | `rounded-full` | +| `var(--border-radius/rounded-md)` | `rounded-md` | + +### Step 4 — Build the component + +Follow the patterns documented below. Use the screenshot for visual verification of the expected output. + +If no Figma URL is provided, you can also use `mcp__plugin_figma_figma__get_screenshot` to visually verify a node when you only have a file key and node ID. + +## Input Validation + +| Required | If Missing | +| ----------------------------------------------- | ------------------------------------ | +| Component name and purpose | Ask — don't guess | +| Figma URL or node reference | Ask — all components come from Figma | +| Variants needed (e.g., primary/secondary/ghost) | Extract from Figma design context | +| Size variants (sm/lg) | Extract from Figma or assume `lg` | + +## Read Before Generating — MANDATORY + +Before writing ANY code: + +**1. Fetch the Figma design context** (if a URL/node ID was provided) + +**2. Read these project files:** + +```bash +# Check current design tokens +cat apps/lfx/src/styles.css + +# Check what components already exist +ls apps/lfx/src/app/shared/components/ + +# Read an existing component as a pattern reference +cat apps/lfx/src/app/shared/components/badge/badge.ts +cat apps/lfx/src/app/shared/components/badge/badge.html +cat apps/lfx/src/app/shared/components/badge/badge.stories.ts +``` + +**Never duplicate an existing component. If it exists, extend it.** + +## File Structure & Naming + +```text +apps/lfx/src/app/shared/components// +├── .ts # NOT .component.ts +├── .html # NOT .component.html +├── .css # Empty with license header (NOT .scss) +└── .stories.ts # Storybook stories — ALWAYS required +``` + +**Do NOT use Angular CLI to generate.** Create files directly following the naming pattern above. The class name is the PascalCase component name without a `Component` suffix (e.g., `Badge`, `Button`, `Chip` — not `BadgeComponent`). + +## Component Architecture + +### Class Structure (11-section order) + +```typescript +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import { Component, computed, input, model, output } from '@angular/core'; + +type BadgeVariant = 'neutral' | 'info' | 'success'; +type BadgeSize = 'sm' | 'lg'; + +@Component({ + selector: 'lfx-badge', + imports: [], + templateUrl: './badge.html', + styleUrl: './badge.css', + host: { + '[attr.data-testid]': '"badge"', + }, +}) +export class Badge { + // 1. Private injections (inject(), readonly) + // 2. Public inputs + public variant = input('neutral'); + public size = input('sm'); + // 3. Model signals (model()) — for two-way binding (checked, visible, etc.) + // 4. Writable signals (signal()) + // 5. Computed signals + public badgeClasses = computed(() => { + const sizeClasses: Record = { + sm: 'px-1.5 py-0.5 text-xs gap-0.5', + lg: 'px-2 py-1 text-sm gap-1', + }; + return `${sizeClasses[this.size()]} ${this.variantClasses()}`; + }); + // 6. Outputs + public readonly clicked = output(); + // 7. Constructor + // 8. Public methods + // 9. Protected methods + // 10. Private initializer functions + // 11. Private helper methods + private variantClasses(): string { + /* ... */ + } +} +``` + +### Key Rules + +- **Standalone** — `imports: []` array, direct imports only (no barrels) +- **Signal API** — `input()`, `model()`, `output()` — never `@Input()` / `@Output()` +- **`model()`** for two-way binding — use for `checked`, `visible`, `selectedValue` etc. +- **Computed signals** — use `computed()` for derived class strings +- **No `Component` suffix** — class is `Badge`, not `BadgeComponent` +- **Selector prefix** — always `lfx-` (e.g., `lfx-badge`) +- **Host data-testid** — `host: { '[attr.data-testid]': '"component-name"' }` +- **`.css` only** — never `.scss` + +## Template Pattern — Class Binding + +**Critical: Static base classes on `class`, dynamic classes on `[class]`.** Angular v20 merges them intelligently — they don't overwrite each other. + +```html + + + + + + + +``` + +**What goes where:** + +| `class="..."` (static) | `[class]="computed()"` (dynamic) | +| ---------------------------------------- | ------------------------------------------- | +| Layout: `inline-flex`, `items-center` | Size-dependent: `px-2 py-1 text-sm` | +| Shape: `rounded-full`, `overflow-hidden` | Variant-dependent: `bg-info-500 text-white` | +| Typography base: `font-semibold` | State-dependent: `opacity-50`, `bg-white` | +| Transitions: `transition-colors` | | + +**For individual boolean toggles**, use `[class.xxx]="condition"`: + +```html + +``` + +**For preventing layout shift**, use `[class.invisible]` instead of `@if` for small toggle elements (icons, dots) inside fixed-size containers: + +```html + + + + +@if (checked()) { + +} +``` + +## Template Rules + +- Always `@if` / `@for` — never `*ngIf` / `*ngFor` +- Always `flex + flex-col + gap-*` — never `space-y-*` +- `data-testid` on all interactive and container elements +- Never nest ternary expressions +- `type="button"` on all ` diff --git a/apps/lfx/src/app/shared/components/button/button.stories.ts b/apps/lfx/src/app/shared/components/button/button.stories.ts new file mode 100644 index 000000000..4734b1826 --- /dev/null +++ b/apps/lfx/src/app/shared/components/button/button.stories.ts @@ -0,0 +1,197 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import type { Meta, StoryObj } from '@storybook/angular'; +import { Button } from './button'; + +const meta: Meta + } + diff --git a/apps/lfx/src/app/shared/components/chip/chip.stories.ts b/apps/lfx/src/app/shared/components/chip/chip.stories.ts new file mode 100644 index 000000000..aaca04a06 --- /dev/null +++ b/apps/lfx/src/app/shared/components/chip/chip.stories.ts @@ -0,0 +1,143 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import type { Meta, StoryObj } from '@storybook/angular'; +import { Chip } from './chip'; + +const meta: Meta = { + title: 'Components/Chip', + component: Chip, + tags: ['autodocs'], + argTypes: { + chipStyle: { + control: 'select', + options: ['bordered', 'neutral'], + }, + size: { + control: 'select', + options: ['sm', 'lg'], + }, + type: { + control: 'select', + options: ['label', 'icon', 'avatar-photo', 'avatar-logo'], + }, + icon: { control: 'text' }, + avatarSrc: { control: 'text' }, + dismissable: { control: 'boolean' }, + label: { control: 'text' }, + }, + render: (args) => ({ + props: args, + template: ``, + }), +}; + +export default meta; +type Story = StoryObj; + +export const BorderedLabel: Story = { + args: { chipStyle: 'bordered', size: 'lg', type: 'label', label: 'Tag' }, +}; + +export const NeutralLabel: Story = { + args: { chipStyle: 'neutral', size: 'lg', type: 'label', label: 'Tag' }, +}; + +export const BorderedSmall: Story = { + args: { chipStyle: 'bordered', size: 'sm', type: 'label', label: 'Tag' }, +}; + +export const NeutralSmall: Story = { + args: { chipStyle: 'neutral', size: 'sm', type: 'label', label: 'Tag' }, +}; + +export const WithIcon: Story = { + args: { chipStyle: 'bordered', size: 'lg', type: 'icon', icon: 'tag', label: 'Category' }, +}; + +export const WithIconSmall: Story = { + args: { chipStyle: 'bordered', size: 'sm', type: 'icon', icon: 'tag', label: 'Category' }, +}; + +export const WithAvatarPhoto: Story = { + args: { + chipStyle: 'bordered', + size: 'lg', + type: 'avatar-photo', + avatarSrc: 'https://i.pravatar.cc/48', + label: 'Jane Doe', + }, +}; + +export const WithAvatarLogo: Story = { + args: { + chipStyle: 'bordered', + size: 'lg', + type: 'avatar-logo', + avatarSrc: 'https://upload.wikimedia.org/wikipedia/commons/3/35/Tux.svg', + label: 'Linux Foundation', + }, +}; + +export const Dismissable: Story = { + args: { chipStyle: 'bordered', size: 'lg', type: 'label', label: 'Removable', dismissable: true }, +}; + +export const DismissableWithIcon: Story = { + args: { chipStyle: 'neutral', size: 'lg', type: 'icon', icon: 'tag', label: 'Filter', dismissable: true }, +}; + +export const DismissableSmall: Story = { + args: { chipStyle: 'bordered', size: 'sm', type: 'label', label: 'Removable', dismissable: true }, +}; + +export const AllVariants: Story = { + render: () => ({ + template: ` +
+
+ Bordered (Large) +
+ + + + + + +
+
+
+ Bordered (Small) +
+ + + + + +
+
+
+ Neutral (Large) +
+ + + + + + +
+
+
+ Neutral (Small) +
+ + + + + +
+
+
+ `, + }), +}; diff --git a/apps/lfx/src/app/shared/components/chip/chip.ts b/apps/lfx/src/app/shared/components/chip/chip.ts new file mode 100644 index 000000000..554833ee4 --- /dev/null +++ b/apps/lfx/src/app/shared/components/chip/chip.ts @@ -0,0 +1,48 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import { Component, computed, input, output } from '@angular/core'; +import { Avatar } from '../avatar/avatar'; + +type ChipStyle = 'bordered' | 'neutral'; +type ChipSize = 'sm' | 'lg'; +type ChipType = 'label' | 'icon' | 'avatar-photo' | 'avatar-logo'; + +@Component({ + selector: 'lfx-chip', + imports: [Avatar], + templateUrl: './chip.html', + styleUrl: './chip.css', + host: { + '[attr.data-testid]': '"chip"', + }, +}) +export class Chip { + public chipStyle = input('bordered'); + public size = input('lg'); + public type = input('label'); + public icon = input(); + public avatarSrc = input(); + public dismissable = input(false); + public label = input(''); + + public readonly dismissed = output(); + + public chipClasses = computed(() => { + const sizeClasses: Record = { + lg: 'px-2.5 py-1 text-sm leading-5', + sm: 'px-1.5 py-0.5 text-xs leading-4', + }; + + const styleClasses: Record = { + bordered: 'bg-white border border-neutral-200', + neutral: 'bg-neutral-100', + }; + + return `${sizeClasses[this.size()]} ${styleClasses[this.chipStyle()]}`; + }); + + public onDismiss(): void { + this.dismissed.emit(); + } +} diff --git a/apps/lfx/src/app/shared/components/link-button/link-button.css b/apps/lfx/src/app/shared/components/link-button/link-button.css new file mode 100644 index 000000000..6267226bd --- /dev/null +++ b/apps/lfx/src/app/shared/components/link-button/link-button.css @@ -0,0 +1,6 @@ +/* Copyright The Linux Foundation and each contributor to LFX. */ +/* SPDX-License-Identifier: MIT */ + +:host { + display: inline-block; +} diff --git a/apps/lfx/src/app/shared/components/link-button/link-button.html b/apps/lfx/src/app/shared/components/link-button/link-button.html new file mode 100644 index 000000000..23b8aace1 --- /dev/null +++ b/apps/lfx/src/app/shared/components/link-button/link-button.html @@ -0,0 +1,18 @@ + + + + diff --git a/apps/lfx/src/app/shared/components/link-button/link-button.stories.ts b/apps/lfx/src/app/shared/components/link-button/link-button.stories.ts new file mode 100644 index 000000000..fab4b3afd --- /dev/null +++ b/apps/lfx/src/app/shared/components/link-button/link-button.stories.ts @@ -0,0 +1,105 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import type { Meta, StoryObj } from '@storybook/angular'; +import { LinkButton } from './link-button'; + +const meta: Meta = { + title: 'Components/LinkButton', + component: LinkButton, + tags: ['autodocs'], + argTypes: { + variant: { + control: 'select', + options: ['accent', 'neutral'], + }, + size: { + control: 'select', + options: ['sm', 'lg'], + }, + disabled: { control: 'boolean' }, + underline: { control: 'boolean' }, + leftIcon: { control: 'text' }, + rightIcon: { control: 'text' }, + }, + render: (args) => ({ + props: args, + template: `Link Button`, + }), +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { variant: 'accent', size: 'lg' }, +}; + +export const AccentSmall: Story = { + args: { variant: 'accent', size: 'sm' }, +}; + +export const Neutral: Story = { + args: { variant: 'neutral', size: 'lg' }, +}; + +export const NeutralSmall: Story = { + args: { variant: 'neutral', size: 'sm' }, +}; + +export const WithLeftIcon: Story = { + args: { variant: 'accent', size: 'lg', leftIcon: 'arrow-left' }, +}; + +export const WithRightIcon: Story = { + args: { variant: 'accent', size: 'lg', rightIcon: 'arrow-right' }, +}; + +export const WithBothIcons: Story = { + args: { variant: 'accent', size: 'lg', leftIcon: 'arrow-left', rightIcon: 'arrow-right' }, +}; + +export const UnderlineOnHover: Story = { + args: { variant: 'accent', size: 'lg', underline: true }, +}; + +export const Disabled: Story = { + args: { variant: 'accent', size: 'lg', disabled: true }, +}; + +export const AllVariants: Story = { + render: () => ({ + template: ` +
+
+ Accent LG + Link Button + With Icon + Underline + Disabled +
+
+ Accent SM + Link Button + With Icon + Underline + Disabled +
+
+ Neutral LG + Link Button + With Icon + Underline + Disabled +
+
+ Neutral SM + Link Button + With Icon + Underline + Disabled +
+
+ `, + }), +}; diff --git a/apps/lfx/src/app/shared/components/link-button/link-button.ts b/apps/lfx/src/app/shared/components/link-button/link-button.ts new file mode 100644 index 000000000..6735c1114 --- /dev/null +++ b/apps/lfx/src/app/shared/components/link-button/link-button.ts @@ -0,0 +1,51 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import { Component, computed, input, output } from '@angular/core'; + +type LinkButtonVariant = 'accent' | 'neutral'; +type LinkButtonSize = 'sm' | 'lg'; + +@Component({ + selector: 'lfx-link-button', + imports: [], + templateUrl: './link-button.html', + styleUrl: './link-button.css', + host: { + '[attr.data-testid]': '"link-button"', + }, +}) +export class LinkButton { + public variant = input('accent'); + public size = input('lg'); + public disabled = input(false); + public underline = input(false); + public leftIcon = input(); + public rightIcon = input(); + + public readonly clicked = output(); + + public buttonClasses = computed(() => { + const variantClasses: Record = { + accent: 'text-info-500 hover:text-info-600', + neutral: 'text-neutral-500 hover:text-neutral-600', + }; + + const sizeClasses: Record = { + sm: 'text-xs gap-1', + lg: 'text-sm gap-1.5', + }; + + const underlineClass = this.underline() ? 'hover:underline' : ''; + + const disabledClass = this.disabled() ? 'opacity-50 pointer-events-none' : ''; + + return `${variantClasses[this.variant()]} ${sizeClasses[this.size()]} ${underlineClass} ${disabledClass}`.trim(); + }); + + public onClick(event: MouseEvent): void { + if (!this.disabled()) { + this.clicked.emit(event); + } + } +} diff --git a/apps/lfx/src/app/shared/components/radio-button/radio-button.css b/apps/lfx/src/app/shared/components/radio-button/radio-button.css new file mode 100644 index 000000000..6267226bd --- /dev/null +++ b/apps/lfx/src/app/shared/components/radio-button/radio-button.css @@ -0,0 +1,6 @@ +/* Copyright The Linux Foundation and each contributor to LFX. */ +/* SPDX-License-Identifier: MIT */ + +:host { + display: inline-block; +} diff --git a/apps/lfx/src/app/shared/components/radio-button/radio-button.html b/apps/lfx/src/app/shared/components/radio-button/radio-button.html new file mode 100644 index 000000000..dd3300f31 --- /dev/null +++ b/apps/lfx/src/app/shared/components/radio-button/radio-button.html @@ -0,0 +1,23 @@ + + + + diff --git a/apps/lfx/src/app/shared/components/radio-button/radio-button.stories.ts b/apps/lfx/src/app/shared/components/radio-button/radio-button.stories.ts new file mode 100644 index 000000000..d82b75832 --- /dev/null +++ b/apps/lfx/src/app/shared/components/radio-button/radio-button.stories.ts @@ -0,0 +1,80 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import type { Meta, StoryObj } from '@storybook/angular'; +import { RadioButton } from './radio-button'; + +const meta: Meta = { + title: 'Components/RadioButton', + component: RadioButton, + tags: ['autodocs'], + argTypes: { + size: { + control: 'select', + options: ['sm', 'lg'], + }, + checked: { control: 'boolean' }, + disabled: { control: 'boolean' }, + label: { control: 'text' }, + name: { control: 'text' }, + value: { control: 'text' }, + }, + render: (args) => ({ + props: args, + template: ``, + }), +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { checked: false, size: 'lg', label: 'Radio label' }, +}; + +export const DefaultSmall: Story = { + args: { checked: false, size: 'sm', label: 'Radio label' }, +}; + +export const Selected: Story = { + args: { checked: true, size: 'lg', label: 'Radio label' }, +}; + +export const SelectedSmall: Story = { + args: { checked: true, size: 'sm', label: 'Radio label' }, +}; + +export const Disabled: Story = { + args: { disabled: true, size: 'lg', label: 'Radio label' }, +}; + +export const DisabledSelected: Story = { + args: { checked: true, disabled: true, size: 'lg', label: 'Radio label' }, +}; + +export const WithoutLabel: Story = { + args: { checked: false, size: 'lg' }, +}; + +export const AllVariants: Story = { + render: () => ({ + template: ` +
+
+ Unselected + + + + +
+
+ Selected + + + + +
+
+ `, + }), +}; diff --git a/apps/lfx/src/app/shared/components/radio-button/radio-button.ts b/apps/lfx/src/app/shared/components/radio-button/radio-button.ts new file mode 100644 index 000000000..207c92af7 --- /dev/null +++ b/apps/lfx/src/app/shared/components/radio-button/radio-button.ts @@ -0,0 +1,67 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import { Component, computed, input, model, output } from '@angular/core'; + +type RadioButtonSize = 'sm' | 'lg'; + +@Component({ + selector: 'lfx-radio-button', + imports: [], + templateUrl: './radio-button.html', + styleUrl: './radio-button.css', + host: { + '[attr.data-testid]': '"radio-button"', + }, +}) +export class RadioButton { + public size = input('lg'); + public disabled = input(false); + public label = input(); + public name = input(); + public value = input(); + + public checked = model(false); + + public readonly changed = output(); + + public circleClasses = computed(() => { + const isChecked = this.checked(); + const isDisabled = this.disabled(); + const isSmall = this.size() === 'sm'; + + const sizeClass = isSmall ? 'size-3' : 'size-4'; + + let stateClass: string; + if (isChecked) { + stateClass = isDisabled ? 'bg-neutral-200 border-neutral-300' : 'bg-info-500 border-info-500'; + } else { + stateClass = isDisabled ? 'bg-neutral-200 border-neutral-300' : 'bg-white border-neutral-300'; + } + + return `${sizeClass} ${stateClass}`; + }); + + public dotClasses = computed(() => { + const isDisabled = this.disabled(); + const isSmall = this.size() === 'sm'; + const colorClass = isDisabled ? 'bg-neutral-400' : 'bg-white'; + const sizeClass = isSmall ? 'size-1' : 'size-1.5'; + return `rounded-full ${colorClass} ${sizeClass}`; + }); + + public labelClasses = computed(() => { + const isSmall = this.size() === 'sm'; + const sizeClass = isSmall ? 'text-xs leading-4' : 'text-sm leading-5'; + const colorClass = this.disabled() ? 'text-neutral-500' : 'text-neutral-900'; + + return `${sizeClass} font-normal ${colorClass}`; + }); + + public onSelect(): void { + if (!this.disabled()) { + this.checked.set(true); + this.changed.emit(true); + } + } +} diff --git a/apps/lfx/src/app/shared/components/spinner/spinner.css b/apps/lfx/src/app/shared/components/spinner/spinner.css new file mode 100644 index 000000000..7addc5e04 --- /dev/null +++ b/apps/lfx/src/app/shared/components/spinner/spinner.css @@ -0,0 +1,33 @@ +/* Copyright The Linux Foundation and each contributor to LFX. */ +/* SPDX-License-Identifier: MIT */ + +.spinner { + border-radius: 50%; + border: 3px solid var(--color-surface-secondary, #e5e7eb); + border-top-color: var(--color-brand-600, #2563eb); + animation: spin 0.8s linear infinite; +} + +.spinner--sm { + width: 1rem; + height: 1rem; + border-width: 2px; +} + +.spinner--md { + width: 1.5rem; + height: 1.5rem; + border-width: 3px; +} + +.spinner--lg { + width: 2.5rem; + height: 2.5rem; + border-width: 4px; +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} diff --git a/apps/lfx/src/app/shared/components/spinner/spinner.html b/apps/lfx/src/app/shared/components/spinner/spinner.html new file mode 100644 index 000000000..a687ea5c1 --- /dev/null +++ b/apps/lfx/src/app/shared/components/spinner/spinner.html @@ -0,0 +1,9 @@ + + + +
diff --git a/apps/lfx/src/app/shared/components/spinner/spinner.stories.ts b/apps/lfx/src/app/shared/components/spinner/spinner.stories.ts new file mode 100644 index 000000000..8260a369f --- /dev/null +++ b/apps/lfx/src/app/shared/components/spinner/spinner.stories.ts @@ -0,0 +1,32 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import type { Meta, StoryObj } from '@storybook/angular'; +import { Spinner } from './spinner'; + +const meta: Meta = { + title: 'Components/Spinner', + component: Spinner, + tags: ['autodocs'], + argTypes: { + size: { + control: 'select', + options: ['sm', 'md', 'lg'], + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Small: Story = { + args: { size: 'sm' }, +}; + +export const Medium: Story = { + args: { size: 'md' }, +}; + +export const Large: Story = { + args: { size: 'lg' }, +}; diff --git a/apps/lfx/src/app/shared/components/spinner/spinner.ts b/apps/lfx/src/app/shared/components/spinner/spinner.ts new file mode 100644 index 000000000..53a02ecf8 --- /dev/null +++ b/apps/lfx/src/app/shared/components/spinner/spinner.ts @@ -0,0 +1,14 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import { Component, input } from '@angular/core'; + +@Component({ + selector: 'lfx-spinner', + imports: [], + templateUrl: './spinner.html', + styleUrl: './spinner.css', +}) +export class Spinner { + public size = input<'sm' | 'md' | 'lg'>('md'); +} diff --git a/apps/lfx/src/app/shared/components/tabs/tab-item.css b/apps/lfx/src/app/shared/components/tabs/tab-item.css new file mode 100644 index 000000000..0704837b8 --- /dev/null +++ b/apps/lfx/src/app/shared/components/tabs/tab-item.css @@ -0,0 +1,2 @@ +/* Copyright The Linux Foundation and each contributor to LFX. */ +/* SPDX-License-Identifier: MIT */ diff --git a/apps/lfx/src/app/shared/components/tabs/tab-item.html b/apps/lfx/src/app/shared/components/tabs/tab-item.html new file mode 100644 index 000000000..30f5341c1 --- /dev/null +++ b/apps/lfx/src/app/shared/components/tabs/tab-item.html @@ -0,0 +1,17 @@ + + + + diff --git a/apps/lfx/src/app/shared/components/tabs/tab-item.ts b/apps/lfx/src/app/shared/components/tabs/tab-item.ts new file mode 100644 index 000000000..7002d2395 --- /dev/null +++ b/apps/lfx/src/app/shared/components/tabs/tab-item.ts @@ -0,0 +1,89 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import { Component, computed, input, output } from '@angular/core'; + +export type TabStyle = 'bordered' | 'switch'; +export type TabSize = 'sm' | 'lg'; + +@Component({ + selector: 'lfx-tab-item', + imports: [], + templateUrl: './tab-item.html', + styleUrl: './tab-item.css', + host: { + '[attr.data-testid]': '"tab-item"', + }, +}) +export class TabItem { + public label = input.required(); + public value = input.required(); + public icon = input(); + public selected = input(false); + public tabStyle = input('switch'); + public size = input('lg'); + + public readonly selectTab = output(); + + public itemClasses = computed(() => { + const style = this.tabStyle(); + const size = this.size(); + const selected = this.selected(); + + if (style === 'switch') { + return this.switchClasses(size, selected); + } + return this.borderedClasses(size, selected); + }); + + public textClasses = computed(() => { + const selected = this.selected(); + const size = this.size(); + + const sizeClass = size === 'sm' ? 'text-xs leading-4' : 'text-sm leading-5'; + const weightClass = selected ? 'font-medium' : 'font-normal'; + const colorClass = selected ? 'text-neutral-900' : 'text-neutral-600'; + + return `${sizeClass} ${weightClass} ${colorClass}`; + }); + + public iconClasses = computed(() => { + const selected = this.selected(); + const size = this.size(); + + const sizeClass = size === 'sm' ? 'text-xs' : 'text-base'; + const colorClass = selected ? 'text-neutral-900' : 'text-neutral-600'; + + return `${sizeClass} ${colorClass}`; + }); + + public onSelect(): void { + if (!this.selected()) { + this.selectTab.emit(this.value()); + } + } + + private switchClasses(size: TabSize, selected: boolean): string { + const base = 'rounded-full overflow-clip'; + + const sizeClasses: Record = { + sm: 'h-6 px-2 gap-1', + lg: 'h-7 px-3 gap-1.5', + }; + + const stateClass = selected ? 'bg-white border border-white shadow-sm' : 'border border-neutral-200'; + + return `${base} ${sizeClasses[size]} ${stateClass}`; + } + + private borderedClasses(size: TabSize, selected: boolean): string { + const sizeClasses: Record = { + sm: 'h-8 pt-1 gap-1', + lg: 'h-10 pt-1 gap-1.5', + }; + + const stateClass = selected ? 'border-b border-info-500' : ''; + + return `${sizeClasses[size]} ${stateClass}`; + } +} diff --git a/apps/lfx/src/app/shared/components/tabs/tabs.css b/apps/lfx/src/app/shared/components/tabs/tabs.css new file mode 100644 index 000000000..0704837b8 --- /dev/null +++ b/apps/lfx/src/app/shared/components/tabs/tabs.css @@ -0,0 +1,2 @@ +/* Copyright The Linux Foundation and each contributor to LFX. */ +/* SPDX-License-Identifier: MIT */ diff --git a/apps/lfx/src/app/shared/components/tabs/tabs.html b/apps/lfx/src/app/shared/components/tabs/tabs.html new file mode 100644 index 000000000..0aa2ff351 --- /dev/null +++ b/apps/lfx/src/app/shared/components/tabs/tabs.html @@ -0,0 +1,15 @@ + + + +
+ @for (tab of tabs(); track tab.value) { + + } +
diff --git a/apps/lfx/src/app/shared/components/tabs/tabs.stories.ts b/apps/lfx/src/app/shared/components/tabs/tabs.stories.ts new file mode 100644 index 000000000..5663cbc42 --- /dev/null +++ b/apps/lfx/src/app/shared/components/tabs/tabs.stories.ts @@ -0,0 +1,111 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import type { Meta, StoryObj } from '@storybook/angular'; +import { Tabs } from './tabs'; + +const sampleTabs = [ + { label: 'Overview', value: 'overview', icon: 'circle-dashed' }, + { label: 'Members', value: 'members', icon: 'circle-dashed' }, + { label: 'Settings', value: 'settings', icon: 'circle-dashed' }, + { label: 'Activity', value: 'activity', icon: 'circle-dashed' }, + { label: 'Reports', value: 'reports', icon: 'circle-dashed' }, + { label: 'Billing', value: 'billing', icon: 'circle-dashed' }, +]; + +const sampleTabsNoIcons = [ + { label: 'Overview', value: 'overview' }, + { label: 'Members', value: 'members' }, + { label: 'Settings', value: 'settings' }, + { label: 'Activity', value: 'activity' }, + { label: 'Reports', value: 'reports' }, + { label: 'Billing', value: 'billing' }, +]; + +const meta: Meta = { + title: 'Components/Tabs', + component: Tabs, + tags: ['autodocs'], + argTypes: { + tabStyle: { + control: 'select', + options: ['switch', 'bordered'], + }, + size: { + control: 'select', + options: ['sm', 'lg'], + }, + }, + render: (args) => ({ + props: { + ...args, + activeTab: 'overview', + }, + template: ``, + }), +}; + +export default meta; +type Story = StoryObj; + +export const SwitchDefault: Story = { + args: { tabs: sampleTabs, tabStyle: 'switch', size: 'lg' }, +}; + +export const SwitchSmall: Story = { + args: { tabs: sampleTabs, tabStyle: 'switch', size: 'sm' }, +}; + +export const BorderedDefault: Story = { + args: { tabs: sampleTabs, tabStyle: 'bordered', size: 'lg' }, +}; + +export const BorderedSmall: Story = { + args: { tabs: sampleTabs, tabStyle: 'bordered', size: 'sm' }, +}; + +export const SwitchNoIcons: Story = { + args: { tabs: sampleTabsNoIcons, tabStyle: 'switch', size: 'lg' }, +}; + +export const BorderedNoIcons: Story = { + args: { tabs: sampleTabsNoIcons, tabStyle: 'bordered', size: 'lg' }, +}; + +export const AllVariants: Story = { + render: () => ({ + props: { + sampleTabs, + sampleTabsNoIcons, + activeTab: 'overview', + }, + template: ` +
+
+ Switch — Default Size + +
+
+ Switch — Small Size + +
+
+ Bordered — Default Size + +
+
+ Bordered — Small Size + +
+
+ Switch — No Icons + +
+
+ Bordered — No Icons + +
+
+ `, + }), +}; diff --git a/apps/lfx/src/app/shared/components/tabs/tabs.ts b/apps/lfx/src/app/shared/components/tabs/tabs.ts new file mode 100644 index 000000000..4bf710a05 --- /dev/null +++ b/apps/lfx/src/app/shared/components/tabs/tabs.ts @@ -0,0 +1,59 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import { Component, computed, input, model, output } from '@angular/core'; +import { TabItem, type TabSize, type TabStyle } from './tab-item'; + +export interface TabDefinition { + label: string; + value: string; + icon?: string; +} + +@Component({ + selector: 'lfx-tabs', + imports: [TabItem], + templateUrl: './tabs.html', + styleUrl: './tabs.css', + host: { + '[attr.data-testid]': '"tabs"', + '[attr.role]': '"tablist"', + }, +}) +export class Tabs { + public tabs = input.required(); + public tabStyle = input('switch'); + public size = input('lg'); + + public activeTab = model(''); + + public readonly tabChange = output(); + + public containerClasses = computed(() => { + const style = this.tabStyle(); + const size = this.size(); + + if (style === 'switch') { + const sizeClasses: Record = { + sm: 'bg-neutral-100 gap-0.5 p-0.5 rounded-full', + lg: 'bg-neutral-100 gap-1 p-1 rounded-full', + }; + return sizeClasses[size]; + } + + const sizeClasses: Record = { + sm: 'border-b border-neutral-200 gap-5', + lg: 'border-b border-neutral-200 gap-6', + }; + return sizeClasses[size]; + }); + + public onTabSelect(value: string): void { + this.activeTab.set(value); + this.tabChange.emit(value); + } + + public isSelected(value: string): boolean { + return this.activeTab() === value; + } +} diff --git a/apps/lfx/src/app/shared/components/toggle-switch/toggle-switch.css b/apps/lfx/src/app/shared/components/toggle-switch/toggle-switch.css new file mode 100644 index 000000000..6267226bd --- /dev/null +++ b/apps/lfx/src/app/shared/components/toggle-switch/toggle-switch.css @@ -0,0 +1,6 @@ +/* Copyright The Linux Foundation and each contributor to LFX. */ +/* SPDX-License-Identifier: MIT */ + +:host { + display: inline-block; +} diff --git a/apps/lfx/src/app/shared/components/toggle-switch/toggle-switch.html b/apps/lfx/src/app/shared/components/toggle-switch/toggle-switch.html new file mode 100644 index 000000000..5574befd4 --- /dev/null +++ b/apps/lfx/src/app/shared/components/toggle-switch/toggle-switch.html @@ -0,0 +1,16 @@ + + + + diff --git a/apps/lfx/src/app/shared/components/toggle-switch/toggle-switch.stories.ts b/apps/lfx/src/app/shared/components/toggle-switch/toggle-switch.stories.ts new file mode 100644 index 000000000..7a7be4335 --- /dev/null +++ b/apps/lfx/src/app/shared/components/toggle-switch/toggle-switch.stories.ts @@ -0,0 +1,86 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import type { Meta, StoryObj } from '@storybook/angular'; +import { ToggleSwitch } from './toggle-switch'; + +const meta: Meta = { + title: 'Components/ToggleSwitch', + component: ToggleSwitch, + tags: ['autodocs'], + argTypes: { + size: { + control: 'select', + options: ['sm', 'lg'], + }, + checked: { control: 'boolean' }, + disabled: { control: 'boolean' }, + label: { control: 'text' }, + }, + render: (args) => ({ + props: args, + template: ``, + }), +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { checked: false, size: 'lg', label: 'Toggle label' }, +}; + +export const DefaultSmall: Story = { + args: { checked: false, size: 'sm', label: 'Toggle label' }, +}; + +export const On: Story = { + args: { checked: true, size: 'lg', label: 'Toggle label' }, +}; + +export const OnSmall: Story = { + args: { checked: true, size: 'sm', label: 'Toggle label' }, +}; + +export const Disabled: Story = { + args: { disabled: true, size: 'lg', label: 'Toggle label' }, +}; + +export const DisabledOn: Story = { + args: { checked: true, disabled: true, size: 'lg', label: 'Toggle label' }, +}; + +export const DisabledSmall: Story = { + args: { disabled: true, size: 'sm', label: 'Toggle label' }, +}; + +export const DisabledOnSmall: Story = { + args: { checked: true, disabled: true, size: 'sm', label: 'Toggle label' }, +}; + +export const WithoutLabel: Story = { + args: { checked: false, size: 'lg' }, +}; + +export const AllVariants: Story = { + render: () => ({ + template: ` +
+
+ Off + + + + +
+
+ On + + + + +
+
+ `, + }), +}; diff --git a/apps/lfx/src/app/shared/components/toggle-switch/toggle-switch.ts b/apps/lfx/src/app/shared/components/toggle-switch/toggle-switch.ts new file mode 100644 index 000000000..e60f54bbd --- /dev/null +++ b/apps/lfx/src/app/shared/components/toggle-switch/toggle-switch.ts @@ -0,0 +1,68 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import { Component, computed, input, model, output } from '@angular/core'; + +type ToggleSwitchSize = 'sm' | 'lg'; + +@Component({ + selector: 'lfx-toggle-switch', + imports: [], + templateUrl: './toggle-switch.html', + styleUrl: './toggle-switch.css', + host: { + '[attr.data-testid]': '"toggle-switch"', + }, +}) +export class ToggleSwitch { + public size = input('lg'); + public disabled = input(false); + public label = input(); + + public checked = model(false); + + public readonly changed = output(); + + public trackClasses = computed(() => { + const isChecked = this.checked(); + const isDisabled = this.disabled(); + const isSmall = this.size() === 'sm'; + + const sizeClass = isSmall ? 'w-5 h-3' : 'w-[30px] h-4'; + + let bgClass: string; + if (isDisabled) { + bgClass = 'bg-neutral-300'; + } else { + bgClass = isChecked ? 'bg-info-500' : 'bg-neutral-200'; + } + + return `${sizeClass} ${bgClass}`; + }); + + public knobClasses = computed(() => { + const isDisabled = this.disabled(); + const isSmall = this.size() === 'sm'; + + const sizeClass = isSmall ? 'size-2' : 'size-3'; + const colorClass = isDisabled ? 'bg-neutral-100' : 'bg-white'; + + return `${sizeClass} ${colorClass}`; + }); + + public labelClasses = computed(() => { + const isSmall = this.size() === 'sm'; + const sizeClass = isSmall ? 'text-xs leading-4' : 'text-sm leading-5'; + const colorClass = this.disabled() ? 'text-neutral-500' : 'text-neutral-900'; + + return `${sizeClass} font-normal ${colorClass}`; + }); + + public onToggle(): void { + if (!this.disabled()) { + const newValue = !this.checked(); + this.checked.set(newValue); + this.changed.emit(newValue); + } + } +} diff --git a/apps/lfx/src/app/shared/components/tooltip/tooltip-trigger.ts b/apps/lfx/src/app/shared/components/tooltip/tooltip-trigger.ts new file mode 100644 index 000000000..c69a0c559 --- /dev/null +++ b/apps/lfx/src/app/shared/components/tooltip/tooltip-trigger.ts @@ -0,0 +1,152 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import { DOCUMENT, isPlatformBrowser } from '@angular/common'; +import { ComponentRef, DestroyRef, Directive, ElementRef, PLATFORM_ID, Renderer2, ViewContainerRef, inject, input } from '@angular/core'; +import { Tooltip } from './tooltip'; + +type TooltipPosition = 'top' | 'bottom'; + +const TOOLTIP_GAP = 8; +const ARROW_SIZE = 5; + +@Directive({ + selector: '[lfxTooltip]', + host: { + '[attr.data-testid]': '"tooltip-trigger"', + '(mouseenter)': 'show()', + '(mouseleave)': 'hide()', + '(focusin)': 'show()', + '(focusout)': 'hide()', + }, +}) +export class TooltipTrigger { + private readonly vcr = inject(ViewContainerRef); + private readonly el = inject(ElementRef); + private readonly renderer = inject(Renderer2); + private readonly document = inject(DOCUMENT); + private readonly destroyRef = inject(DestroyRef); + private readonly platformId = inject(PLATFORM_ID); + + public lfxTooltip = input.required(); + public lfxTooltipDescription = input(); + public lfxTooltipPosition = input('top'); + + private tooltipRef: ComponentRef | null = null; + private tooltipWrapper: HTMLElement | null = null; + + public constructor() { + this.destroyRef.onDestroy(() => this.hide()); + } + + public show(): void { + if (!isPlatformBrowser(this.platformId) || this.tooltipRef) { + return; + } + + this.tooltipRef = this.vcr.createComponent(Tooltip); + this.tooltipRef.setInput('label', this.lfxTooltip()); + + const description = this.lfxTooltipDescription(); + if (description) { + this.tooltipRef.setInput('description', description); + } + + this.tooltipRef.changeDetectorRef.detectChanges(); + + const tooltipEl = this.tooltipRef.location.nativeElement as HTMLElement; + + this.tooltipWrapper = this.renderer.createElement('div') as HTMLElement; + this.renderer.setStyle(this.tooltipWrapper, 'position', 'fixed'); + this.renderer.setStyle(this.tooltipWrapper, 'z-index', '9999'); + this.renderer.setStyle(this.tooltipWrapper, 'pointer-events', 'none'); + this.renderer.setStyle(this.tooltipWrapper, 'opacity', '0'); + this.renderer.setStyle(this.tooltipWrapper, 'transition', 'opacity 150ms ease-in-out'); + this.renderer.setStyle(this.tooltipWrapper, 'width', 'max-content'); + this.renderer.setStyle(this.tooltipWrapper, 'max-width', '24rem'); + + this.renderer.appendChild(this.tooltipWrapper, tooltipEl); + this.createArrow(); + this.renderer.appendChild(this.document.body, this.tooltipWrapper); + + this.positionTooltip(); + + requestAnimationFrame(() => { + if (this.tooltipWrapper) { + this.renderer.setStyle(this.tooltipWrapper, 'opacity', '1'); + } + }); + } + + public hide(): void { + if (this.tooltipWrapper) { + this.renderer.removeChild(this.document.body, this.tooltipWrapper); + this.tooltipWrapper = null; + } + + if (this.tooltipRef) { + this.tooltipRef.destroy(); + this.tooltipRef = null; + } + } + + private createArrow(): void { + if (!this.tooltipWrapper) { + return; + } + + const arrow = this.renderer.createElement('div') as HTMLElement; + const position = this.lfxTooltipPosition(); + + this.renderer.setStyle(arrow, 'position', 'absolute'); + this.renderer.setStyle(arrow, 'left', '50%'); + this.renderer.setStyle(arrow, 'transform', 'translateX(-50%)'); + this.renderer.setStyle(arrow, 'width', '0'); + this.renderer.setStyle(arrow, 'height', '0'); + this.renderer.setStyle(arrow, 'border-left', `${ARROW_SIZE}px solid transparent`); + this.renderer.setStyle(arrow, 'border-right', `${ARROW_SIZE}px solid transparent`); + + if (position === 'top') { + this.renderer.setStyle(arrow, 'bottom', `-${ARROW_SIZE}px`); + this.renderer.setStyle(arrow, 'border-top', `${ARROW_SIZE}px solid #0f172a`); + } else { + this.renderer.setStyle(arrow, 'top', `-${ARROW_SIZE}px`); + this.renderer.setStyle(arrow, 'border-bottom', `${ARROW_SIZE}px solid #0f172a`); + } + + this.renderer.setAttribute(arrow, 'data-testid', 'tooltip-arrow'); + this.renderer.appendChild(this.tooltipWrapper, arrow); + } + + private positionTooltip(): void { + if (!this.tooltipWrapper) { + return; + } + + const triggerRect = (this.el.nativeElement as HTMLElement).getBoundingClientRect(); + const tooltipRect = this.tooltipWrapper.getBoundingClientRect(); + const position = this.lfxTooltipPosition(); + + const left = triggerRect.left + triggerRect.width / 2 - tooltipRect.width / 2; + + let top: number; + if (position === 'top') { + top = triggerRect.top - tooltipRect.height - TOOLTIP_GAP; + } else { + top = triggerRect.bottom + TOOLTIP_GAP; + } + + const clampedLeft = Math.max(4, Math.min(left, window.innerWidth - tooltipRect.width - 4)); + + this.renderer.setStyle(this.tooltipWrapper, 'top', `${top}px`); + this.renderer.setStyle(this.tooltipWrapper, 'left', `${clampedLeft}px`); + + if (clampedLeft !== left) { + const arrowEl = this.tooltipWrapper.querySelector('[data-testid="tooltip-arrow"]') as HTMLElement; + if (arrowEl) { + const arrowLeft = triggerRect.left + triggerRect.width / 2 - clampedLeft; + this.renderer.setStyle(arrowEl, 'left', `${arrowLeft}px`); + } + } + } +} diff --git a/apps/lfx/src/app/shared/components/tooltip/tooltip.css b/apps/lfx/src/app/shared/components/tooltip/tooltip.css new file mode 100644 index 000000000..939b09541 --- /dev/null +++ b/apps/lfx/src/app/shared/components/tooltip/tooltip.css @@ -0,0 +1,6 @@ +/* Copyright The Linux Foundation and each contributor to LFX. */ +/* SPDX-License-Identifier: MIT */ + +:host { + display: contents; +} diff --git a/apps/lfx/src/app/shared/components/tooltip/tooltip.html b/apps/lfx/src/app/shared/components/tooltip/tooltip.html new file mode 100644 index 000000000..df345ee2f --- /dev/null +++ b/apps/lfx/src/app/shared/components/tooltip/tooltip.html @@ -0,0 +1,9 @@ + + + + diff --git a/apps/lfx/src/app/shared/components/tooltip/tooltip.stories.ts b/apps/lfx/src/app/shared/components/tooltip/tooltip.stories.ts new file mode 100644 index 000000000..4655d24c4 --- /dev/null +++ b/apps/lfx/src/app/shared/components/tooltip/tooltip.stories.ts @@ -0,0 +1,90 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import type { Meta, StoryObj } from '@storybook/angular'; +import { TooltipTrigger } from './tooltip-trigger'; + +const meta: Meta = { + title: 'Components/Tooltip', + component: TooltipTrigger, + tags: ['autodocs'], + argTypes: { + lfxTooltip: { control: 'text' }, + lfxTooltipDescription: { control: 'text' }, + lfxTooltipPosition: { control: 'select', options: ['top', 'bottom'] }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Simple: Story = { + render: (args) => ({ + props: args, + template: ``, + moduleMetadata: { imports: [TooltipTrigger] }, + }), + args: { lfxTooltip: 'Tooltip label' }, +}; + +export const WithDescription: Story = { + render: (args) => ({ + props: args, + template: ``, + moduleMetadata: { imports: [TooltipTrigger] }, + }), + args: { lfxTooltip: 'Tooltip label', lfxTooltipDescription: 'This is a short description for the tooltip.' }, +}; + +export const LongDescription: Story = { + render: (args) => ({ + props: args, + template: ``, + moduleMetadata: { imports: [TooltipTrigger] }, + }), + args: { + lfxTooltip: 'Tooltip label', + lfxTooltipDescription: + 'This is a longer description that demonstrates how the tooltip handles wrapping text across multiple lines within the max width constraint.', + }, +}; + +export const PositionBottom: Story = { + render: (args) => ({ + props: args, + template: `
`, + moduleMetadata: { imports: [TooltipTrigger] }, + }), + args: { lfxTooltip: 'Tooltip below' }, +}; + +export const AllVariants: Story = { + render: () => ({ + template: ` +
+
+ Simple +
+ + +
+
+
+ With Description +
+ + +
+
+
+ Position +
+ + +
+
+
+ `, + moduleMetadata: { imports: [TooltipTrigger] }, + }), +}; diff --git a/apps/lfx/src/app/shared/components/tooltip/tooltip.ts b/apps/lfx/src/app/shared/components/tooltip/tooltip.ts new file mode 100644 index 000000000..d55160ca1 --- /dev/null +++ b/apps/lfx/src/app/shared/components/tooltip/tooltip.ts @@ -0,0 +1,26 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import { Component, computed, input } from '@angular/core'; + +@Component({ + selector: 'lfx-tooltip', + imports: [], + templateUrl: './tooltip.html', + styleUrl: './tooltip.css', + host: { + '[attr.data-testid]': '"tooltip"', + }, +}) +export class Tooltip { + public label = input.required(); + public description = input(); + + public containerClasses = computed(() => { + return this.description() ? 'flex-col gap-1 items-start' : ''; + }); + + public labelClasses = computed(() => { + return this.description() ? '' : 'text-center w-full'; + }); +} diff --git a/apps/lfx/src/index.html b/apps/lfx/src/index.html new file mode 100644 index 000000000..cb5d9d070 --- /dev/null +++ b/apps/lfx/src/index.html @@ -0,0 +1,19 @@ + + + + + + + LFX + + + + + + + + + + + + diff --git a/apps/lfx/src/main.server.ts b/apps/lfx/src/main.server.ts new file mode 100644 index 000000000..6a4ed092f --- /dev/null +++ b/apps/lfx/src/main.server.ts @@ -0,0 +1,11 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import { BootstrapContext, bootstrapApplication } from '@angular/platform-browser'; + +import { AppComponent } from './app/app.component'; +import { config } from './app/app.config.server'; + +const bootstrap = (context: BootstrapContext) => bootstrapApplication(AppComponent, config, context); + +export default bootstrap; diff --git a/apps/lfx/src/main.ts b/apps/lfx/src/main.ts new file mode 100644 index 000000000..33570e3b9 --- /dev/null +++ b/apps/lfx/src/main.ts @@ -0,0 +1,9 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import { bootstrapApplication } from '@angular/platform-browser'; + +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, appConfig).catch((err) => console.error(err)); diff --git a/apps/lfx/src/server/helpers/api-error.ts b/apps/lfx/src/server/helpers/api-error.ts new file mode 100644 index 000000000..2b0a3c6d2 --- /dev/null +++ b/apps/lfx/src/server/helpers/api-error.ts @@ -0,0 +1,65 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +export class ApiError extends Error { + public readonly statusCode: number; + public readonly code: string; + public readonly details?: Record; + + public constructor(message: string, statusCode: number, code: string, details?: Record) { + super(message); + this.name = 'ApiError'; + this.statusCode = statusCode; + this.code = code; + this.details = details; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + } + + // --- Factory methods for common errors --- + + public static badRequest(message: string, details?: Record): ApiError { + return new ApiError(message, 400, 'BAD_REQUEST', details); + } + + public static unauthorized(message = 'Authentication required'): ApiError { + return new ApiError(message, 401, 'UNAUTHORIZED'); + } + + public static forbidden(message = 'Access denied'): ApiError { + return new ApiError(message, 403, 'FORBIDDEN'); + } + + public static notFound(message = 'Resource not found'): ApiError { + return new ApiError(message, 404, 'NOT_FOUND'); + } + + public static timeout(path: string, timeoutMs: number): ApiError { + return new ApiError(`Request timeout after ${timeoutMs}ms`, 408, 'TIMEOUT', { path }); + } + + public static upstream(message: string, statusCode: number, path: string, errorBody?: any): ApiError { + return new ApiError(message, statusCode, statusCode >= 500 ? 'UPSTREAM_ERROR' : 'UPSTREAM_CLIENT_ERROR', { + path, + ...(errorBody && { errorBody }), + }); + } + + public static networkError(message: string, path: string): ApiError { + return new ApiError(message, 502, 'NETWORK_ERROR', { path }); + } + + public toResponse(): Record { + return { + error: this.message, + code: this.code, + ...(this.details && { details: this.details }), + }; + } +} + +export function isApiError(error: unknown): error is ApiError { + return error instanceof ApiError; +} diff --git a/apps/lfx/src/server/helpers/error-serializer.ts b/apps/lfx/src/server/helpers/error-serializer.ts new file mode 100644 index 000000000..16653903b --- /dev/null +++ b/apps/lfx/src/server/helpers/error-serializer.ts @@ -0,0 +1,37 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +/** + * Custom error serializer for Pino logging + * Provides full stack traces in development for debugging while keeping production logs clean + * + * Development: Includes stack traces for local debugging + * Production: Excludes stack traces unless LOG_LEVEL=debug (cleaner CloudWatch logs) + */ +export const customErrorSerializer = (err: any) => { + if (!err) return err; + + const serialized: any = { + type: err.constructor?.name || err.name || 'Error', + message: err.message || String(err), + }; + + // Add common error properties if they exist + if (err.code) serialized.code = err.code; + if (err.statusCode) serialized.statusCode = err.statusCode; + if (err.status) serialized.status = err.status; + + // Include stack trace in development or when debug logging is enabled + if (process.env['NODE_ENV'] !== 'production' || process.env['LOG_LEVEL'] === 'debug') { + serialized.stack = err.stack; + } + + // Include any additional custom properties from error object + Object.keys(err).forEach((key) => { + if (!['message', 'stack', 'name', 'constructor'].includes(key)) { + serialized[key] = err[key]; + } + }); + + return serialized; +}; diff --git a/apps/lfx/src/server/helpers/server-logger.ts b/apps/lfx/src/server/helpers/server-logger.ts new file mode 100644 index 000000000..03b186391 --- /dev/null +++ b/apps/lfx/src/server/helpers/server-logger.ts @@ -0,0 +1,93 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import { IncomingMessage, ServerResponse } from 'node:http'; +import pino from 'pino'; +import pinoPretty from 'pino-pretty'; + +import { customErrorSerializer } from './error-serializer'; + +/** + * Whitelist-based request serializer. + * Only emits known-safe fields — prevents accidental leakage of + * authorization headers, cookies, API keys, or other sensitive data. + */ +export function reqSerializer(req: IncomingMessage & { id?: string; originalUrl?: string; ip?: string }) { + return { + id: req.id, + method: req.method, + url: req.originalUrl || req.url, + remoteAddress: req.ip || req.socket?.remoteAddress, + userAgent: req.headers['user-agent'], + }; +} + +/** + * Whitelist-based response serializer. + * Only emits statusCode — prevents leakage of set-cookie or other sensitive response headers. + */ +export function resSerializer(res: ServerResponse) { + return { + statusCode: res.statusCode, + }; +} + +/** + * Base Pino logger instance for server-level operations. + * + * Used for: + * - Server startup/shutdown messages + * - Direct logging from server code outside request context + * - Operations that don't have access to req.log + * - Infrastructure operations (NATS, Snowflake, etc.) + */ + +// Create pretty stream conditionally for development +const prettyStream = + process.env['NODE_ENV'] !== 'production' + ? pinoPretty({ + colorize: true, + translateTime: 'SYS:standard', + ignore: 'pid,hostname', + }) + : process.stdout; + +export const serverLogger = pino( + { + level: process.env['LOG_LEVEL'] || 'info', + base: { + service: 'lfx-ssr', + environment: process.env['NODE_ENV'] || 'development', + version: process.env['APP_VERSION'] || '1.0.0', + }, + mixin: () => { + const traceHeader = process.env['_X_AMZN_TRACE_ID']; + if (traceHeader) { + const traceId = traceHeader.split(';')[0]?.replace('Root=', ''); + return { aws_trace_id: traceId }; + } + return {}; + }, + serializers: { + err: customErrorSerializer, + error: customErrorSerializer, + req: reqSerializer, + res: resSerializer, + }, + redact: { + paths: ['access_token', 'refresh_token', 'authorization', 'cookie'], + remove: true, + }, + formatters: { + level: (label) => { + return { level: label.toUpperCase() }; + }, + bindings: (bindings) => ({ + pid: bindings['pid'], + hostname: bindings['hostname'], + }), + }, + timestamp: pino.stdTimeFunctions.isoTime, + }, + prettyStream +); diff --git a/apps/lfx/src/server/helpers/url-validation.ts b/apps/lfx/src/server/helpers/url-validation.ts new file mode 100644 index 000000000..6941f35db --- /dev/null +++ b/apps/lfx/src/server/helpers/url-validation.ts @@ -0,0 +1,193 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +/** + * URL and Cookie Validation Utilities + * + * This module provides secure validation functions for URLs and cookies to prevent + * various security vulnerabilities including: + * - Open redirect attacks + * - Domain spoofing attacks + * - Cookie injection attacks + * - Cross-site scripting (XSS) via URL manipulation + * - Unauthorized cookie acceptance from random domains + * + * Security Features: + * - Strict domain allowlisting per environment + * - Protocol validation (http/https only) + * - Exact domain matching (no subdomain/parent domain matching) + * - Suspicious character detection + * - Cookie domain extraction and validation + * - RFC 6265 cookie size compliance + * - Specific Auth0 client ID validation + * - Linux Foundation domain pattern validation + * + * @author Security Team + * @version 2.0.0 + */ + +/** + * Validates and sanitizes a URL to prevent open redirect attacks + * @param url - The URL to validate + * @param allowedDomains - Array of allowed domains (optional) + * @returns The sanitized URL or null if invalid + */ +export const validateAndSanitizeUrl = (url: string, allowedDomains?: string[]): string | null => { + if (!url || typeof url !== 'string') { + return null; + } + + try { + // Ensure the URL has a protocol + const urlWithProtocol = url.startsWith('http://') || url.startsWith('https://') ? url : `${process.env['PCC_BASE_URL']}${url}`; + const parsedUrl = new URL(urlWithProtocol); + + // Validate protocol + if (!['http:', 'https:'].includes(parsedUrl.protocol)) { + return null; + } + + // If allowed domains are specified, validate against them + if (allowedDomains && allowedDomains.length > 0) { + const domain = parsedUrl.origin.toLowerCase(); + const isAllowed = allowedDomains.some((allowedDomain) => domain === allowedDomain.toLowerCase()); + + if (!isAllowed) { + return null; + } + } + + // Return the original URL if it's relative, otherwise return the validated URL + return parsedUrl.toString(); + } catch { + return null; + } +}; + +/** + * Domain allowlist for each environment + */ +const DOMAIN_ALLOWLIST = { + development: [`auth0.${process.env['PCC_AUTH0_CLIENT_ID'] || ''}.is.authenticated`, 'auth-linuxfoundation-dev.auth0.com'], + staging: ['auth-linuxfoundation-staging.auth0.com'], + production: ['auth-sso.linuxfoundation.org'], +}; + +/** + * Extracts domain from a cookie string + * @param cookie - The cookie string to parse + * @returns The extracted domain or null if invalid + */ +const extractDomainFromCookie = (cookie: string): string | null => { + if (!cookie || typeof cookie !== 'string') { + return null; + } + + try { + // Additional security checks for cookie format + if (cookie.length > 4096) { + // RFC 6265: Cookies should not exceed 4096 bytes + return null; + } + + // Check for suspicious cookie patterns + if (cookie.includes(';') && cookie.includes('=') && cookie.toLowerCase().includes('domain=')) { + // Parse the cookie to extract domain + const cookieParts = cookie.split(';'); + const domainPart = cookieParts.find((part) => part.trim().toLowerCase().startsWith('domain=')); + + if (domainPart) { + // Extract domain value + const domain = domainPart.split('=')[1]?.trim(); + if (domain && domain.length > 0 && domain.length < 253) { + return domain; + } + } + } + + // If no domain is specified, try to extract from the cookie name + // This handles cases where the cookie name itself contains the domain + const cookieName = cookie.split('=')[0]?.trim(); + if (cookieName && cookieName.length > 0 && cookieName.length < 4096) { + // Only accept specific cookie patterns that match our allowlist + // This prevents accepting random Auth0 cookies from any domain + + // Check for our specific Auth0 cookie pattern + if (cookieName.includes('auth0.') && cookieName.includes('.is.authenticated')) { + // Extract the specific Auth0 client ID from the cookie name + const auth0Pattern = /^auth0\.([^.]+)\.is\.authenticated$/; + const match = cookieName.match(auth0Pattern); + if (match) { + const clientId = match[1]; + // Only accept if it matches our configured client ID + if (clientId === process.env['PCC_AUTH0_CLIENT_ID']) { + return cookieName; + } + } + return null; + } + + // Check for Linux Foundation specific domains only + if (cookieName.includes('linuxfoundation') || cookieName.includes('auth-sso')) { + // Validate against our specific domain patterns + const validPatterns = [/^auth-linuxfoundation-dev\.auth0\.com$/, /^auth-linuxfoundation-staging\.auth0\.com$/, /^auth-sso\.linuxfoundation\.org$/]; + + for (const pattern of validPatterns) { + if (pattern.test(cookieName)) { + return cookieName; + } + } + } + } + + return null; + } catch { + return null; + } +}; + +/** + * Validates if a cookie domain is allowed for the current environment + * @param cookie - The cookie string to validate + * @param environment - The current environment (development, staging, production) + * @returns True if the cookie domain is allowed, false otherwise + */ +export const validateCookieDomain = (cookie: string, environment: keyof typeof DOMAIN_ALLOWLIST): boolean => { + if (!cookie || !environment || !DOMAIN_ALLOWLIST[environment]) { + return false; + } + + const extractedDomain = extractDomainFromCookie(cookie); + if (!extractedDomain) { + return false; + } + + const allowedDomains = DOMAIN_ALLOWLIST[environment]; + const normalizedExtractedDomain = extractedDomain.toLowerCase(); + + // Additional security checks + // Prevent domain spoofing attacks + if ( + normalizedExtractedDomain.includes('..') || + normalizedExtractedDomain.includes('--') || + normalizedExtractedDomain.startsWith('.') || + normalizedExtractedDomain.endsWith('.') + ) { + return false; + } + + // Check for suspicious characters + const suspiciousChars = /[<>"'&]/; + if (suspiciousChars.test(normalizedExtractedDomain)) { + return false; + } + + // Strict validation - only allow exact matches from our allowlist + // This prevents accepting cookies from similar domains or subdomains + return allowedDomains.some((allowedDomain) => { + const normalizedAllowedDomain = allowedDomain.toLowerCase(); + + // Only allow exact matches - no subdomain or parent domain matching + return normalizedExtractedDomain === normalizedAllowedDomain; + }); +}; diff --git a/apps/lfx/src/server/middleware/auth.middleware.ts b/apps/lfx/src/server/middleware/auth.middleware.ts new file mode 100644 index 000000000..54ddea582 --- /dev/null +++ b/apps/lfx/src/server/middleware/auth.middleware.ts @@ -0,0 +1,391 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import { AuthConfig, AuthDecision, AuthMiddlewareResult, RouteAuthConfig, TokenExtractionResult } from '@lfx-one/shared/interfaces'; +import { NextFunction, Request, Response } from 'express'; + +import { ApiError } from '../helpers/api-error'; +import { logger } from '../services/logger.service'; + +// OIDC middleware already provides req.oidc with authentication context + +/** + * Default route configuration for the application + * Ordered by specificity - more specific patterns should come first + */ +const DEFAULT_ROUTE_CONFIG: RouteAuthConfig[] = [ + // Health check - completely public + { pattern: '/health', type: 'api', auth: 'public' }, + + // Public API routes - optional authentication with token benefits + { pattern: '/public/api', type: 'api', auth: 'optional', tokenRequired: false }, + + // Public meeting join - no authentication required + { pattern: '/meetings/', type: 'ssr', auth: 'optional' }, + + // Protected API routes - require authentication and token + { pattern: '/api', type: 'api', auth: 'required', tokenRequired: true }, + + // All other routes - Angular SSR routes requiring authentication + { pattern: '/', type: 'ssr', auth: 'required' }, +]; + +/** + * Default configuration for authentication middleware + */ +const DEFAULT_CONFIG: AuthConfig = { + routes: DEFAULT_ROUTE_CONFIG, + defaultAuth: 'required', + defaultType: 'ssr', +}; + +/** + * Classifies a route based on the request path and route configuration + */ +function classifyRoute(path: string, config: AuthConfig): RouteAuthConfig { + for (const routeConfig of config.routes) { + if (typeof routeConfig.pattern === 'string') { + const pattern = routeConfig.pattern; + // Exact match, or prefix match at a path-segment boundary + // Prevents '/health' matching '/healthz' or '/api' matching '/api-docs' + if (path === pattern || path.startsWith(pattern.endsWith('/') ? pattern : pattern + '/')) { + return routeConfig; + } + } else if (routeConfig.pattern.test(path)) { + return routeConfig; + } + } + + // Default fallback + return { + pattern: '/', + type: config.defaultType, + auth: config.defaultAuth, + }; +} + +/** + * Checks authentication status from OIDC session + */ +function checkAuthentication(req: Request): boolean { + logger.debug(req, 'auth_check', 'Authentication check debug', { + path: req.path, + hasOidc: !!req.oidc, + isAuthenticated: req.oidc?.isAuthenticated(), + cookies: Object.keys(req.cookies || {}), + }); + + const authenticated = req.oidc?.isAuthenticated() ?? false; + const message = authenticated ? 'Authentication check successful' : 'Authentication check failed - not authenticated'; + logger.debug(req, 'auth_check', message, { path: req.path, authenticated }); + + return authenticated; +} + +/** + * Extracts bearer token from OIDC session if available + * @param req - Express request object + * @param isOptionalRoute - Whether this is an optional auth route (affects logout behavior on refresh failure) + */ +async function extractBearerToken(req: Request, isOptionalRoute: boolean = false): Promise { + const startTime = Date.now(); + + try { + if (req.oidc?.isAuthenticated()) { + // Check if token exists and is expired + if (req.oidc.accessToken?.isExpired()) { + try { + // Always attempt to refresh the token for better UX + // Authenticated users should get enhanced features when possible + const refreshedToken = await req.oidc.accessToken.refresh(); + if (refreshedToken?.access_token) { + req.bearerToken = refreshedToken.access_token; + logger.debug(req, 'token_refresh', 'Token refreshed', { path: req.path }); + return { success: true, needsLogout: false }; + } + } catch (refreshError) { + // Different handling based on route type: + // - Optional routes: Log warning and continue without token (no logout) + // - Required routes: Log error and force logout to re-authenticate + if (isOptionalRoute) { + logger.warning(req, 'token_extraction', 'Token refresh failed on optional route - continuing without token', { + path: req.path, + failure_reason: 'token_refresh_failed', + is_optional_route: isOptionalRoute, + error: refreshError instanceof Error ? refreshError.message : 'Unknown error', + }); + } else { + logger.error(req, 'token_extraction', startTime, refreshError, { + path: req.path, + failure_reason: 'token_refresh_failed', + is_optional_route: isOptionalRoute, + }); + } + + // For optional routes, don't force logout - just continue without token + // For required routes, user needs to re-authenticate + return { success: false, needsLogout: !isOptionalRoute }; + } + } else if (req.oidc.accessToken?.access_token) { + // Token exists and is not expired + const accessToken = req.oidc.accessToken.access_token; + if (typeof accessToken === 'string') { + req.bearerToken = accessToken; + logger.debug(req, 'token_extraction', 'Token extracted', { path: req.path }); + return { success: true, needsLogout: false }; + } + } + } + } catch (error) { + logger.error(req, 'token_extraction', startTime, error, { + path: req.path, + failure_reason: 'extraction_error', + }); + return { success: false, needsLogout: false }; + } + + logger.debug(req, 'token_extraction', 'Token extraction failed - not authenticated', { + path: req.path, + }); + return { success: false, needsLogout: false }; +} + +/** + * Makes authentication decision based on route config and auth status + */ +function makeAuthDecision(result: AuthMiddlewareResult, req: Request): AuthDecision { + const { route, authenticated, hasToken, needsLogout } = result; + + // Public routes - always allow (check first to short-circuit) + if (route.auth === 'public') { + logger.debug(req, 'auth_decision', 'Public route - allowing access', { + path: req.path, + routeType: route.type, + authLevel: route.auth, + }); + return { action: 'allow' }; + } + + // Optional auth routes - always allow but may have enhanced features + // Token refresh is attempted for better UX, but failures don't block access + // (needsLogout is always false for optional routes) + if (route.auth === 'optional') { + logger.debug(req, 'auth_decision', 'Optional auth route - allowing access', { + path: req.path, + routeType: route.type, + authLevel: route.auth, + authenticated, + hasToken, + }); + return { action: 'allow' }; + } + + // If user needs logout due to failed token refresh (only for required auth routes now) + if (needsLogout) { + logger.warning(req, 'auth_token_refresh_failure', 'Token refresh failed - user needs logout', { + path: req.path, + routeType: route.type, + method: req.method, + }); + + // For API routes or non-GET requests, return 401 instead of logout redirect + // This prevents breaking XHR/Fetch clients that can't handle HTML redirects + if (route.type === 'api' || req.method !== 'GET') { + logger.debug(req, 'auth_decision_401', 'Returning 401 for API route or non-GET request', { + path: req.path, + routeType: route.type, + method: req.method, + }); + return { + action: 'error', + errorType: 'authentication', + statusCode: 401, + }; + } + + // For SSR GET requests, proceed with logout redirect + logger.debug(req, 'auth_decision_logout', 'Proceeding with logout redirect for SSR GET request', { + path: req.path, + routeType: route.type, + method: req.method, + }); + return { action: 'logout' }; + } + + // Required auth routes + if (route.auth === 'required') { + if (!authenticated) { + // SSR routes - redirect to login + if (route.type === 'ssr' && req.method === 'GET') { + logger.debug(req, 'auth_decision_redirect_login', 'Redirecting to login for unauthenticated SSR GET request', { + path: req.path, + routeType: route.type, + method: req.method, + }); + return { + action: 'redirect', + redirectUrl: `/login?returnTo=${encodeURIComponent(req.originalUrl)}`, + }; + } + + // Non-GET SSR routes - return 401 error + if (route.type === 'ssr' && req.method !== 'GET') { + logger.warning(req, 'auth_check', 'SSR route requires authentication for non-GET request - returning 401', { + path: req.path, + routeType: route.type, + method: req.method, + }); + return { + action: 'error', + errorType: 'authentication', + statusCode: 401, + }; + } + + // API routes - return 401 error + if (route.type === 'api') { + logger.warning(req, 'auth_check', 'API route requires authentication - returning 401', { + path: req.path, + routeType: route.type, + method: req.method, + }); + return { + action: 'error', + errorType: 'authentication', + statusCode: 401, + }; + } + } + + // Token validation for API routes + if (route.tokenRequired && !hasToken) { + logger.warning(req, 'auth_check', 'API route requires bearer token - returning 401', { + path: req.path, + authenticated, + hasToken, + }); + return { + action: 'error', + errorType: 'authentication', + statusCode: 401, + }; + } + } + + logger.debug(req, 'auth_decision', 'Authentication check passed - allowing access', { + path: req.path, + routeType: route.type, + authLevel: route.auth, + authenticated, + hasToken, + }); + + return { action: 'allow' }; +} + +/** + * Executes the authentication decision + */ +async function executeAuthDecision(decision: AuthDecision, req: Request, res: Response, next: NextFunction): Promise { + switch (decision.action) { + case 'allow': + next(); + break; + + case 'redirect': + res.oidc.login({ returnTo: decision.redirectUrl || req.originalUrl }); + break; + + case 'logout': + // Log user out due to token refresh failure + logger.debug(req, 'auth_logout_execution', 'Executing logout due to token refresh failure', { + path: req.path, + originalUrl: req.originalUrl, + }); + // Redirect to home page after logout to avoid redirect loops + res.oidc.logout({ returnTo: '/' }); + break; + + case 'error': { + const error = + decision.errorType === 'authorization' + ? ApiError.forbidden('Insufficient permissions to access this resource') + : ApiError.unauthorized('Authentication required to access this resource'); + next(error); + break; + } + } +} + +/** + * Authentication middleware that handles all authentication scenarios + * for both SSR routes and API endpoints. + */ +export function createAuthMiddleware(config: AuthConfig = DEFAULT_CONFIG) { + return async (req: Request, res: Response, next: NextFunction): Promise => { + const startTime = Date.now(); + + try { + // 1. Route classification + const routeConfig = classifyRoute(req.path, config); + + logger.debug(req, 'auth_middleware', 'Starting authentication check', { + path: req.path, + method: req.method, + routeType: routeConfig.type, + authLevel: routeConfig.auth, + tokenRequired: routeConfig.tokenRequired, + }); + + // 2. Authentication status check + const authenticated = checkAuthentication(req); + + // 3. Token extraction (if needed) + let hasToken = false; + let needsLogout = false; + if (routeConfig.tokenRequired || routeConfig.auth === 'optional') { + // Always attempt token refresh for better UX + // Optional routes will handle refresh failures gracefully (no forced logout) + // Required routes will force logout on refresh failure + const isOptionalRoute = routeConfig.auth === 'optional'; + const tokenResult = await extractBearerToken(req, isOptionalRoute); + hasToken = tokenResult.success; + needsLogout = tokenResult.needsLogout; + } + + // 4. Authentication context is already available in req.oidc + + // 5. Build result for decision making + const result: AuthMiddlewareResult = { + route: routeConfig, + authenticated, + hasToken, + needsLogout, + }; + + // 6. Make authentication decision + const decision = makeAuthDecision(result, req); + + // 7. Execute decision + await executeAuthDecision(decision, req, res, next); + + logger.debug(req, 'auth_middleware', 'Authentication decision made', { + path: req.path, + decision: decision.action, + authenticated, + hasToken, + }); + } catch (error) { + logger.error(req, 'auth_middleware', startTime, error, { + path: req.path, + method: req.method, + }); + next(error); + } + }; +} + +/** + * Default authentication middleware instance + */ +export const authMiddleware = createAuthMiddleware(); diff --git a/apps/lfx/src/server/middleware/error-handler.middleware.ts b/apps/lfx/src/server/middleware/error-handler.middleware.ts new file mode 100644 index 000000000..79b5fe038 --- /dev/null +++ b/apps/lfx/src/server/middleware/error-handler.middleware.ts @@ -0,0 +1,82 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import { NextFunction, Request, Response } from 'express'; + +import { ApiError, isApiError } from '../helpers/api-error'; +import { logger } from '../services/logger.service'; + +/** + * Derives operation name from request path for logging context + */ +function getOperationFromPath(path: string): string { + return ( + path + .replace(/^\//, '') + .replace(/\/[0-9a-f-]{36}/gi, '') + .replace(/\/\d+/g, '') + .replace(/\//g, '_') + .replace(/_+$/, '') || 'api_request' + ); +} + +/** + * Centralized error handler middleware — the SINGLE place for error logging. + * + * Controllers and domain services do NOT log errors; they let errors propagate + * naturally to Express error handling, which routes them here. + */ +export function apiErrorHandler(error: Error | ApiError, req: Request, res: Response, next: NextFunction): void { + if (res.headersSent) { + next(error); + return; + } + + const operation = getOperationFromPath(req.path); + const now = (req as Request & { _startTime?: number })._startTime || Date.now(); + + if (isApiError(error)) { + const logContext = { + error_type: error.code, + status_code: error.statusCode, + request_id: req.id, + path: req.path, + method: req.method, + user_agent: req.get('User-Agent'), + details: error.details, + }; + + if (error.statusCode >= 500) { + logger.error(req, operation, now, error, logContext); + } else if (error.statusCode >= 400) { + logger.warning(req, operation, `API error: ${error.message}`, { ...logContext, err: error }); + } else { + logger.debug(req, operation, `API error: ${error.message}`, { ...logContext, err: error }); + } + + const response = error.toResponse(); + // Strip details from 5xx and upstream errors to avoid leaking internal payloads + if (error.statusCode >= 500 || error.code === 'UPSTREAM_ERROR' || error.code === 'UPSTREAM_CLIENT_ERROR') { + delete response['details']; + } + res.status(error.statusCode).json({ + ...response, + path: req.path, + }); + return; + } + + // Unhandled errors + logger.error(req, operation, now, error, { + error_type: 'unhandled', + path: req.path, + method: req.method, + user_agent: req.get('User-Agent'), + }); + + res.status(500).json({ + error: 'Internal server error', + code: 'INTERNAL_ERROR', + path: req.path, + }); +} diff --git a/apps/lfx/src/server/server.ts b/apps/lfx/src/server/server.ts new file mode 100644 index 000000000..d2df39a07 --- /dev/null +++ b/apps/lfx/src/server/server.ts @@ -0,0 +1,256 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import { APP_BASE_HREF } from '@angular/common'; +import { REQUEST } from '@angular/core'; +import { AngularNodeAppEngine, createNodeRequestHandler, isMainModule, writeResponseToNodeResponse } from '@angular/ssr/node'; +import { AuthContext, User } from '@lfx-one/shared/interfaces'; +import dotenv from 'dotenv'; +import express, { NextFunction, Request, Response } from 'express'; +import { attemptSilentLogin, auth, ConfigParams } from 'express-openid-connect'; +import { dirname, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import pinoHttp from 'pino-http'; + +import { ApiError } from './helpers/api-error'; +import { customErrorSerializer } from './helpers/error-serializer'; +import { reqSerializer, resSerializer, serverLogger } from './helpers/server-logger'; +import { validateAndSanitizeUrl } from './helpers/url-validation'; +import { authMiddleware } from './middleware/auth.middleware'; +import { apiErrorHandler } from './middleware/error-handler.middleware'; +import { logger } from './services/logger.service'; + +if (process.env['NODE_ENV'] !== 'production') { + dotenv.config(); +} + +const serverDistFolder = dirname(fileURLToPath(import.meta.url)); +const browserDistFolder = resolve(serverDistFolder, '../browser'); + +const angularApp = new AngularNodeAppEngine(); +const app = express(); + +/** + * Enable gzip/deflate compression for all responses. + * + * Configuration optimized for SSR: + * - Compresses HTML, CSS, JS, JSON, and other text-based responses + * - Uses level 6 (balanced compression/speed ratio) + * - 1KB threshold to avoid compressing small responses + * - Uses default filter for text-based content types + */ +// eslint-disable-next-line @typescript-eslint/no-require-imports +const compression = require('compression'); +app.use( + compression({ + level: 6, // Balanced compression level (1=fastest, 9=best compression) + threshold: 1024, // Only compress responses larger than 1KB + }) +); + +app.use(express.json({ limit: '15mb' })); +app.use(express.urlencoded({ extended: true, limit: '15mb' })); + +/** + * Serve static files from /browser + */ +app.get( + '**', + express.static(browserDistFolder, { + maxAge: '1y', + index: false, // Let Angular SSR handle the index route + }) +); + +// Add health endpoint before logger middleware +app.get('/health', (_req: Request, res: Response) => { + res.send('OK'); +}); + +/** + * HTTP request/response logging middleware using Pino. + * + * Provides: + * - Automatic HTTP request/response logging + * - Request-scoped logger accessible via req.log in route handlers + * - Request correlation and timing + * - Consistent configuration with serverLogger + * + * Usage in routes: req.log.info({...}, 'message') + */ +const httpLogger = pinoHttp({ + logger: serverLogger, // Use the same base logger for consistency + serializers: { + err: customErrorSerializer, + error: customErrorSerializer, + req: reqSerializer, + res: resSerializer, + }, + // Disable automatic request/response logging - our LoggerService handles operation logging + autoLogging: false, +}); + +// Add HTTP logger middleware after health endpoint to avoid logging health check +app.use(httpLogger); + +const authConfig: ConfigParams = { + authRequired: false, // Disable global auth requirement to handle it in selective middleware + auth0Logout: true, + baseURL: process.env['PCC_BASE_URL'] || 'http://localhost:4200', + clientID: process.env['PCC_AUTH0_CLIENT_ID'] || 'local-dev-placeholder', + issuerBaseURL: process.env['PCC_AUTH0_ISSUER_BASE_URL'] || 'https://example.com', + secret: process.env['PCC_AUTH0_SECRET'] || 'local-dev-secret-minimum-32-chars-long', + authorizationParams: { + response_type: 'code', + audience: process.env['PCC_AUTH0_AUDIENCE'] || 'https://example.com', + scope: 'openid email profile access:api offline_access', + }, + clientSecret: process.env['PCC_AUTH0_CLIENT_SECRET'] || 'local-dev-placeholder', + routes: { + login: false, + }, +}; + +app.use(auth(authConfig)); + +// Silent login attempt for meeting join pages only +// If user has SSO session elsewhere, they'll be authenticated automatically +// If not, they proceed as unauthenticated (route is optional auth) +app.use('/meetings/', attemptSilentLogin()); + +app.use('/login', (req: Request, res: Response) => { + if (req.oidc?.isAuthenticated() && !req.oidc?.accessToken?.isExpired()) { + const returnTo = req.query['returnTo'] as string; + const validatedReturnTo = validateAndSanitizeUrl(returnTo, [process.env['PCC_BASE_URL'] as string]); + if (validatedReturnTo) { + res.redirect(validatedReturnTo); + } else { + res.redirect('/'); + } + } else { + const returnTo = req.query['returnTo'] as string; + const validatedReturnTo = validateAndSanitizeUrl(returnTo, [process.env['PCC_BASE_URL'] as string]); + if (validatedReturnTo) { + res.oidc.login({ returnTo: validatedReturnTo }); + } else { + res.oidc.login({ returnTo: '/' }); + } + } +}); + +// Apply authentication middleware to all routes +app.use(authMiddleware); + +// API routes will be mounted here + +// Catch unmatched API routes and return 404 before falling through to SSR +app.use(['/api/*', '/public/api/*'], (req: Request, _res: Response, next: NextFunction) => { + next(ApiError.notFound(`No API route matches ${req.method} ${req.path}`)); +}); + +// Add API error handler middleware +app.use(['/api/*', '/public/api/*'], apiErrorHandler); + +/** + * Handle all other requests by rendering the Angular application. + * Require authentication for all non-API routes. + */ +app.use('/**', async (req: Request, res: Response, next: NextFunction) => { + const ssrStartTime = Date.now(); + const authContext: AuthContext = { + authenticated: false, + user: null, + }; + + if (req.oidc?.isAuthenticated() && !req.oidc?.accessToken?.isExpired()) { + authContext.authenticated = true; + try { + // Fetch user info from OIDC + authContext.user = req.oidc?.user as User; + + if (!authContext.user?.name) { + authContext.user = await req.oidc.fetchUserInfo(); + } + } catch (error) { + // If userinfo fetch fails, fall back to basic user info from token + // Do NOT logout — a transient Auth0/userinfo failure should not sign out valid sessions + logger.warning(req, 'ssr_user_info', 'Failed to fetch user info, using basic user data from token', { + err: error, + path: req.path, + }); + } + } + + angularApp + .handle(req, { + auth: authContext, + providers: [ + { provide: APP_BASE_HREF, useValue: process.env['PCC_BASE_URL'] }, + { provide: REQUEST, useValue: req }, + ], + }) + .then((response) => { + if (response) { + return writeResponseToNodeResponse(response, res); + } + + return next(); + }) + .catch((error: unknown) => { + const err = error instanceof Error ? error : new Error(String(error)); + const code = error instanceof Error ? (error as Error & { code?: string }).code : undefined; + + if (code === 'NOT_FOUND') { + res.status(404).send('Not Found'); + } else if (code === 'UNAUTHORIZED') { + res.status(401).send('Unauthorized'); + } else { + logger.error(req, 'ssr_render', ssrStartTime, err, { + url: req.url, + method: req.method, + }); + res.status(500).send('Internal Server Error'); + } + }); +}); + +// Global error handler for all routes (must be last) +app.use((error: Error, req: Request, res: Response, next: NextFunction) => { + // If response already sent, delegate to default Express error handler + if (res.headersSent) { + next(error); + return; + } + + // Use the same error handler logic for all routes + apiErrorHandler(error, req, res, next); +}); + +/** + * Start the server if this module is the main entry point. + * The server listens on the port defined by the `PORT` environment variable, or defaults to 4200. + */ +export function startServer() { + const port = process.env['PORT'] || 4201; + app.listen(port, () => { + logger.debug(undefined, 'server_startup', 'Node Express server started', { + port, + url: `http://localhost:${port}`, + node_env: process.env['NODE_ENV'] || 'development', + pm2: process.env['PM2'] === 'true', + }); + }); +} + +const metaUrl = import.meta.url; +const isMain = isMainModule(metaUrl); +const isPM2 = process.env['PM2'] === 'true'; + +if (isMain || isPM2) { + startServer(); +} + +/** + * The request handler used by the Angular CLI (dev-server and during build). + */ +export const reqHandler = createNodeRequestHandler(app); diff --git a/apps/lfx/src/server/services/lfx.service.ts b/apps/lfx/src/server/services/lfx.service.ts new file mode 100644 index 000000000..3310101de --- /dev/null +++ b/apps/lfx/src/server/services/lfx.service.ts @@ -0,0 +1,135 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import { DEFAULT_QUERY_PARAMS } from '@lfx-one/shared/constants'; +import { Request } from 'express'; + +import { ApiError } from '../helpers/api-error'; + +/** + * LfxService - Unified upstream microservice communication layer + * + * Replaces both MicroserviceProxyService and ApiClientService with a single, + * flattened class that handles all Go microservice communication. + * + * Features: + * - Native fetch with AbortSignal.timeout + * - User bearer token forwarding by default + * - Query parameter building with DEFAULT_QUERY_PARAMS merge + * - JSON request/response serialization + * - Structured error handling via ApiError + */ +class LfxService { + private readonly timeout = 30000; + private readonly userAgent = 'LFX-Server/1.0'; + + // --- Public API --- + + public async get(req: Request, path: string, query?: Record): Promise { + return this.request(req, 'GET', path, undefined, query); + } + + public async post(req: Request, path: string, data?: any, query?: Record): Promise { + return this.request(req, 'POST', path, data, query); + } + + public async put(req: Request, path: string, data?: any, query?: Record): Promise { + return this.request(req, 'PUT', path, data, query); + } + + public async patch(req: Request, path: string, data?: any, query?: Record): Promise { + return this.request(req, 'PATCH', path, data, query); + } + + public async delete(req: Request, path: string, query?: Record): Promise { + return this.request(req, 'DELETE', path, undefined, query); + } + + // --- Private --- + + private async request( + req: Request, + method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE', + path: string, + data?: any, + query?: Record + ): Promise { + const baseUrl = process.env['LFX_V2_SERVICE'] || 'http://lfx-api.k8s.orb.local'; + const mergedQuery = { ...query, ...DEFAULT_QUERY_PARAMS }; + const url = this.buildUrl(`${baseUrl}${path}`, mergedQuery); + const token = req.bearerToken; + + const headers: Record = { + Accept: 'application/json', + 'Content-Type': 'application/json', + 'User-Agent': this.userAgent, + }; + + if (token) { + headers['Authorization'] = `Bearer ${token}`; + } + + const init: RequestInit = { + method, + headers, + signal: AbortSignal.timeout(this.timeout), + }; + + if (data && ['POST', 'PUT', 'PATCH'].includes(method)) { + init.body = JSON.stringify(data); + } + + try { + const response = await fetch(url, init); + + if (!response.ok) { + let errorBody: any = null; + try { + const text = await response.text(); + if (text) errorBody = JSON.parse(text); + } catch { + // ignore parse failures + } + + const message = errorBody?.message || errorBody?.error || response.statusText; + throw ApiError.upstream(message, response.status, path, errorBody); + } + + const text = await response.text(); + return (text ? JSON.parse(text) : null) as T; + } catch (error: unknown) { + // Re-throw ApiErrors as-is + if (error instanceof ApiError) throw error; + + if (error instanceof Error) { + if (error.name === 'TimeoutError' || error.name === 'AbortError') { + throw ApiError.timeout(path, this.timeout); + } + + throw ApiError.networkError(`Request failed: ${error.message}`, path); + } + + throw error; + } + } + + private buildUrl(base: string, query?: Record): string { + if (!query) return base; + + const params = new URLSearchParams(); + for (const [key, value] of Object.entries(query)) { + if (Array.isArray(value)) { + for (const item of value) { + params.append(key, String(item)); + } + } else if (value !== undefined && value !== null) { + params.append(key, String(value)); + } + } + + const qs = params.toString(); + return qs ? `${base}?${qs}` : base; + } +} + +export const lfxService = new LfxService(); diff --git a/apps/lfx/src/server/services/logger.service.ts b/apps/lfx/src/server/services/logger.service.ts new file mode 100644 index 000000000..2c926413a --- /dev/null +++ b/apps/lfx/src/server/services/logger.service.ts @@ -0,0 +1,466 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +import { SENSITIVE_FIELDS } from '@lfx-one/shared/constants'; +import { Request } from 'express'; + +import { serverLogger } from '../helpers/server-logger'; + +/** + * Operation state for tracking active operations per request + */ +interface OperationState { + startTime: number; + operation: string; + logged: boolean; +} + +/** + * Options for starting an operation + */ +interface StartOperationOptions { + silent?: boolean; +} + +/** + * Options for error logging + */ +interface ErrorOptions { + skipIfLogged?: boolean; +} + +/** + * LoggerService - Singleton service for consistent, deduplicated logging + * + * Features: + * - Operation tracking to prevent duplicate logs (request-scoped only) + * - CloudWatch-optimized JSON output + * - Request correlation via request_id (when req provided) + * - Duration tracking for performance monitoring + * - Supports both request-scoped (with req) and infrastructure (without req) logging + */ +export class LoggerService { + private static instance: LoggerService; + + /** + * WeakMap to track operations per request without memory leaks + * Key: Request object, Value: Map of operation name to state + */ + private operationStacks = new WeakMap>(); + + // eslint-disable-next-line @typescript-eslint/no-empty-function + private constructor() {} + + /** + * Get the singleton instance + */ + public static getInstance(): LoggerService { + if (!LoggerService.instance) { + LoggerService.instance = new LoggerService(); + } + return LoggerService.instance; + } + + /** + * Starts tracking an operation + * Logs at DEBUG for request-scoped calls, INFO for infrastructure (ADR 0002) + * Returns startTime for duration calculation + * @param req - Request object (optional - use undefined for infrastructure operations) + */ + public startOperation(req: Request | undefined, operation: string, metadata: Record = {}, options: StartOperationOptions = {}): number { + const startTime = Date.now(); + + // Infrastructure logging (no request context) + if (!req) { + if (!options.silent) { + serverLogger.info( + { + operation, + status: 'started', + ...(Object.keys(metadata).length > 0 && { data: metadata }), + }, + `Starting ${this.formatOperation(operation)}` + ); + } + return startTime; + } + + // Request-scoped logging with deduplication tracking + const stack = this.getOperationStack(req); + + // Check for duplicate start calls + if (stack.has(operation)) { + const existing = stack.get(operation); + if (existing && !existing.logged) { + req.log.warn( + { + operation, + warning: 'duplicate_start_detected', + original_start: existing.startTime, + request_id: req.id, + }, + `Duplicate start detected for ${this.formatOperation(operation)}` + ); + } + } + + // Store operation state + stack.set(operation, { + startTime, + operation, + logged: false, + }); + + // Log start at DEBUG level (ADR 0002: startOperation never emits INFO for request-scoped calls) + if (!options.silent) { + req.log.debug( + { + operation, + status: 'started', + request_id: req.id, + user_agent: req.get('User-Agent'), + ip_address: req.ip, + ...(Object.keys(metadata).length > 0 && { data: metadata }), + }, + `Starting ${this.formatOperation(operation)}` + ); + } + + return startTime; + } + + /** + * Logs successful completion of an operation + * Reads (GET/HEAD/OPTIONS) log at DEBUG, writes (POST/PUT/DELETE/PATCH) log at INFO (ADR 0002) + * @param req - Request object (optional - use undefined for infrastructure operations) + */ + public success(req: Request | undefined, operation: string, startTime: number, metadata: Record = {}): void { + const duration = Date.now() - startTime; + + // Infrastructure logging (no request context) + if (!req) { + const { status_code, ...restMetadata } = metadata as { status_code?: number; [key: string]: unknown }; + serverLogger.info( + { + operation, + status: 'success', + duration_ms: duration, + ...(status_code && { status_code }), + ...(Object.keys(restMetadata).length > 0 && { data: restMetadata }), + }, + `Successfully completed ${this.formatOperation(operation)}` + ); + return; + } + + // Request-scoped logging with deduplication tracking + const stack = this.getOperationStack(req); + const opState = stack.get(operation); + + // Mark as logged to prevent duplicate logging + if (opState) { + opState.logged = true; + } + + // Extract status_code from metadata if present, rest goes to data + const { status_code, ...restMetadata } = metadata as { status_code?: number; [key: string]: unknown }; + + const logData = { + operation, + status: 'success', + duration_ms: duration, + status_code: status_code || 200, + request_id: req.id, + ...(Object.keys(restMetadata).length > 0 && { data: restMetadata }), + }; + const logMessage = `Successfully completed ${this.formatOperation(operation)}`; + + // ADR 0002: reads (GET/HEAD/OPTIONS) log at DEBUG, writes (POST/PUT/DELETE/PATCH) log at INFO + if (this.isReadMethod(req)) { + req.log.debug(logData, logMessage); + } else { + req.log.info(logData, logMessage); + } + + // Clean up completed operation + stack.delete(operation); + } + + /** + * Logs operation failure with error details + * Can skip logging if already logged (prevents duplicates - request-scoped only) + * @param req - Request object (optional - use undefined for infrastructure operations) + */ + public error( + req: Request | undefined, + operation: string, + startTime: number, + error: unknown, + metadata: Record = {}, + options: ErrorOptions = {} + ): void { + const duration = Date.now() - startTime; + + // Infrastructure logging (no request context) + if (!req) { + serverLogger.error( + { + operation, + status: 'failed', + duration_ms: duration, + err: error, + ...(Object.keys(metadata).length > 0 && { data: metadata }), + }, + `Failed to ${this.formatOperation(operation)}` + ); + return; + } + + // Request-scoped logging with deduplication tracking + const stack = this.getOperationStack(req); + const opState = stack.get(operation); + + // Skip if already logged and skipIfLogged is true + if (options.skipIfLogged && opState?.logged) { + req.log.debug( + { + operation, + skip_reason: 'already_logged', + request_id: req.id, + }, + `Skipping duplicate error log for ${this.formatOperation(operation)}` + ); + return; + } + + // Mark as logged + if (opState) { + opState.logged = true; + } + + req.log.error( + { + operation, + status: 'failed', + duration_ms: duration, + err: error, + request_id: req.id, + ...(Object.keys(metadata).length > 0 && { data: metadata }), + }, + `Failed to ${this.formatOperation(operation)}` + ); + + // Clean up failed operation + stack.delete(operation); + } + + /** + * Logs ETag-related operations + * @param req - Request object (optional - use undefined for infrastructure operations) + */ + public etag( + req: Request | undefined, + operation: string, + resourceType: string, + resourceId: string, + etag?: string, + metadata: Record = {} + ): void { + // Infrastructure logging (no request context) + if (!req) { + serverLogger.info( + { + operation, + resource_type: resourceType, + resource_id: resourceId, + etag, + ...(Object.keys(metadata).length > 0 && { data: metadata }), + }, + `ETag operation: ${this.formatOperation(operation)}` + ); + return; + } + + // Request-scoped logging + req.log.info( + { + operation, + resource_type: resourceType, + resource_id: resourceId, + etag, + request_id: req.id, + ...(Object.keys(metadata).length > 0 && { data: metadata }), + }, + `ETag operation: ${this.formatOperation(operation)}` + ); + } + + /** + * Logs warning messages with operation context + * @param req - Request object (optional - use undefined for infrastructure operations) + */ + public warning(req: Request | undefined, operation: string, message: string, metadata: Record = {}): void { + // Extract err from metadata to place at top level for proper error serialization + const { err, ...rest } = metadata; + + // Infrastructure logging (no request context) + if (!req) { + serverLogger.warn( + { + operation, + status: 'warning', + warning_message: message, + ...(err ? { err } : {}), // err at top level for Pino error serializer + ...(Object.keys(rest).length > 0 && { data: rest }), + }, + `Warning during ${this.formatOperation(operation)}: ${message}` + ); + return; + } + + // Request-scoped logging + req.log.warn( + { + operation, + status: 'warning', + warning_message: message, + request_id: req.id, + ...(err ? { err } : {}), // err at top level for Pino error serializer + ...(Object.keys(rest).length > 0 && { data: rest }), + }, + `Warning during ${this.formatOperation(operation)}: ${message}` + ); + } + + /** + * Logs info messages with operation context + * Use for significant business operations that should be visible in production + * @param req - Request object (optional - use undefined for infrastructure operations) + */ + public info(req: Request | undefined, operation: string, message: string, metadata: Record = {}): void { + // Extract err from metadata to place at top level for proper error serialization + const { err, ...rest } = metadata; + + // Infrastructure logging (no request context) + if (!req) { + serverLogger.info( + { + operation, + status: 'info', + ...(err ? { err } : {}), // err at top level for Pino error serializer + ...(Object.keys(rest).length > 0 && { data: rest }), + }, + `${this.formatOperation(operation)}: ${message}` + ); + return; + } + + // Request-scoped logging + req.log.info( + { + operation, + status: 'info', + request_id: req.id, + ...(err ? { err } : {}), // err at top level for Pino error serializer + ...(Object.keys(rest).length > 0 && { data: rest }), + }, + `${this.formatOperation(operation)}: ${message}` + ); + } + + /** + * Logs debug messages with operation context + * Use for detailed internal state, preparation steps, or verbose information + * @param req - Request object (optional - use undefined for infrastructure operations) + */ + public debug(req: Request | undefined, operation: string, message: string, metadata: Record = {}): void { + // Extract err from metadata to place at top level for proper error serialization + const { err, ...rest } = metadata; + + // Infrastructure logging (no request context) + if (!req) { + serverLogger.debug( + { + operation, + status: 'debug', + ...(err ? { err } : {}), // err at top level for Pino error serializer + ...(Object.keys(rest).length > 0 && { data: rest }), + }, + `${this.formatOperation(operation)}: ${message}` + ); + return; + } + + // Request-scoped logging + req.log.debug( + { + operation, + status: 'debug', + request_id: req.id, + ...(err ? { err } : {}), // err at top level for Pino error serializer + ...(Object.keys(rest).length > 0 && { data: rest }), + }, + `${this.formatOperation(operation)}: ${message}` + ); + } + + /** + * Sanitizes sensitive data from metadata before logging + */ + public sanitize(metadata: Record): Record { + const sanitized = { ...metadata }; + + Object.keys(sanitized).forEach((key) => { + if (SENSITIVE_FIELDS.some((field) => key.toLowerCase().includes(field))) { + sanitized[key] = '[REDACTED]'; + } + }); + + return sanitized; + } + + /** + * Checks if an operation has been started + */ + public hasOperation(req: Request, operation: string): boolean { + const stack = this.getOperationStack(req); + return stack.has(operation); + } + + /** + * Gets the start time of an operation (useful for nested operations) + */ + public getOperationStartTime(req: Request, operation: string): number | undefined { + const stack = this.getOperationStack(req); + return stack.get(operation)?.startTime; + } + + /** + * Get or create the operation stack for a request + */ + private getOperationStack(req: Request): Map { + if (!this.operationStacks.has(req)) { + this.operationStacks.set(req, new Map()); + } + return this.operationStacks.get(req)!; + } + + /** + * Checks if the HTTP method is a read operation (GET, HEAD, OPTIONS) + * Used to determine log levels per ADR 0002: reads log at DEBUG, writes at INFO + */ + private isReadMethod(req: Request): boolean { + const method = req.method?.toUpperCase(); + return method === 'GET' || method === 'HEAD' || method === 'OPTIONS'; + } + + /** + * Format operation name for log messages + */ + private formatOperation(operation: string): string { + return operation.replace(/_/g, ' '); + } +} + +// Export singleton instance for convenient usage +export const logger = LoggerService.getInstance(); diff --git a/apps/lfx/src/styles.css b/apps/lfx/src/styles.css new file mode 100644 index 000000000..3173fafa4 --- /dev/null +++ b/apps/lfx/src/styles.css @@ -0,0 +1,214 @@ +/* Copyright The Linux Foundation and each contributor to LFX. */ +/* SPDX-License-Identifier: MIT */ + +@import 'tailwindcss'; + +@variant dark (&:where(.dark, .dark *)); + +@theme { + /* ─── Brand Color Scale (based on #0068fa) ─── */ + --color-brand-50: #eff6ff; + --color-brand-100: #dbeafe; + --color-brand-200: #bfdbfe; + --color-brand-300: #93c5fd; + --color-brand-400: #60a5fa; + --color-brand-500: #0068fa; + --color-brand-600: #0052cc; + --color-brand-700: #003d99; + --color-brand-800: #002b6b; + --color-brand-900: #001a42; + + /* ─── Neutral Color Scale (from Figma Coherence UI Kit) ─── */ + --color-neutral-50: #f8fafc; + --color-neutral-100: #f1f5f9; + --color-neutral-200: #e2e8f0; + --color-neutral-300: #cad5e2; + --color-neutral-400: #94a3b8; + --color-neutral-500: #62748e; + --color-neutral-600: #45556c; + --color-neutral-700: #334155; + --color-neutral-800: #1e293b; + --color-neutral-900: #0f172a; + + /* ─── Primary & Secondary ─── */ + --color-primary: #0068fa; + --color-primary-dark: #0052cc; + --color-secondary: #6b7280; + + /* ─── Canvas Hierarchy ─── */ + --color-canvas: #ffffff; + --color-canvas-subtle: #f9fafb; + --color-canvas-overlay: rgba(0, 0, 0, 0.5); + + /* ─── Surface Hierarchy ─── */ + --color-surface: #ffffff; + --color-surface-secondary: #f9fafb; + --color-surface-hover: #f3f4f6; + --color-surface-active: #e5e7eb; + + /* ─── Border Tokens ─── */ + --color-border: #e5e7eb; + --color-border-strong: #d1d5db; + --color-border-subtle: #f3f4f6; + + /* ─── Text Tokens ─── */ + --color-text: #111827; + --color-text-secondary: #6b7280; + --color-text-muted: #9ca3af; + --color-text-inverse: #ffffff; + --color-text-on-primary: #ffffff; + + /* ─── Semantic: Success (from Figma Coherence UI Kit) ─── */ + --color-success-50: #edfcf5; + --color-success-100: #d0fae5; + --color-success-200: #a5f3cf; + --color-success-300: #6de8b5; + --color-success-400: #33d597; + --color-success-500: #00bc7d; + --color-success-600: #009966; + --color-success-700: #007a53; + --color-success-800: #006043; + --color-success-900: #004f37; + + /* ─── Semantic: Warning (from Figma Coherence UI Kit) ─── */ + --color-warning-50: #fffbeb; + --color-warning-100: #fef3c6; + --color-warning-200: #fde68a; + --color-warning-300: #fcd34d; + --color-warning-400: #fbbf24; + --color-warning-500: #fe9a00; + --color-warning-600: #e17100; + --color-warning-700: #b45309; + --color-warning-800: #92400e; + --color-warning-900: #78350f; + + /* ─── Semantic: Danger (from Figma Coherence UI Kit) ─── */ + --color-danger-50: #fff5f5; + --color-danger-100: #ffe2e2; + --color-danger-200: #ffc9c9; + --color-danger-300: #ffa3a3; + --color-danger-400: #ff6b6b; + --color-danger-500: #fb2c36; + --color-danger-600: #e7000b; + --color-danger-700: #c10007; + --color-danger-800: #a1000a; + --color-danger-900: #840010; + + /* ─── Semantic: Info / Accent (from Figma Coherence UI Kit) ─── */ + --color-info-50: #f0f8ff; + --color-info-100: #ecf4ff; + --color-info-200: #c7e2ff; + --color-info-300: #93c5ff; + --color-info-400: #52a8ff; + --color-info-500: #009aff; + --color-info-600: #0077cc; + --color-info-700: #005fa3; + --color-info-800: #004a80; + --color-info-900: #003866; + + /* ─── Semantic: Discovery (from Figma Coherence UI Kit) ─── */ + --color-discovery-50: #f5f0ff; + --color-discovery-100: #ede9fe; + --color-discovery-200: #ddd6fe; + --color-discovery-300: #c4b5fd; + --color-discovery-400: #a78bfa; + --color-discovery-500: #8e51ff; + --color-discovery-600: #7f22fe; + --color-discovery-700: #6d28d9; + --color-discovery-800: #5b21b6; + --color-discovery-900: #4c1d95; + + /* ─── Typography ─── */ + --font-family-sans: 'Inter', system-ui, -apple-system, sans-serif; + --font-size-xs: 0.75rem; + --font-size-sm: 0.875rem; + --font-size-base: 1rem; + --font-size-lg: 1.125rem; + --font-size-xl: 1.25rem; + --font-size-2xl: 1.5rem; + --font-size-3xl: 1.875rem; + --font-size-4xl: 2.25rem; + --font-weight-normal: 400; + --font-weight-medium: 500; + --font-weight-semibold: 600; + --font-weight-bold: 700; + --line-height-tight: 1.25; + --line-height-normal: 1.5; + --line-height-relaxed: 1.75; + + /* ─── Spacing ─── */ + --spacing-xs: 0.25rem; + --spacing-sm: 0.5rem; + --spacing-md: 1rem; + --spacing-lg: 1.5rem; + --spacing-xl: 2rem; + --spacing-2xl: 3rem; + --spacing-3xl: 4rem; + + /* ─── Border Radius ─── */ + --radius-sm: 0.25rem; + --radius-md: 0.375rem; + --radius-lg: 0.5rem; + --radius-xl: 0.75rem; + --radius-full: 9999px; + + /* ─── Shadows ─── */ + --shadow-sm: 0 1px 3px 0 rgba(0, 0, 0, 0.05), 0 1px 2px -1px rgba(0, 0, 0, 0.05); + --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -2px rgba(0, 0, 0, 0.05); + --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1); + --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1); +} + +/* ─── Dark Mode ─── */ +.dark { + /* Canvas */ + --color-canvas: #0f172a; + --color-canvas-subtle: #1e293b; + --color-canvas-overlay: rgba(0, 0, 0, 0.7); + + /* Surface */ + --color-surface: #1e293b; + --color-surface-secondary: #334155; + --color-surface-hover: #334155; + --color-surface-active: #475569; + + /* Border */ + --color-border: #334155; + --color-border-strong: #475569; + --color-border-subtle: #1e293b; + + /* Text */ + --color-text: #f1f5f9; + --color-text-secondary: #94a3b8; + --color-text-muted: #64748b; + --color-text-inverse: #0f172a; + --color-text-on-primary: #ffffff; + + /* Brand */ + --color-primary: #3b82f6; + --color-primary-dark: #2563eb; + --color-secondary: #94a3b8; + + /* Semantic */ + --color-success-100: #064e3b; + --color-success-500: #34d399; + --color-success-600: #6ee7b7; + --color-warning-100: #78350f; + --color-warning-500: #fbbf24; + --color-warning-600: #fcd34d; + --color-danger-100: #7f1d1d; + --color-danger-500: #f87171; + --color-danger-600: #fca5a5; + --color-info-100: #1e3a5f; + --color-info-500: #60a5fa; + --color-info-600: #93c5fd; + --color-discovery-100: #3b1d6e; + --color-discovery-500: #a78bfa; + --color-discovery-600: #c4b5fd; + + /* Shadows (darker for dark mode) */ + --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.3); + --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -2px rgba(0, 0, 0, 0.3); + --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.4), 0 4px 6px -4px rgba(0, 0, 0, 0.3); + --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.5), 0 8px 10px -6px rgba(0, 0, 0, 0.4); +} diff --git a/apps/lfx/src/types/express.d.ts b/apps/lfx/src/types/express.d.ts new file mode 100644 index 000000000..8dc793aac --- /dev/null +++ b/apps/lfx/src/types/express.d.ts @@ -0,0 +1,12 @@ +// Copyright The Linux Foundation and each contributor to LFX. +// SPDX-License-Identifier: MIT + +declare global { + namespace Express { + interface Request { + bearerToken?: string; + } + } +} + +export {}; diff --git a/apps/lfx/tsconfig.app.json b/apps/lfx/tsconfig.app.json new file mode 100644 index 000000000..63169e72c --- /dev/null +++ b/apps/lfx/tsconfig.app.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": ["node"] + }, + "files": ["src/main.ts", "src/main.server.ts", "src/server/server.ts"], + "include": ["src/**/*.d.ts", "src/**/*.ts"], + "exclude": ["src/**/*.stories.ts"] +} diff --git a/apps/lfx/tsconfig.json b/apps/lfx/tsconfig.json new file mode 100644 index 000000000..62f45b5e7 --- /dev/null +++ b/apps/lfx/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compileOnSave": false, + "include": ["src/**/*"], + "compilerOptions": { + "outDir": "./dist/out-tsc", + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + "isolatedModules": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "moduleResolution": "bundler", + "importHelpers": true, + "target": "ES2022", + "module": "ES2022", + "paths": { + "@lfx-one/shared": ["../../packages/shared/src"], + "@lfx-one/shared/*": ["../../packages/shared/src/*"] + } + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/package.json b/package.json index cbf3dab7b..a0d649084 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "build:development": "turbo run build:development", "build:production": "turbo run build:production", "build:staging": "turbo run build:staging", - "start": "turbo run start --log-prefix=none", + "start": "turbo run start", "lint": "turbo run lint", "test": "turbo run test", "e2e": "turbo run e2e", @@ -21,6 +21,7 @@ "restart:prod": "pm2 restart lfx-one", "reload:prod": "pm2 reload lfx-one", "logs:prod": "pm2 logs lfx-one", + "storybook": "turbo run storybook --filter=lfx --log-prefix=none", "format": "prettier --write \"**/*.{ts,tsx,js,jsx,html,css,scss,md,mdx,json}\"", "format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,html,css,scss,md,mdx,json}\"", "lint:check": "turbo run lint:check", @@ -41,6 +42,8 @@ "husky": "^9.1.7", "lint-staged": "^16.2.7", "prettier": "^3.7.4", + "prettier-plugin-organize-imports": "^4.2.0", + "prettier-plugin-tailwindcss": "^0.6.14", "tslib": "^2.8.1", "turbo": "^2.6.3", "typescript": "5.8.3" diff --git a/turbo.json b/turbo.json index 892f28e1c..963ea56ae 100644 --- a/turbo.json +++ b/turbo.json @@ -63,6 +63,10 @@ "inputs": ["$TURBO_DEFAULT$", ".env*", "e2e/**", "playwright.config.ts"], "outputs": ["playwright-report/**", "test-results/**"], "cache": false + }, + "storybook": { + "cache": false, + "persistent": true } } } diff --git a/yarn.lock b/yarn.lock index 613ac15d3..6547a58ce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,6 +5,20 @@ __metadata: version: 8 cacheKey: 10c0 +"@adobe/css-tools@npm:^4.4.0": + version: 4.4.4 + resolution: "@adobe/css-tools@npm:4.4.4" + checksum: 10c0/8f3e6cfaa5e6286e6f05de01d91d060425be2ebaef490881f5fe6da8bbdb336835c5d373ea337b0c3b0a1af4be048ba18780f0f6021d30809b4545922a7e13d9 + languageName: node + linkType: hard + +"@aduh95/viz.js@npm:3.4.0": + version: 3.4.0 + resolution: "@aduh95/viz.js@npm:3.4.0" + checksum: 10c0/6acb40e881dc0b7ac7a6800a1508e8c420e1f6b09bd42e3289aa2199345729af8aec6ffc52dc72cfe678476fcc341f4a83bc2c3d59cd223232e8495f3a414ab0 + languageName: node + linkType: hard + "@algolia/abtesting@npm:1.1.0": version: 1.1.0 resolution: "@algolia/abtesting@npm:1.1.0" @@ -186,6 +200,16 @@ __metadata: languageName: node linkType: hard +"@angular-devkit/architect@npm:0.2003.20": + version: 0.2003.20 + resolution: "@angular-devkit/architect@npm:0.2003.20" + dependencies: + "@angular-devkit/core": "npm:20.3.20" + rxjs: "npm:7.8.2" + checksum: 10c0/59484525d4174594b7967d455f1383f2722774038aa786f765443f26e9686619995c19eafce5a7ea0b490d6fd81aea0dc3458ac0092f053e4c7bbd70aad6a1c7 + languageName: node + linkType: hard + "@angular-devkit/architect@npm:>= 0.2100.0 < 0.2200.0": version: 0.2101.1 resolution: "@angular-devkit/architect@npm:0.2101.1" @@ -198,6 +222,118 @@ __metadata: languageName: node linkType: hard +"@angular-devkit/build-angular@npm:^20.3.13": + version: 20.3.20 + resolution: "@angular-devkit/build-angular@npm:20.3.20" + dependencies: + "@ampproject/remapping": "npm:2.3.0" + "@angular-devkit/architect": "npm:0.2003.20" + "@angular-devkit/build-webpack": "npm:0.2003.20" + "@angular-devkit/core": "npm:20.3.20" + "@angular/build": "npm:20.3.20" + "@babel/core": "npm:7.28.3" + "@babel/generator": "npm:7.28.3" + "@babel/helper-annotate-as-pure": "npm:7.27.3" + "@babel/helper-split-export-declaration": "npm:7.24.7" + "@babel/plugin-transform-async-generator-functions": "npm:7.28.0" + "@babel/plugin-transform-async-to-generator": "npm:7.27.1" + "@babel/plugin-transform-runtime": "npm:7.28.3" + "@babel/preset-env": "npm:7.28.3" + "@babel/runtime": "npm:7.28.3" + "@discoveryjs/json-ext": "npm:0.6.3" + "@ngtools/webpack": "npm:20.3.20" + ansi-colors: "npm:4.1.3" + autoprefixer: "npm:10.4.21" + babel-loader: "npm:10.0.0" + browserslist: "npm:^4.21.5" + copy-webpack-plugin: "npm:14.0.0" + css-loader: "npm:7.1.2" + esbuild: "npm:0.25.9" + esbuild-wasm: "npm:0.25.9" + fast-glob: "npm:3.3.3" + http-proxy-middleware: "npm:3.0.5" + istanbul-lib-instrument: "npm:6.0.3" + jsonc-parser: "npm:3.3.1" + karma-source-map-support: "npm:1.4.0" + less: "npm:4.4.0" + less-loader: "npm:12.3.0" + license-webpack-plugin: "npm:4.0.2" + loader-utils: "npm:3.3.1" + mini-css-extract-plugin: "npm:2.9.4" + open: "npm:10.2.0" + ora: "npm:8.2.0" + picomatch: "npm:4.0.3" + piscina: "npm:5.1.3" + postcss: "npm:8.5.6" + postcss-loader: "npm:8.1.1" + resolve-url-loader: "npm:5.0.0" + rxjs: "npm:7.8.2" + sass: "npm:1.90.0" + sass-loader: "npm:16.0.5" + semver: "npm:7.7.2" + source-map-loader: "npm:5.0.0" + source-map-support: "npm:0.5.21" + terser: "npm:5.43.1" + tree-kill: "npm:1.2.2" + tslib: "npm:2.8.1" + webpack: "npm:5.105.0" + webpack-dev-middleware: "npm:7.4.2" + webpack-dev-server: "npm:5.2.2" + webpack-merge: "npm:6.0.1" + webpack-subresource-integrity: "npm:5.1.0" + peerDependencies: + "@angular/compiler-cli": ^20.0.0 + "@angular/core": ^20.0.0 + "@angular/localize": ^20.0.0 + "@angular/platform-browser": ^20.0.0 + "@angular/platform-server": ^20.0.0 + "@angular/service-worker": ^20.0.0 + "@angular/ssr": ^20.3.20 + "@web/test-runner": ^0.20.0 + browser-sync: ^3.0.2 + jest: ^29.5.0 || ^30.2.0 + jest-environment-jsdom: ^29.5.0 || ^30.2.0 + karma: ^6.3.0 + ng-packagr: ^20.0.0 + protractor: ^7.0.0 + tailwindcss: ^2.0.0 || ^3.0.0 || ^4.0.0 + typescript: ">=5.8 <6.0" + dependenciesMeta: + esbuild: + optional: true + peerDependenciesMeta: + "@angular/core": + optional: true + "@angular/localize": + optional: true + "@angular/platform-browser": + optional: true + "@angular/platform-server": + optional: true + "@angular/service-worker": + optional: true + "@angular/ssr": + optional: true + "@web/test-runner": + optional: true + browser-sync: + optional: true + jest: + optional: true + jest-environment-jsdom: + optional: true + karma: + optional: true + ng-packagr: + optional: true + protractor: + optional: true + tailwindcss: + optional: true + checksum: 10c0/87251a8dec3ab3f7954018661fb942dbf1363c20251a060c077950cde8352acad2e970060e04282b279c7172dfe2be2cacca321a99b6309f8c9111cb2ee72681 + languageName: node + linkType: hard + "@angular-devkit/build-angular@npm:^20.3.8": version: 20.3.13 resolution: "@angular-devkit/build-angular@npm:20.3.13" @@ -323,6 +459,19 @@ __metadata: languageName: node linkType: hard +"@angular-devkit/build-webpack@npm:0.2003.20": + version: 0.2003.20 + resolution: "@angular-devkit/build-webpack@npm:0.2003.20" + dependencies: + "@angular-devkit/architect": "npm:0.2003.20" + rxjs: "npm:7.8.2" + peerDependencies: + webpack: ^5.30.0 + webpack-dev-server: ^5.0.2 + checksum: 10c0/73a72016f8c61abdbb9d2f5f82b531c155ee17f22925906d655c72896036ceda2ae5118c22866d3a363051555231cbde152b641b8d924892656efd473fd5ca59 + languageName: node + linkType: hard + "@angular-devkit/core@npm:20.3.13": version: 20.3.13 resolution: "@angular-devkit/core@npm:20.3.13" @@ -342,6 +491,44 @@ __metadata: languageName: node linkType: hard +"@angular-devkit/core@npm:20.3.20": + version: 20.3.20 + resolution: "@angular-devkit/core@npm:20.3.20" + dependencies: + ajv: "npm:8.18.0" + ajv-formats: "npm:3.0.1" + jsonc-parser: "npm:3.3.1" + picomatch: "npm:4.0.3" + rxjs: "npm:7.8.2" + source-map: "npm:0.7.6" + peerDependencies: + chokidar: ^4.0.0 + peerDependenciesMeta: + chokidar: + optional: true + checksum: 10c0/12af987f92fb544e04588165d186e60288ca1b32ea7861baf5555cb1f2da38d0239b73bde3bba4d880208e796272852e47c63cee34a451767dc8f6b454cb336e + languageName: node + linkType: hard + +"@angular-devkit/core@npm:21.1.0": + version: 21.1.0 + resolution: "@angular-devkit/core@npm:21.1.0" + dependencies: + ajv: "npm:8.17.1" + ajv-formats: "npm:3.0.1" + jsonc-parser: "npm:3.3.1" + picomatch: "npm:4.0.3" + rxjs: "npm:7.8.2" + source-map: "npm:0.7.6" + peerDependencies: + chokidar: ^5.0.0 + peerDependenciesMeta: + chokidar: + optional: true + checksum: 10c0/e83820545dd6b80e009582ff2763d8907c0ccb12628b3aa0aa28a6d76ce5b740d08736fc0535a8f5bea1db45a2819fcab2c8524e48f3485bfd0085170048839f + languageName: node + linkType: hard + "@angular-devkit/core@npm:21.1.1, @angular-devkit/core@npm:>= 21.0.0 < 22.0.0": version: 21.1.1 resolution: "@angular-devkit/core@npm:21.1.1" @@ -374,6 +561,19 @@ __metadata: languageName: node linkType: hard +"@angular-devkit/schematics@npm:21.1.0": + version: 21.1.0 + resolution: "@angular-devkit/schematics@npm:21.1.0" + dependencies: + "@angular-devkit/core": "npm:21.1.0" + jsonc-parser: "npm:3.3.1" + magic-string: "npm:0.30.21" + ora: "npm:9.0.0" + rxjs: "npm:7.8.2" + checksum: 10c0/ebfd6dd41f9f0bc45f625da05668a248b8031b1c575ea270e77535c712cdaf43399dcc267a0d15d9d0c181e3870a3284962cb8bf09b53f67dfc4bc02167086c3 + languageName: node + linkType: hard + "@angular-devkit/schematics@npm:>= 21.0.0 < 22.0.0": version: 21.1.1 resolution: "@angular-devkit/schematics@npm:21.1.1" @@ -572,6 +772,86 @@ __metadata: languageName: node linkType: hard +"@angular/build@npm:20.3.20, @angular/build@npm:^20.3.13": + version: 20.3.20 + resolution: "@angular/build@npm:20.3.20" + dependencies: + "@ampproject/remapping": "npm:2.3.0" + "@angular-devkit/architect": "npm:0.2003.20" + "@babel/core": "npm:7.28.3" + "@babel/helper-annotate-as-pure": "npm:7.27.3" + "@babel/helper-split-export-declaration": "npm:7.24.7" + "@inquirer/confirm": "npm:5.1.14" + "@vitejs/plugin-basic-ssl": "npm:2.1.0" + beasties: "npm:0.3.5" + browserslist: "npm:^4.23.0" + esbuild: "npm:0.25.9" + https-proxy-agent: "npm:7.0.6" + istanbul-lib-instrument: "npm:6.0.3" + jsonc-parser: "npm:3.3.1" + listr2: "npm:9.0.1" + lmdb: "npm:3.4.2" + magic-string: "npm:0.30.17" + mrmime: "npm:2.0.1" + parse5-html-rewriting-stream: "npm:8.0.0" + picomatch: "npm:4.0.3" + piscina: "npm:5.1.3" + rollup: "npm:4.59.0" + sass: "npm:1.90.0" + semver: "npm:7.7.2" + source-map-support: "npm:0.5.21" + tinyglobby: "npm:0.2.14" + vite: "npm:7.1.11" + watchpack: "npm:2.4.4" + peerDependencies: + "@angular/compiler": ^20.0.0 + "@angular/compiler-cli": ^20.0.0 + "@angular/core": ^20.0.0 + "@angular/localize": ^20.0.0 + "@angular/platform-browser": ^20.0.0 + "@angular/platform-server": ^20.0.0 + "@angular/service-worker": ^20.0.0 + "@angular/ssr": ^20.3.20 + karma: ^6.4.0 + less: ^4.2.0 + ng-packagr: ^20.0.0 + postcss: ^8.4.0 + tailwindcss: ^2.0.0 || ^3.0.0 || ^4.0.0 + tslib: ^2.3.0 + typescript: ">=5.8 <6.0" + vitest: ^3.1.1 + dependenciesMeta: + lmdb: + optional: true + peerDependenciesMeta: + "@angular/core": + optional: true + "@angular/localize": + optional: true + "@angular/platform-browser": + optional: true + "@angular/platform-server": + optional: true + "@angular/service-worker": + optional: true + "@angular/ssr": + optional: true + karma: + optional: true + less: + optional: true + ng-packagr: + optional: true + postcss: + optional: true + tailwindcss: + optional: true + vitest: + optional: true + checksum: 10c0/5056b993d7812635c3e52989c5c9f4dfe9cb0b52600f174c0648916c6a0ec9073493c9aed841ab8d945580163230df939e7e53d1e3238c85d5fdfc466653094f + languageName: node + linkType: hard + "@angular/cdk@npm:^20.2.14": version: 20.2.14 resolution: "@angular/cdk@npm:20.2.14" @@ -615,14 +895,14 @@ __metadata: linkType: hard "@angular/common@npm:^20.3.15": - version: 20.3.15 - resolution: "@angular/common@npm:20.3.15" + version: 20.3.18 + resolution: "@angular/common@npm:20.3.18" dependencies: tslib: "npm:^2.3.0" peerDependencies: - "@angular/core": 20.3.15 + "@angular/core": 20.3.18 rxjs: ^6.5.3 || ^7.4.0 - checksum: 10c0/d8582bda3db80a11735f173197bd1ae1054cce973112eac245bff92bec09b15ea7ba845a83060029027aa25e95ad4fce36a1fbd5208e86775905c80d1875019d + checksum: 10c0/8b6068815b7e5c7e1fc0fa953dc330e8645ae803943f279a5bd960e3b42aa9cbc812db776f06a854709ca5b48298a3d1efb62b2c8f2dee7b1f4cd61ca30fe9f7 languageName: node linkType: hard @@ -661,12 +941,12 @@ __metadata: linkType: hard "@angular/core@npm:^20.3.15": - version: 20.3.15 - resolution: "@angular/core@npm:20.3.15" + version: 20.3.18 + resolution: "@angular/core@npm:20.3.18" dependencies: tslib: "npm:^2.3.0" peerDependencies: - "@angular/compiler": 20.3.15 + "@angular/compiler": 20.3.18 rxjs: ^6.5.3 || ^7.4.0 zone.js: ~0.15.0 peerDependenciesMeta: @@ -674,21 +954,21 @@ __metadata: optional: true zone.js: optional: true - checksum: 10c0/fdf5e49cb5c5336f1b3d147f03e653b08fb670cf1a08777c860be3884ff0a2effad0c9e6e1323c3bf7c8239eb2a677c41846ce4c9c5653d80dec8be780165797 + checksum: 10c0/255451ba833324734f8e77f0ffc977f17dd02b82ee97efeb081b0185f493d76e2d53dd9d20606e1bfdc878926a2601b854c8304ba92ae32ea1c9cf265790a8ad languageName: node linkType: hard "@angular/forms@npm:^20.3.15": - version: 20.3.15 - resolution: "@angular/forms@npm:20.3.15" + version: 20.3.18 + resolution: "@angular/forms@npm:20.3.18" dependencies: tslib: "npm:^2.3.0" peerDependencies: - "@angular/common": 20.3.15 - "@angular/core": 20.3.15 - "@angular/platform-browser": 20.3.15 + "@angular/common": 20.3.18 + "@angular/core": 20.3.18 + "@angular/platform-browser": 20.3.18 rxjs: ^6.5.3 || ^7.4.0 - checksum: 10c0/d2f09cfc49c46b2d33d5798784ea6f7883e2cbbbf0708f38c98be30efcd4870ea3c2f95ca8573a13204e2a7363c701b17a66dac55b142b2771b4f694fc84ea85 + checksum: 10c0/ad8ef4847dfd6b359238b76331bbd7e8166721b38110b818584827e8376175c0fda9aefde4816be06808a6635ec5a8f0e9f953370cbe826c1ac7cd4bedcc7e3e languageName: node linkType: hard @@ -769,6 +1049,13 @@ __metadata: languageName: node linkType: hard +"@arr/every@npm:^1.0.0": + version: 1.0.1 + resolution: "@arr/every@npm:1.0.1" + checksum: 10c0/f9769bc97eca37d1c0dedfda4c17506c0e1269d95c15a7478a49c4d84d43512a3f350b71c95e045cf4113d3398ebd6d298f2eea09196a1ed61c311bc4e6964e7 + languageName: node + linkType: hard + "@aws-crypto/crc32@npm:5.2.0": version: 5.2.0 resolution: "@aws-crypto/crc32@npm:5.2.0" @@ -1681,6 +1968,17 @@ __metadata: languageName: node linkType: hard +"@babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.28.6, @babel/code-frame@npm:^7.29.0": + version: 7.29.0 + resolution: "@babel/code-frame@npm:7.29.0" + dependencies: + "@babel/helper-validator-identifier": "npm:^7.28.5" + js-tokens: "npm:^4.0.0" + picocolors: "npm:^1.1.1" + checksum: 10c0/d34cc504e7765dfb576a663d97067afb614525806b5cad1a5cc1a7183b916fec8ff57fa233585e3926fd5a9e6b31aae6df91aa81ae9775fb7a28f658d3346f0d + languageName: node + linkType: hard + "@babel/compat-data@npm:^7.27.2, @babel/compat-data@npm:^7.27.7": version: 7.28.0 resolution: "@babel/compat-data@npm:7.28.0" @@ -1695,6 +1993,13 @@ __metadata: languageName: node linkType: hard +"@babel/compat-data@npm:^7.28.6": + version: 7.29.0 + resolution: "@babel/compat-data@npm:7.29.0" + checksum: 10c0/08f348554989d23aa801bf1405aa34b15e841c0d52d79da7e524285c77a5f9d298e70e11d91cc578d8e2c9542efc586d50c5f5cf8e1915b254a9dcf786913a94 + languageName: node + linkType: hard + "@babel/core@npm:7.28.3": version: 7.28.3 resolution: "@babel/core@npm:7.28.3" @@ -1718,11 +2023,34 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.23.9": - version: 7.28.0 - resolution: "@babel/core@npm:7.28.0" +"@babel/core@npm:7.28.6": + version: 7.28.6 + resolution: "@babel/core@npm:7.28.6" dependencies: - "@ampproject/remapping": "npm:^2.2.0" + "@babel/code-frame": "npm:^7.28.6" + "@babel/generator": "npm:^7.28.6" + "@babel/helper-compilation-targets": "npm:^7.28.6" + "@babel/helper-module-transforms": "npm:^7.28.6" + "@babel/helpers": "npm:^7.28.6" + "@babel/parser": "npm:^7.28.6" + "@babel/template": "npm:^7.28.6" + "@babel/traverse": "npm:^7.28.6" + "@babel/types": "npm:^7.28.6" + "@jridgewell/remapping": "npm:^2.3.5" + convert-source-map: "npm:^2.0.0" + debug: "npm:^4.1.0" + gensync: "npm:^1.0.0-beta.2" + json5: "npm:^2.2.3" + semver: "npm:^6.3.1" + checksum: 10c0/716b88b1ab057aa53ffa40f2b2fb7e4ab7a35cd6a065fa60e55ca13d2a666672592329f7ea9269aec17e90cc7ce29f42eda566d07859bfd998329a9f283faadb + languageName: node + linkType: hard + +"@babel/core@npm:^7.23.9": + version: 7.28.0 + resolution: "@babel/core@npm:7.28.0" + dependencies: + "@ampproject/remapping": "npm:^2.2.0" "@babel/code-frame": "npm:^7.27.1" "@babel/generator": "npm:^7.28.0" "@babel/helper-compilation-targets": "npm:^7.27.2" @@ -1780,6 +2108,19 @@ __metadata: languageName: node linkType: hard +"@babel/generator@npm:^7.28.6, @babel/generator@npm:^7.29.0": + version: 7.29.1 + resolution: "@babel/generator@npm:7.29.1" + dependencies: + "@babel/parser": "npm:^7.29.0" + "@babel/types": "npm:^7.29.0" + "@jridgewell/gen-mapping": "npm:^0.3.12" + "@jridgewell/trace-mapping": "npm:^0.3.28" + jsesc: "npm:^3.0.2" + checksum: 10c0/349086e6876258ef3fb2823030fee0f6c0eb9c3ebe35fc572e16997f8c030d765f636ddc6299edae63e760ea6658f8ee9a2edfa6d6b24c9a80c917916b973551 + languageName: node + linkType: hard + "@babel/helper-annotate-as-pure@npm:7.27.3, @babel/helper-annotate-as-pure@npm:^7.27.1, @babel/helper-annotate-as-pure@npm:^7.27.3": version: 7.27.3 resolution: "@babel/helper-annotate-as-pure@npm:7.27.3" @@ -1802,6 +2143,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-compilation-targets@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/helper-compilation-targets@npm:7.28.6" + dependencies: + "@babel/compat-data": "npm:^7.28.6" + "@babel/helper-validator-option": "npm:^7.27.1" + browserslist: "npm:^4.24.0" + lru-cache: "npm:^5.1.1" + semver: "npm:^6.3.1" + checksum: 10c0/3fcdf3b1b857a1578e99d20508859dbd3f22f3c87b8a0f3dc540627b4be539bae7f6e61e49d931542fe5b557545347272bbdacd7f58a5c77025a18b745593a50 + languageName: node + linkType: hard + "@babel/helper-create-class-features-plugin@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-create-class-features-plugin@npm:7.27.1" @@ -1836,6 +2190,23 @@ __metadata: languageName: node linkType: hard +"@babel/helper-create-class-features-plugin@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/helper-create-class-features-plugin@npm:7.28.6" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.27.3" + "@babel/helper-member-expression-to-functions": "npm:^7.28.5" + "@babel/helper-optimise-call-expression": "npm:^7.27.1" + "@babel/helper-replace-supers": "npm:^7.28.6" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" + "@babel/traverse": "npm:^7.28.6" + semver: "npm:^6.3.1" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/0b62b46717891f4366006b88c9b7f277980d4f578c4c3789b7a4f5a2e09e121de4cda9a414ab403986745cd3ad1af3fe2d948c9f78ab80d4dc085afc9602af50 + languageName: node + linkType: hard + "@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-create-regexp-features-plugin@npm:7.27.1" @@ -1849,6 +2220,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-create-regexp-features-plugin@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/helper-create-regexp-features-plugin@npm:7.28.5" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.27.3" + regexpu-core: "npm:^6.3.1" + semver: "npm:^6.3.1" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/7af3d604cadecdb2b0d2cedd696507f02a53a58be0523281c2d6766211443b55161dde1e6c0d96ab16ddfd82a2607a2f792390caa24797e9733631f8aa86859f + languageName: node + linkType: hard + "@babel/helper-define-polyfill-provider@npm:^0.6.5": version: 0.6.5 resolution: "@babel/helper-define-polyfill-provider@npm:0.6.5" @@ -1901,6 +2285,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-imports@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/helper-module-imports@npm:7.28.6" + dependencies: + "@babel/traverse": "npm:^7.28.6" + "@babel/types": "npm:^7.28.6" + checksum: 10c0/b49d8d8f204d9dbfd5ac70c54e533e5269afb3cea966a9d976722b13e9922cc773a653405f53c89acb247d5aebdae4681d631a3ae3df77ec046b58da76eda2ac + languageName: node + linkType: hard + "@babel/helper-module-transforms@npm:^7.27.1, @babel/helper-module-transforms@npm:^7.27.3": version: 7.27.3 resolution: "@babel/helper-module-transforms@npm:7.27.3" @@ -1927,6 +2321,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-transforms@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/helper-module-transforms@npm:7.28.6" + dependencies: + "@babel/helper-module-imports": "npm:^7.28.6" + "@babel/helper-validator-identifier": "npm:^7.28.5" + "@babel/traverse": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/6f03e14fc30b287ce0b839474b5f271e72837d0cafe6b172d759184d998fbee3903a035e81e07c2c596449e504f453463d58baa65b6f40a37ded5bec74620b2b + languageName: node + linkType: hard + "@babel/helper-optimise-call-expression@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-optimise-call-expression@npm:7.27.1" @@ -1943,6 +2350,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-plugin-utils@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/helper-plugin-utils@npm:7.28.6" + checksum: 10c0/3f5f8acc152fdbb69a84b8624145ff4f9b9f6e776cb989f9f968f8606eb7185c5c3cfcf3ba08534e37e1e0e1c118ac67080610333f56baa4f7376c99b5f1143d + languageName: node + linkType: hard + "@babel/helper-remap-async-to-generator@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-remap-async-to-generator@npm:7.27.1" @@ -1969,6 +2383,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-replace-supers@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/helper-replace-supers@npm:7.28.6" + dependencies: + "@babel/helper-member-expression-to-functions": "npm:^7.28.5" + "@babel/helper-optimise-call-expression": "npm:^7.27.1" + "@babel/traverse": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/04663c6389551b99b8c3e7ba4e2638b8ca2a156418c26771516124c53083aa8e74b6a45abe5dd46360af79709a0e9c6b72c076d0eab9efecdd5aaf836e79d8d5 + languageName: node + linkType: hard + "@babel/helper-skip-transparent-expression-wrappers@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.27.1" @@ -2047,6 +2474,16 @@ __metadata: languageName: node linkType: hard +"@babel/helpers@npm:^7.28.6": + version: 7.29.2 + resolution: "@babel/helpers@npm:7.29.2" + dependencies: + "@babel/template": "npm:^7.28.6" + "@babel/types": "npm:^7.29.0" + checksum: 10c0/dab0e65b9318b2502a62c58bc0913572318595eec0482c31f0ad416b72636e6698a1d7c57cd2791d4528eb8c548bca88d338dc4d2a55a108dc1f6702f9bc5512 + languageName: node + linkType: hard + "@babel/parser@npm:^7.23.9, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.0": version: 7.28.0 resolution: "@babel/parser@npm:7.28.0" @@ -2069,7 +2506,18 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.27.1": +"@babel/parser@npm:^7.28.6, @babel/parser@npm:^7.29.0": + version: 7.29.2 + resolution: "@babel/parser@npm:7.29.2" + dependencies: + "@babel/types": "npm:^7.29.0" + bin: + parser: ./bin/babel-parser.js + checksum: 10c0/e5a4e69e3ac7acdde995f37cf299a68458cfe7009dff66bd0962fd04920bef287201169006af365af479c08ff216bfefbb595e331f87f6ae7283858aebbc3317 + languageName: node + linkType: hard + +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.27.1, @babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.28.5": version: 7.28.5 resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.28.5" dependencies: @@ -2128,6 +2576,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/traverse": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/f1a9194e8d1742081def7af748e9249eb5082c25d0ced292720a1f054895f99041c764a05f45af669a2c8898aeb79266058aedb0d3e1038963ad49be8288918a + languageName: node + linkType: hard + "@babel/plugin-proposal-private-property-in-object@npm:7.21.0-placeholder-for-preset-env.2": version: 7.21.0-placeholder-for-preset-env.2 resolution: "@babel/plugin-proposal-private-property-in-object@npm:7.21.0-placeholder-for-preset-env.2" @@ -2148,6 +2608,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-import-assertions@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-syntax-import-assertions@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/f3b8bdccb9b4d3e3b9226684ca518e055399d05579da97dfe0160a38d65198cfe7dce809e73179d6463a863a040f980de32425a876d88efe4eda933d0d95982c + languageName: node + linkType: hard + "@babel/plugin-syntax-import-attributes@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-syntax-import-attributes@npm:7.27.1" @@ -2159,6 +2630,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-import-attributes@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-syntax-import-attributes@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/1be160e2c426faa74e5be2e30e39e8d0d8c543063bd5d06cd804f8751b8fbcb82ce824ca7f9ce4b09c003693f6c06a11ce503b7e34d85e1a259631e4c3f72ad2 + languageName: node + linkType: hard + "@babel/plugin-syntax-unicode-sets-regex@npm:^7.18.6": version: 7.18.6 resolution: "@babel/plugin-syntax-unicode-sets-regex@npm:7.18.6" @@ -2195,6 +2677,19 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-async-generator-functions@npm:^7.28.6": + version: 7.29.0 + resolution: "@babel/plugin-transform-async-generator-functions@npm:7.29.0" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-remap-async-to-generator": "npm:^7.27.1" + "@babel/traverse": "npm:^7.29.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/4080fc5e7dad7761bfebbb4fbe06bdfeb3a8bf0c027bcb4373e59e6b3dc7c5002eca7cbb1afba801d6439df8f92f7bcb3fb862e8fbbe43a9e59bb5653dcc0568 + languageName: node + linkType: hard + "@babel/plugin-transform-async-to-generator@npm:7.27.1, @babel/plugin-transform-async-to-generator@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-async-to-generator@npm:7.27.1" @@ -2208,6 +2703,19 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-async-to-generator@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-async-to-generator@npm:7.28.6" + dependencies: + "@babel/helper-module-imports": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-remap-async-to-generator": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/2eb0826248587df6e50038f36194a138771a7df22581020451c7779edeaf9ef39bf47c5b7a20ae2645af6416e8c896feeca273317329652e84abd79a4ab920ad + languageName: node + linkType: hard + "@babel/plugin-transform-block-scoped-functions@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.27.1" @@ -2230,6 +2738,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-block-scoping@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-block-scoping@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/2e3e09e1f9770b56cef4dcbffddf262508fd03416072f815ac66b2b224a3a12cd285cfec12fc067f1add414e7db5ce6dafb5164a6e0fb1a728e6a97d0c6f6e9d + languageName: node + linkType: hard + "@babel/plugin-transform-class-properties@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-class-properties@npm:7.27.1" @@ -2242,6 +2761,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-class-properties@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-class-properties@npm:7.28.6" + dependencies: + "@babel/helper-create-class-features-plugin": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/c4327fcd730c239d9f173f9b695b57b801729e273b4848aef1f75818069dfd31d985d75175db188d947b9b1bbe5353dae298849042026a5e4fcf07582ff3f9f1 + languageName: node + linkType: hard + "@babel/plugin-transform-class-static-block@npm:^7.28.3": version: 7.28.3 resolution: "@babel/plugin-transform-class-static-block@npm:7.28.3" @@ -2254,6 +2785,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-class-static-block@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-class-static-block@npm:7.28.6" + dependencies: + "@babel/helper-create-class-features-plugin": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.12.0 + checksum: 10c0/dbe9b1fd302ae41b73186e17ac8d8ecf625ebc2416a91f2dc8013977a1bdf21e6ea288a83f084752b412242f3866e789d4fddeb428af323fe35b60e0fae4f98c + languageName: node + linkType: hard + "@babel/plugin-transform-classes@npm:^7.28.3": version: 7.28.4 resolution: "@babel/plugin-transform-classes@npm:7.28.4" @@ -2270,6 +2813,22 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-classes@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-classes@npm:7.28.6" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.27.3" + "@babel/helper-compilation-targets": "npm:^7.28.6" + "@babel/helper-globals": "npm:^7.28.0" + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-replace-supers": "npm:^7.28.6" + "@babel/traverse": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/dc22f1f6eadab17305128fbf9cc5f30e87a51a77dd0a6d5498097994e8a9b9a90ab298c11edf2342acbeaac9edc9c601cad72eedcf4b592cd465a787d7f41490 + languageName: node + linkType: hard + "@babel/plugin-transform-computed-properties@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-computed-properties@npm:7.27.1" @@ -2282,6 +2841,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-computed-properties@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-computed-properties@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/template": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/1e9893503ae6d651125701cc29450e87c0b873c8febebff19da75da9c40cfb7968c52c28bf948244e461110aeb7b3591f2cc199b7406ff74a24c50c7a5729f39 + languageName: node + linkType: hard + "@babel/plugin-transform-destructuring@npm:^7.28.0": version: 7.28.0 resolution: "@babel/plugin-transform-destructuring@npm:7.28.0" @@ -2294,6 +2865,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-destructuring@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/plugin-transform-destructuring@npm:7.28.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/traverse": "npm:^7.28.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/288207f488412b23bb206c7c01ba143714e2506b72a9ec09e993f28366cc8188d121bde714659b3437984a86d2881d9b1b06de3089d5582823ccf2f3b3eaa2c4 + languageName: node + linkType: hard + "@babel/plugin-transform-dotall-regex@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-dotall-regex@npm:7.27.1" @@ -2306,6 +2889,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-dotall-regex@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-dotall-regex@npm:7.28.6" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.28.5" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/e2fb76b7ae99087cf4212013a3ca9dee07048f90f98fd6264855080fb6c3f169be11c9b8c9d8b26cf9a407e4d0a5fa6e103f7cef433a542b75cf7127c99d4f97 + languageName: node + linkType: hard + "@babel/plugin-transform-duplicate-keys@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-duplicate-keys@npm:7.27.1" @@ -2329,6 +2924,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:^7.28.6": + version: 7.29.0 + resolution: "@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:7.29.0" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.28.5" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/6f03d9e5e31a05b28555541be6e283407e08447a36be6ddf8068b3efa970411d832e04b1282e2b894baf89a3864ff7e7f1e36346652a8d983170c6d548555167 + languageName: node + linkType: hard + "@babel/plugin-transform-dynamic-import@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-dynamic-import@npm:7.27.1" @@ -2352,6 +2959,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-explicit-resource-management@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-explicit-resource-management@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/plugin-transform-destructuring": "npm:^7.28.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/e6ea28c26e058fe61ada3e70b0def1992dd5a44f5fc14d8e2c6a3a512fb4d4c6dc96a3e1d0b466d83db32a9101e0b02df94051e48d3140da115b8ea9f8a31f37 + languageName: node + linkType: hard + "@babel/plugin-transform-exponentiation-operator@npm:^7.27.1": version: 7.28.5 resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.28.5" @@ -2363,6 +2982,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-exponentiation-operator@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/4572d955a50dbc9a652a19431b4bb822cb479ee6045f4e6df72659c499c13036da0a2adf650b07ca995f2781e80aa868943bea1e7bff1de3169ec3f0a73a902e + languageName: node + linkType: hard + "@babel/plugin-transform-export-namespace-from@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-export-namespace-from@npm:7.27.1" @@ -2410,6 +3040,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-json-strings@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-json-strings@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/ab1091798c58e6c0bb8a864ee2b727c400924592c6ed69797a26b4c205f850a935de77ad516570be0419c279a3d9f7740c2aa448762eb8364ea77a6a357a9653 + languageName: node + linkType: hard + "@babel/plugin-transform-literals@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-literals@npm:7.27.1" @@ -2432,6 +3073,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-logical-assignment-operators@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/4632a35453d2131f0be466681d0a33e3db44d868ff51ec46cd87e0ebd1e47c6a39b894f7d1c9b06f931addf6efa9d30e60c4cdedeb4f69d426f683e11f8490cf + languageName: node + linkType: hard + "@babel/plugin-transform-member-expression-literals@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-member-expression-literals@npm:7.27.1" @@ -2467,6 +3119,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-modules-commonjs@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-modules-commonjs@npm:7.28.6" + dependencies: + "@babel/helper-module-transforms": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/7c45992797c6150644c8552feff4a016ba7bd6d59ff2b039ed969a9c5b20a6804cd9d21db5045fc8cca8ca7f08262497e354e93f8f2be6a1cdf3fbfa8c31a9b6 + languageName: node + linkType: hard + "@babel/plugin-transform-modules-systemjs@npm:^7.27.1": version: 7.28.5 resolution: "@babel/plugin-transform-modules-systemjs@npm:7.28.5" @@ -2481,6 +3145,20 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-modules-systemjs@npm:^7.28.5": + version: 7.29.0 + resolution: "@babel/plugin-transform-modules-systemjs@npm:7.29.0" + dependencies: + "@babel/helper-module-transforms": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-validator-identifier": "npm:^7.28.5" + "@babel/traverse": "npm:^7.29.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/44ea502f2c990398b7d9adc5b44d9e1810a0a5e86eebc05c92d039458f0b3994fe243efa9353b90f8a648d8a91b79845fb353d8679d7324cc9de0162d732771d + languageName: node + linkType: hard + "@babel/plugin-transform-modules-umd@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-modules-umd@npm:7.27.1" @@ -2527,6 +3205,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/6607f2201d66ccb688f0b1db09475ef995837df19f14705da41f693b669f834c206147a854864ab107913d7b4f4748878b0cd9fe9ca8bfd1bee0c206fc027b49 + languageName: node + linkType: hard + "@babel/plugin-transform-numeric-separator@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-numeric-separator@npm:7.27.1" @@ -2538,6 +3227,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-numeric-separator@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-numeric-separator@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/191097d8d2753cdd16d1acca65a945d1645ab20b65655c2f5b030a9e38967a52e093dcb21ebf391e342222705c6ffe5dea15dafd6257f7b51b77fb64a830b637 + languageName: node + linkType: hard + "@babel/plugin-transform-object-rest-spread@npm:^7.28.0": version: 7.28.4 resolution: "@babel/plugin-transform-object-rest-spread@npm:7.28.4" @@ -2553,6 +3253,21 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-object-rest-spread@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-object-rest-spread@npm:7.28.6" + dependencies: + "@babel/helper-compilation-targets": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/plugin-transform-destructuring": "npm:^7.28.5" + "@babel/plugin-transform-parameters": "npm:^7.27.7" + "@babel/traverse": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/f55334352d4fcde385f2e8a58836687e71ff668c9b6e4c34d52575bf2789cdde92d9d3116edba13647ac0bc3e51fb2a6d1e8fb822dce7e8123334b82600bc4c3 + languageName: node + linkType: hard + "@babel/plugin-transform-object-super@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-object-super@npm:7.27.1" @@ -2576,6 +3291,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-optional-catch-binding@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/36e8face000ee65e478a55febf687ce9be7513ad498c60dfe585851555565e0c28e7cb891b3c59709318539ce46f7697d5f42130eb18f385cd47e47cfa297446 + languageName: node + linkType: hard + "@babel/plugin-transform-optional-chaining@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-optional-chaining@npm:7.27.1" @@ -2588,6 +3314,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-optional-chaining@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-optional-chaining@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/c159cc74115c2266be21791f192dd079e2aeb65c8731157e53b80fcefa41e8e28ad370021d4dfbdb31f25e5afa0322669a8eb2d032cd96e65ac37e020324c763 + languageName: node + linkType: hard + "@babel/plugin-transform-parameters@npm:^7.27.7": version: 7.27.7 resolution: "@babel/plugin-transform-parameters@npm:7.27.7" @@ -2599,6 +3337,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-private-methods@npm:7.28.6, @babel/plugin-transform-private-methods@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-private-methods@npm:7.28.6" + dependencies: + "@babel/helper-create-class-features-plugin": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/fb504e2bfdcf3f734d2a90ab20d61427c58385f57f950d3de6ff4e6d12dd4aa7d552147312d218367e129b7920dccfc3230ba554de861986cda38921bad84067 + languageName: node + linkType: hard + "@babel/plugin-transform-private-methods@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-private-methods@npm:7.27.1" @@ -2624,6 +3374,19 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-private-property-in-object@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-private-property-in-object@npm:7.28.6" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.27.3" + "@babel/helper-create-class-features-plugin": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/0f6bbc6ec3f93b556d3de7d56bf49335255fc4c43488e51a5025d6ee0286183fd3cf950ffcac1bbeed8a45777f860a49996455c8d3b4a04c3b1a5f28e697fe31 + languageName: node + linkType: hard + "@babel/plugin-transform-property-literals@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-property-literals@npm:7.27.1" @@ -2646,6 +3409,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-regenerator@npm:^7.28.6": + version: 7.29.0 + resolution: "@babel/plugin-transform-regenerator@npm:7.29.0" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/86c7db9b97f85ee47c0fae0528802cbc06e5775e61580ee905335c16bb971270086764a3859873d9adcd7d0f913a5b93eb0dc271aec8fb9e93e090e4ac95e29e + languageName: node + linkType: hard + "@babel/plugin-transform-regexp-modifiers@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-regexp-modifiers@npm:7.27.1" @@ -2658,6 +3432,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-regexp-modifiers@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-regexp-modifiers@npm:7.28.6" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.28.5" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/97e36b086800f71694fa406abc00192e3833662f2bdd5f51c018bd0c95eef247c4ae187417c207d03a9c5374342eac0bb65a39112c431a9b23b09b1eda1562e5 + languageName: node + linkType: hard + "@babel/plugin-transform-reserved-words@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-reserved-words@npm:7.27.1" @@ -2708,6 +3494,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-spread@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-spread@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/bcac50e558d6f0c501cbce19ec197af558cef51fe3b3a6eba27276e323e57a5be28109b4264a5425ac12a67bf95d6af9c2a42b05e79c522ce913fb9529259d76 + languageName: node + linkType: hard + "@babel/plugin-transform-sticky-regex@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-sticky-regex@npm:7.27.1" @@ -2764,6 +3562,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-unicode-property-regex@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.28.6" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.28.5" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/b25f8cde643f4f47e0fa4f7b5c552e2dfbb6ad0ce07cf40f7e8ae40daa9855ad855d76d4d6d010153b74e48c8794685955c92ca637c0da152ce5f0fa9e7c90fa + languageName: node + linkType: hard + "@babel/plugin-transform-unicode-regex@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-unicode-regex@npm:7.27.1" @@ -2788,6 +3598,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-unicode-sets-regex@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.28.6" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.28.5" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/c03c8818736b138db73d1f7a96fbfa22d1994639164d743f0f00e6383d3b7b3144d333de960ff4afad0bddd0baaac257295e3316969eba995b1b6a1b4dec933e + languageName: node + linkType: hard + "@babel/preset-env@npm:7.28.3": version: 7.28.3 resolution: "@babel/preset-env@npm:7.28.3" @@ -2868,6 +3690,86 @@ __metadata: languageName: node linkType: hard +"@babel/preset-env@npm:7.28.6": + version: 7.28.6 + resolution: "@babel/preset-env@npm:7.28.6" + dependencies: + "@babel/compat-data": "npm:^7.28.6" + "@babel/helper-compilation-targets": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-validator-option": "npm:^7.27.1" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "npm:^7.28.5" + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "npm:^7.27.1" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.27.1" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.27.1" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.28.6" + "@babel/plugin-proposal-private-property-in-object": "npm:7.21.0-placeholder-for-preset-env.2" + "@babel/plugin-syntax-import-assertions": "npm:^7.28.6" + "@babel/plugin-syntax-import-attributes": "npm:^7.28.6" + "@babel/plugin-syntax-unicode-sets-regex": "npm:^7.18.6" + "@babel/plugin-transform-arrow-functions": "npm:^7.27.1" + "@babel/plugin-transform-async-generator-functions": "npm:^7.28.6" + "@babel/plugin-transform-async-to-generator": "npm:^7.28.6" + "@babel/plugin-transform-block-scoped-functions": "npm:^7.27.1" + "@babel/plugin-transform-block-scoping": "npm:^7.28.6" + "@babel/plugin-transform-class-properties": "npm:^7.28.6" + "@babel/plugin-transform-class-static-block": "npm:^7.28.6" + "@babel/plugin-transform-classes": "npm:^7.28.6" + "@babel/plugin-transform-computed-properties": "npm:^7.28.6" + "@babel/plugin-transform-destructuring": "npm:^7.28.5" + "@babel/plugin-transform-dotall-regex": "npm:^7.28.6" + "@babel/plugin-transform-duplicate-keys": "npm:^7.27.1" + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "npm:^7.28.6" + "@babel/plugin-transform-dynamic-import": "npm:^7.27.1" + "@babel/plugin-transform-explicit-resource-management": "npm:^7.28.6" + "@babel/plugin-transform-exponentiation-operator": "npm:^7.28.6" + "@babel/plugin-transform-export-namespace-from": "npm:^7.27.1" + "@babel/plugin-transform-for-of": "npm:^7.27.1" + "@babel/plugin-transform-function-name": "npm:^7.27.1" + "@babel/plugin-transform-json-strings": "npm:^7.28.6" + "@babel/plugin-transform-literals": "npm:^7.27.1" + "@babel/plugin-transform-logical-assignment-operators": "npm:^7.28.6" + "@babel/plugin-transform-member-expression-literals": "npm:^7.27.1" + "@babel/plugin-transform-modules-amd": "npm:^7.27.1" + "@babel/plugin-transform-modules-commonjs": "npm:^7.28.6" + "@babel/plugin-transform-modules-systemjs": "npm:^7.28.5" + "@babel/plugin-transform-modules-umd": "npm:^7.27.1" + "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.27.1" + "@babel/plugin-transform-new-target": "npm:^7.27.1" + "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.28.6" + "@babel/plugin-transform-numeric-separator": "npm:^7.28.6" + "@babel/plugin-transform-object-rest-spread": "npm:^7.28.6" + "@babel/plugin-transform-object-super": "npm:^7.27.1" + "@babel/plugin-transform-optional-catch-binding": "npm:^7.28.6" + "@babel/plugin-transform-optional-chaining": "npm:^7.28.6" + "@babel/plugin-transform-parameters": "npm:^7.27.7" + "@babel/plugin-transform-private-methods": "npm:^7.28.6" + "@babel/plugin-transform-private-property-in-object": "npm:^7.28.6" + "@babel/plugin-transform-property-literals": "npm:^7.27.1" + "@babel/plugin-transform-regenerator": "npm:^7.28.6" + "@babel/plugin-transform-regexp-modifiers": "npm:^7.28.6" + "@babel/plugin-transform-reserved-words": "npm:^7.27.1" + "@babel/plugin-transform-shorthand-properties": "npm:^7.27.1" + "@babel/plugin-transform-spread": "npm:^7.28.6" + "@babel/plugin-transform-sticky-regex": "npm:^7.27.1" + "@babel/plugin-transform-template-literals": "npm:^7.27.1" + "@babel/plugin-transform-typeof-symbol": "npm:^7.27.1" + "@babel/plugin-transform-unicode-escapes": "npm:^7.27.1" + "@babel/plugin-transform-unicode-property-regex": "npm:^7.28.6" + "@babel/plugin-transform-unicode-regex": "npm:^7.27.1" + "@babel/plugin-transform-unicode-sets-regex": "npm:^7.28.6" + "@babel/preset-modules": "npm:0.1.6-no-external-plugins" + babel-plugin-polyfill-corejs2: "npm:^0.4.14" + babel-plugin-polyfill-corejs3: "npm:^0.13.0" + babel-plugin-polyfill-regenerator: "npm:^0.6.5" + core-js-compat: "npm:^3.43.0" + semver: "npm:^6.3.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/a08f007c5e8c95beb10a4ab8ad8fdbd823c8ace5f24f491f69a10b6cad079825d39cd1bc9dd312680bbd5aa5f95095cce7d01f51e31bae6720039b11e8105ace + languageName: node + linkType: hard + "@babel/preset-modules@npm:0.1.6-no-external-plugins": version: 0.1.6-no-external-plugins resolution: "@babel/preset-modules@npm:0.1.6-no-external-plugins" @@ -2888,6 +3790,13 @@ __metadata: languageName: node linkType: hard +"@babel/runtime@npm:^7.28.4": + version: 7.29.2 + resolution: "@babel/runtime@npm:7.29.2" + checksum: 10c0/30b80a0140d16467792e1bbeb06f655b0dab70407da38dfac7fedae9c859f9ae9d846ef14ad77bd3814c064295fe9b1bc551f1541ea14646ae9f22b71a8bc17a + languageName: node + linkType: hard + "@babel/template@npm:^7.27.1, @babel/template@npm:^7.27.2": version: 7.27.2 resolution: "@babel/template@npm:7.27.2" @@ -2899,6 +3808,17 @@ __metadata: languageName: node linkType: hard +"@babel/template@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/template@npm:7.28.6" + dependencies: + "@babel/code-frame": "npm:^7.28.6" + "@babel/parser": "npm:^7.28.6" + "@babel/types": "npm:^7.28.6" + checksum: 10c0/66d87225ed0bc77f888181ae2d97845021838c619944877f7c4398c6748bcf611f216dfd6be74d39016af502bca876e6ce6873db3c49e4ac354c56d34d57e9f5 + languageName: node + linkType: hard + "@babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.27.3, @babel/traverse@npm:^7.28.0": version: 7.28.0 resolution: "@babel/traverse@npm:7.28.0" @@ -2925,7 +3845,22 @@ __metadata: "@babel/template": "npm:^7.27.2" "@babel/types": "npm:^7.28.5" debug: "npm:^4.3.1" - checksum: 10c0/f6c4a595993ae2b73f2d4cd9c062f2e232174d293edd4abe1d715bd6281da8d99e47c65857e8d0917d9384c65972f4acdebc6749a7c40a8fcc38b3c7fb3e706f + checksum: 10c0/f6c4a595993ae2b73f2d4cd9c062f2e232174d293edd4abe1d715bd6281da8d99e47c65857e8d0917d9384c65972f4acdebc6749a7c40a8fcc38b3c7fb3e706f + languageName: node + linkType: hard + +"@babel/traverse@npm:^7.28.6, @babel/traverse@npm:^7.29.0": + version: 7.29.0 + resolution: "@babel/traverse@npm:7.29.0" + dependencies: + "@babel/code-frame": "npm:^7.29.0" + "@babel/generator": "npm:^7.29.0" + "@babel/helper-globals": "npm:^7.28.0" + "@babel/parser": "npm:^7.29.0" + "@babel/template": "npm:^7.28.6" + "@babel/types": "npm:^7.29.0" + debug: "npm:^4.3.1" + checksum: 10c0/f63ef6e58d02a9fbf3c0e2e5f1c877da3e0bc57f91a19d2223d53e356a76859cbaf51171c9211c71816d94a0e69efa2732fd27ffc0e1bbc84b636e60932333eb languageName: node linkType: hard @@ -2949,6 +3884,16 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.28.6, @babel/types@npm:^7.29.0": + version: 7.29.0 + resolution: "@babel/types@npm:7.29.0" + dependencies: + "@babel/helper-string-parser": "npm:^7.27.1" + "@babel/helper-validator-identifier": "npm:^7.28.5" + checksum: 10c0/23cc3466e83bcbfab8b9bd0edaafdb5d4efdb88b82b3be6728bbade5ba2f0996f84f63b1c5f7a8c0d67efded28300898a5f930b171bb40b311bca2029c4e9b4f + languageName: node + linkType: hard + "@colors/colors@npm:1.6.0, @colors/colors@npm:^1.6.0": version: 1.6.0 resolution: "@colors/colors@npm:1.6.0" @@ -3153,6 +4098,106 @@ __metadata: languageName: node linkType: hard +"@compodoc/compodoc@npm:^1.2.1": + version: 1.2.1 + resolution: "@compodoc/compodoc@npm:1.2.1" + dependencies: + "@angular-devkit/schematics": "npm:21.1.0" + "@babel/core": "npm:7.28.6" + "@babel/plugin-transform-private-methods": "npm:7.28.6" + "@babel/preset-env": "npm:7.28.6" + "@compodoc/live-server": "npm:^1.2.3" + "@compodoc/ngd-transformer": "npm:^2.1.3" + "@polka/send-type": "npm:^0.5.2" + body-parser: "npm:^2.2.2" + bootstrap.native: "npm:^5.1.6" + cheerio: "npm:1.1.2" + chokidar: "npm:^5.0.0" + colors: "npm:1.4.0" + commander: "npm:^14.0.2" + cosmiconfig: "npm:^9.0.0" + decache: "npm:^4.6.2" + es6-shim: "npm:^0.35.8" + fancy-log: "npm:^2.0.0" + fast-glob: "npm:^3.3.3" + fs-extra: "npm:^11.3.3" + glob: "npm:^13.0.0" + handlebars: "npm:^4.7.8" + html-entities: "npm:^2.6.0" + i18next: "npm:25.7.4" + json5: "npm:^2.2.3" + lodash: "npm:^4.17.21" + loglevel: "npm:^1.9.2" + loglevel-plugin-prefix: "npm:^0.8.4" + lunr: "npm:^2.3.9" + marked: "npm:7.0.3" + minimist: "npm:^1.2.8" + neotraverse: "npm:^0.6.18" + opencollective-postinstall: "npm:^2.0.3" + os-name: "npm:4.0.1" + picocolors: "npm:^1.1.1" + polka: "npm:^0.5.2" + prismjs: "npm:^1.30.0" + semver: "npm:^7.7.3" + sirv: "npm:^3.0.2" + svg-pan-zoom: "npm:^3.6.2" + tablesort: "npm:^5.7.0" + ts-morph: "npm:^27.0.2" + uuid: "npm:11.1.0" + vis-network: "npm:^10.0.2" + bin: + compodoc: bin/index-cli.js + checksum: 10c0/b3748b159fa5c7004122e5460b28fb26601a0ebd7e24c9d9bc8d35aba4bcc935a5903eb70c81a79d0ccabcc1e38f828e4e087d0fb46e6c6d0e0e563c38656f0e + languageName: node + linkType: hard + +"@compodoc/live-server@npm:^1.2.3": + version: 1.2.3 + resolution: "@compodoc/live-server@npm:1.2.3" + dependencies: + chokidar: "npm:^3.5.2" + colors: "npm:1.4.0" + connect: "npm:^3.7.0" + cors: "npm:latest" + event-stream: "npm:4.0.1" + faye-websocket: "npm:0.11.x" + http-auth: "npm:4.1.9" + http-auth-connect: "npm:^1.0.5" + morgan: "npm:^1.10.0" + object-assign: "npm:latest" + open: "npm:8.4.0" + proxy-middleware: "npm:latest" + send: "npm:latest" + serve-index: "npm:^1.9.1" + bin: + live-server: live-server.js + checksum: 10c0/8dd2d66d42a8f3e0ba2102cbe3a19114ed789068b848cd5f8a967ea1d14e8f8650300caee00c6ae9f3a637262d0f9f1bcbee67f3ca023e4619a318d0f28f3066 + languageName: node + linkType: hard + +"@compodoc/ngd-core@npm:~2.1.1": + version: 2.1.1 + resolution: "@compodoc/ngd-core@npm:2.1.1" + dependencies: + ansi-colors: "npm:^4.1.3" + fancy-log: "npm:^2.0.0" + typescript: "npm:^5.0.4" + checksum: 10c0/f78f4231e39d96e397bb39614cfbe8dfc6b985eb9b2795cd5188a40f65eb60eb096dc29de61baa6d914fbc86ec7f21b5a2d02e6000b26d82ae3cd682aea79275 + languageName: node + linkType: hard + +"@compodoc/ngd-transformer@npm:^2.1.3": + version: 2.1.3 + resolution: "@compodoc/ngd-transformer@npm:2.1.3" + dependencies: + "@aduh95/viz.js": "npm:3.4.0" + "@compodoc/ngd-core": "npm:~2.1.1" + dot: "npm:^2.0.0-beta.1" + fs-extra: "npm:^11.1.1" + checksum: 10c0/fb7b13860fc022cda284ca0bae55f8c6610621a060c943740838b5fa2f6be7957c99c2750024cf949b2c8f1c5f41bc64cd8e28ab333f985627f5991bcaf5cdcf + languageName: node + linkType: hard + "@dabh/diagnostics@npm:^2.0.8": version: 2.0.8 resolution: "@dabh/diagnostics@npm:2.0.8" @@ -3202,6 +4247,34 @@ __metadata: languageName: node linkType: hard +"@emnapi/core@npm:^1.7.1, @emnapi/core@npm:^1.8.1": + version: 1.9.0 + resolution: "@emnapi/core@npm:1.9.0" + dependencies: + "@emnapi/wasi-threads": "npm:1.2.0" + tslib: "npm:^2.4.0" + checksum: 10c0/defbfa5861aa5ff1346dbc6a19df50d727ae76ae276a31a97b178db8eecae0c5179976878087b43ac2441750e40e6c50e465280383256deb16dd2fb167dd515c + languageName: node + linkType: hard + +"@emnapi/runtime@npm:^1.7.1, @emnapi/runtime@npm:^1.8.1": + version: 1.9.0 + resolution: "@emnapi/runtime@npm:1.9.0" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/f825e53b2d3f9d31fd880e669197d006bb5158c3a52ab25f0546f3d52ac58eb539a4bd1dcc378af6c10d202956fa064b28ab7b572a76de58972c0b8656a692ef + languageName: node + linkType: hard + +"@emnapi/wasi-threads@npm:1.2.0, @emnapi/wasi-threads@npm:^1.1.0": + version: 1.2.0 + resolution: "@emnapi/wasi-threads@npm:1.2.0" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/1e3724b5814b06c14782fda87eee9b9aa68af01576c81ffeaefdf621ddb74386e419d5b3b1027b6a8172397729d95a92f814fc4b8d3c224376428faa07a6a01a + languageName: node + linkType: hard + "@esbuild/aix-ppc64@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/aix-ppc64@npm:0.25.6" @@ -3216,6 +4289,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/aix-ppc64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/aix-ppc64@npm:0.27.4" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/android-arm64@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/android-arm64@npm:0.25.6" @@ -3230,6 +4310,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/android-arm64@npm:0.27.4" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/android-arm@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/android-arm@npm:0.25.6" @@ -3244,6 +4331,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/android-arm@npm:0.27.4" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@esbuild/android-x64@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/android-x64@npm:0.25.6" @@ -3258,6 +4352,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/android-x64@npm:0.27.4" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + "@esbuild/darwin-arm64@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/darwin-arm64@npm:0.25.6" @@ -3272,6 +4373,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/darwin-arm64@npm:0.27.4" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/darwin-x64@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/darwin-x64@npm:0.25.6" @@ -3286,6 +4394,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/darwin-x64@npm:0.27.4" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@esbuild/freebsd-arm64@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/freebsd-arm64@npm:0.25.6" @@ -3300,6 +4415,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/freebsd-arm64@npm:0.27.4" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/freebsd-x64@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/freebsd-x64@npm:0.25.6" @@ -3314,6 +4436,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/freebsd-x64@npm:0.27.4" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/linux-arm64@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/linux-arm64@npm:0.25.6" @@ -3328,6 +4457,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-arm64@npm:0.27.4" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/linux-arm@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/linux-arm@npm:0.25.6" @@ -3342,6 +4478,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-arm@npm:0.27.4" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@esbuild/linux-ia32@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/linux-ia32@npm:0.25.6" @@ -3356,6 +4499,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ia32@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-ia32@npm:0.27.4" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/linux-loong64@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/linux-loong64@npm:0.25.6" @@ -3370,6 +4520,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-loong64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-loong64@npm:0.27.4" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + "@esbuild/linux-mips64el@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/linux-mips64el@npm:0.25.6" @@ -3384,6 +4541,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-mips64el@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-mips64el@npm:0.27.4" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + "@esbuild/linux-ppc64@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/linux-ppc64@npm:0.25.6" @@ -3398,6 +4562,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ppc64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-ppc64@npm:0.27.4" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/linux-riscv64@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/linux-riscv64@npm:0.25.6" @@ -3412,6 +4583,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-riscv64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-riscv64@npm:0.27.4" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + "@esbuild/linux-s390x@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/linux-s390x@npm:0.25.6" @@ -3426,6 +4604,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-s390x@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-s390x@npm:0.27.4" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + "@esbuild/linux-x64@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/linux-x64@npm:0.25.6" @@ -3440,6 +4625,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-x64@npm:0.27.4" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + "@esbuild/netbsd-arm64@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/netbsd-arm64@npm:0.25.6" @@ -3454,6 +4646,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/netbsd-arm64@npm:0.27.4" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/netbsd-x64@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/netbsd-x64@npm:0.25.6" @@ -3468,6 +4667,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/netbsd-x64@npm:0.27.4" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/openbsd-arm64@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/openbsd-arm64@npm:0.25.6" @@ -3482,6 +4688,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/openbsd-arm64@npm:0.27.4" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/openbsd-x64@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/openbsd-x64@npm:0.25.6" @@ -3496,6 +4709,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/openbsd-x64@npm:0.27.4" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/openharmony-arm64@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/openharmony-arm64@npm:0.25.6" @@ -3510,6 +4730,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openharmony-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/openharmony-arm64@npm:0.27.4" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/sunos-x64@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/sunos-x64@npm:0.25.6" @@ -3524,6 +4751,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/sunos-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/sunos-x64@npm:0.27.4" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + "@esbuild/win32-arm64@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/win32-arm64@npm:0.25.6" @@ -3538,6 +4772,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/win32-arm64@npm:0.27.4" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/win32-ia32@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/win32-ia32@npm:0.25.6" @@ -3552,6 +4793,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-ia32@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/win32-ia32@npm:0.27.4" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/win32-x64@npm:0.25.6": version: 0.25.6 resolution: "@esbuild/win32-x64@npm:0.25.6" @@ -3566,6 +4814,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/win32-x64@npm:0.27.4" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@eslint-community/eslint-utils@npm:^4.7.0": version: 4.7.0 resolution: "@eslint-community/eslint-utils@npm:4.7.0" @@ -4147,6 +5402,16 @@ __metadata: languageName: node linkType: hard +"@jridgewell/remapping@npm:^2.3.5": + version: 2.3.5 + resolution: "@jridgewell/remapping@npm:2.3.5" + dependencies: + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.24" + checksum: 10c0/3de494219ffeb2c5c38711d0d7bb128097edf91893090a2dbc8ee0b55d092bb7347b1fd0f478486c5eab010e855c73927b1666f2107516d472d24a73017d1194 + languageName: node + linkType: hard + "@jridgewell/resolve-uri@npm:^3.1.0": version: 3.1.2 resolution: "@jridgewell/resolve-uri@npm:3.1.2" @@ -4335,6 +5600,18 @@ __metadata: languageName: node linkType: hard +"@mdx-js/react@npm:^3.0.0": + version: 3.1.1 + resolution: "@mdx-js/react@npm:3.1.1" + dependencies: + "@types/mdx": "npm:^2.0.0" + peerDependencies: + "@types/react": ">=16" + react: ">=16" + checksum: 10c0/34ca98bc2a0f969894ea144dc5c8a5294690505458cd24965cd9be854d779c193ad9192bf9143c4c18438fafd1902e100d99067e045c69319288562d497558c6 + languageName: node + linkType: hard + "@modelcontextprotocol/sdk@npm:1.24.0": version: 1.24.0 resolution: "@modelcontextprotocol/sdk@npm:1.24.0" @@ -4586,6 +5863,17 @@ __metadata: languageName: node linkType: hard +"@napi-rs/wasm-runtime@npm:^1.1.1": + version: 1.1.1 + resolution: "@napi-rs/wasm-runtime@npm:1.1.1" + dependencies: + "@emnapi/core": "npm:^1.7.1" + "@emnapi/runtime": "npm:^1.7.1" + "@tybys/wasm-util": "npm:^0.10.1" + checksum: 10c0/04d57b67e80736e41fe44674a011878db0a8ad893f4d44abb9d3608debb7c174224cba2796ed5b0c1d367368159f3ca6be45f1c59222f70e32ddc880f803d447 + languageName: node + linkType: hard + "@ngtools/webpack@npm:20.3.13": version: 20.3.13 resolution: "@ngtools/webpack@npm:20.3.13" @@ -4597,6 +5885,17 @@ __metadata: languageName: node linkType: hard +"@ngtools/webpack@npm:20.3.20": + version: 20.3.20 + resolution: "@ngtools/webpack@npm:20.3.20" + peerDependencies: + "@angular/compiler-cli": ^20.0.0 + typescript: ">=5.8 <6.0" + webpack: ^5.54.0 + checksum: 10c0/fee01867a736281824ee95cec62af4cbfd592d30834f57cc4dfaef570d6c547a1abe9a390fdc7819b6e2a0de9a41fb76b364c09889fba2951fba084549fccb2f + languageName: node + linkType: hard + "@nodelib/fs.scandir@npm:2.1.5": version: 2.1.5 resolution: "@nodelib/fs.scandir@npm:2.1.5" @@ -4988,6 +6287,27 @@ __metadata: languageName: node linkType: hard +"@polka/send-type@npm:^0.5.2": + version: 0.5.2 + resolution: "@polka/send-type@npm:0.5.2" + checksum: 10c0/5481c55ff5706205343eb3b7f8f7962c36aa4c96dfab67399367f4f76f8d5d0c25b89b28bb10cd41a5463f30f35710ba6935f057f4b59a38d1cb92aecae1f8f8 + languageName: node + linkType: hard + +"@polka/url@npm:^0.5.0": + version: 0.5.0 + resolution: "@polka/url@npm:0.5.0" + checksum: 10c0/76324126e1608f4cdc5c6b11b618ca67612c37d45401f3fbcce4967294093761b7568cc6ae74ade8afbe744547e72e9d50bc38f690ddea0904a1d66a6b8a0093 + languageName: node + linkType: hard + +"@polka/url@npm:^1.0.0-next.24": + version: 1.0.0-next.29 + resolution: "@polka/url@npm:1.0.0-next.29" + checksum: 10c0/0d58e081844095cb029d3c19a659bfefd09d5d51a2f791bc61eba7ea826f13d6ee204a8a448c2f5a855c17df07b37517373ff916dd05801063c0568ae9937684 + languageName: node + linkType: hard + "@primeuix/styled@npm:^0.7.3, @primeuix/styled@npm:^0.7.4": version: 0.7.4 resolution: "@primeuix/styled@npm:0.7.4" @@ -5036,6 +6356,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-android-arm-eabi@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.59.0" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@rollup/rollup-android-arm64@npm:4.52.3": version: 4.52.3 resolution: "@rollup/rollup-android-arm64@npm:4.52.3" @@ -5050,6 +6377,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-android-arm64@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-android-arm64@npm:4.59.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-darwin-arm64@npm:4.52.3": version: 4.52.3 resolution: "@rollup/rollup-darwin-arm64@npm:4.52.3" @@ -5064,6 +6398,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-darwin-arm64@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-darwin-arm64@npm:4.59.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-darwin-x64@npm:4.52.3": version: 4.52.3 resolution: "@rollup/rollup-darwin-x64@npm:4.52.3" @@ -5078,6 +6419,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-darwin-x64@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-darwin-x64@npm:4.59.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@rollup/rollup-freebsd-arm64@npm:4.52.3": version: 4.52.3 resolution: "@rollup/rollup-freebsd-arm64@npm:4.52.3" @@ -5092,6 +6440,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-freebsd-arm64@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.59.0" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-freebsd-x64@npm:4.52.3": version: 4.52.3 resolution: "@rollup/rollup-freebsd-x64@npm:4.52.3" @@ -5106,6 +6461,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-freebsd-x64@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-freebsd-x64@npm:4.59.0" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@rollup/rollup-linux-arm-gnueabihf@npm:4.52.3": version: 4.52.3 resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.52.3" @@ -5120,6 +6482,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm-gnueabihf@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.59.0" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-arm-musleabihf@npm:4.52.3": version: 4.52.3 resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.52.3" @@ -5134,6 +6503,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm-musleabihf@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.59.0" + conditions: os=linux & cpu=arm & libc=musl + languageName: node + linkType: hard + "@rollup/rollup-linux-arm64-gnu@npm:4.52.3": version: 4.52.3 resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.52.3" @@ -5148,6 +6524,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm64-gnu@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.59.0" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-arm64-musl@npm:4.52.3": version: 4.52.3 resolution: "@rollup/rollup-linux-arm64-musl@npm:4.52.3" @@ -5162,6 +6545,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm64-musl@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.59.0" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + "@rollup/rollup-linux-loong64-gnu@npm:4.52.3": version: 4.52.3 resolution: "@rollup/rollup-linux-loong64-gnu@npm:4.52.3" @@ -5176,6 +6566,20 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-loong64-gnu@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-loong64-gnu@npm:4.59.0" + conditions: os=linux & cpu=loong64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-loong64-musl@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-loong64-musl@npm:4.59.0" + conditions: os=linux & cpu=loong64 & libc=musl + languageName: node + linkType: hard + "@rollup/rollup-linux-ppc64-gnu@npm:4.52.3": version: 4.52.3 resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.52.3" @@ -5190,6 +6594,20 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-ppc64-gnu@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.59.0" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-ppc64-musl@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-ppc64-musl@npm:4.59.0" + conditions: os=linux & cpu=ppc64 & libc=musl + languageName: node + linkType: hard + "@rollup/rollup-linux-riscv64-gnu@npm:4.52.3": version: 4.52.3 resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.52.3" @@ -5204,6 +6622,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-riscv64-gnu@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.59.0" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-riscv64-musl@npm:4.52.3": version: 4.52.3 resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.52.3" @@ -5218,6 +6643,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-riscv64-musl@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.59.0" + conditions: os=linux & cpu=riscv64 & libc=musl + languageName: node + linkType: hard + "@rollup/rollup-linux-s390x-gnu@npm:4.52.3": version: 4.52.3 resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.52.3" @@ -5225,9 +6657,16 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-linux-s390x-gnu@npm:4.53.3": - version: 4.53.3 - resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.53.3" +"@rollup/rollup-linux-s390x-gnu@npm:4.53.3": + version: 4.53.3 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.53.3" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-s390x-gnu@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.59.0" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard @@ -5246,6 +6685,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-x64-gnu@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.59.0" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-x64-musl@npm:4.52.3": version: 4.52.3 resolution: "@rollup/rollup-linux-x64-musl@npm:4.52.3" @@ -5260,6 +6706,20 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-x64-musl@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.59.0" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-openbsd-x64@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-openbsd-x64@npm:4.59.0" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + "@rollup/rollup-openharmony-arm64@npm:4.52.3": version: 4.52.3 resolution: "@rollup/rollup-openharmony-arm64@npm:4.52.3" @@ -5274,6 +6734,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-openharmony-arm64@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-openharmony-arm64@npm:4.59.0" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-win32-arm64-msvc@npm:4.52.3": version: 4.52.3 resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.52.3" @@ -5288,6 +6755,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-arm64-msvc@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.59.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-win32-ia32-msvc@npm:4.52.3": version: 4.52.3 resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.52.3" @@ -5302,6 +6776,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-ia32-msvc@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.59.0" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@rollup/rollup-win32-x64-gnu@npm:4.52.3": version: 4.52.3 resolution: "@rollup/rollup-win32-x64-gnu@npm:4.52.3" @@ -5316,6 +6797,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-x64-gnu@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-win32-x64-gnu@npm:4.59.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@rollup/rollup-win32-x64-msvc@npm:4.52.3": version: 4.52.3 resolution: "@rollup/rollup-win32-x64-msvc@npm:4.52.3" @@ -5330,6 +6818,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-x64-msvc@npm:4.59.0": + version: 4.59.0 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.59.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@schematics/angular@npm:20.3.13": version: 20.3.13 resolution: "@schematics/angular@npm:20.3.13" @@ -6047,6 +7542,151 @@ __metadata: languageName: node linkType: hard +"@storybook/addon-docs@npm:^10.3.0": + version: 10.3.0 + resolution: "@storybook/addon-docs@npm:10.3.0" + dependencies: + "@mdx-js/react": "npm:^3.0.0" + "@storybook/csf-plugin": "npm:10.3.0" + "@storybook/icons": "npm:^2.0.1" + "@storybook/react-dom-shim": "npm:10.3.0" + react: "npm:^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + react-dom: "npm:^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + ts-dedent: "npm:^2.0.0" + peerDependencies: + storybook: ^10.3.0 + checksum: 10c0/f70ce1bb5bd31ace42386c8000b5e1b0a9b509c574b9b1dca4f1e55ebaa081b93db45a5661e3dfe0133581abfcb70a7acbd4bd45ee0f846cbc01f631ced54ffa + languageName: node + linkType: hard + +"@storybook/angular@npm:^10.3.0": + version: 10.3.0 + resolution: "@storybook/angular@npm:10.3.0" + dependencies: + "@storybook/builder-webpack5": "npm:10.3.0" + "@storybook/global": "npm:^5.0.0" + telejson: "npm:8.0.0" + ts-dedent: "npm:^2.0.0" + tsconfig-paths-webpack-plugin: "npm:^4.0.1" + webpack: "npm:5" + peerDependencies: + "@angular-devkit/architect": ">=0.1800.0 < 0.2200.0" + "@angular-devkit/build-angular": ">=18.0.0 < 22.0.0" + "@angular-devkit/core": ">=18.0.0 < 22.0.0" + "@angular/animations": ">=18.0.0 < 22.0.0" + "@angular/cli": ">=18.0.0 < 22.0.0" + "@angular/common": ">=18.0.0 < 22.0.0" + "@angular/compiler": ">=18.0.0 < 22.0.0" + "@angular/compiler-cli": ">=18.0.0 < 22.0.0" + "@angular/core": ">=18.0.0 < 22.0.0" + "@angular/platform-browser": ">=18.0.0 < 22.0.0" + "@angular/platform-browser-dynamic": ">=18.0.0 < 22.0.0" + rxjs: ^6.5.3 || ^7.4.0 + storybook: ^10.3.0 + typescript: ^4.9.0 || ^5.0.0 + zone.js: ">=0.14.0" + peerDependenciesMeta: + "@angular/animations": + optional: true + "@angular/cli": + optional: true + zone.js: + optional: true + checksum: 10c0/603903ff2f3a09cd9bfe9d2f0fba6a0ad548bf4087e595b1092d7a6200d77809660f0147b54bd6486675c0dddd694f003fcdc3067c5702d46ad60ad6ddf00735 + languageName: node + linkType: hard + +"@storybook/builder-webpack5@npm:10.3.0": + version: 10.3.0 + resolution: "@storybook/builder-webpack5@npm:10.3.0" + dependencies: + "@storybook/core-webpack": "npm:10.3.0" + case-sensitive-paths-webpack-plugin: "npm:^2.4.0" + cjs-module-lexer: "npm:^1.2.3" + css-loader: "npm:^7.1.2" + es-module-lexer: "npm:^1.5.0" + fork-ts-checker-webpack-plugin: "npm:^9.1.0" + html-webpack-plugin: "npm:^5.5.0" + magic-string: "npm:^0.30.5" + style-loader: "npm:^4.0.0" + terser-webpack-plugin: "npm:^5.3.14" + ts-dedent: "npm:^2.0.0" + webpack: "npm:5" + webpack-dev-middleware: "npm:^6.1.2" + webpack-hot-middleware: "npm:^2.25.1" + webpack-virtual-modules: "npm:^0.6.0" + peerDependencies: + storybook: ^10.3.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/c8ef1681bb3947d44aa1c40615c208749fbb334e3623513974d9ce8ac84a0b708832e8c209f050c86566a52278d8705870f7671b14afb2a216a4558a7794910a + languageName: node + linkType: hard + +"@storybook/core-webpack@npm:10.3.0": + version: 10.3.0 + resolution: "@storybook/core-webpack@npm:10.3.0" + dependencies: + ts-dedent: "npm:^2.0.0" + peerDependencies: + storybook: ^10.3.0 + checksum: 10c0/6a2b4bb3a70dd4e03b64738da452e68d721b574afec08103a00cffc91afb85c4b404d73516407810abf971140aa4da5a65f1cdd7c0da7adf1dddc271d0de8b7c + languageName: node + linkType: hard + +"@storybook/csf-plugin@npm:10.3.0": + version: 10.3.0 + resolution: "@storybook/csf-plugin@npm:10.3.0" + dependencies: + unplugin: "npm:^2.3.5" + peerDependencies: + esbuild: "*" + rollup: "*" + storybook: ^10.3.0 + vite: "*" + webpack: "*" + peerDependenciesMeta: + esbuild: + optional: true + rollup: + optional: true + vite: + optional: true + webpack: + optional: true + checksum: 10c0/59c1784257d313fb7298a34c079462ba0ad518f82369441e6432da1abdc47ecb16afc40bbb02fd1331183be10914d383ed1f68a6b431ea25019fd50b63453e7f + languageName: node + linkType: hard + +"@storybook/global@npm:^5.0.0": + version: 5.0.0 + resolution: "@storybook/global@npm:5.0.0" + checksum: 10c0/8f1b61dcdd3a89584540896e659af2ecc700bc740c16909a7be24ac19127ea213324de144a141f7caf8affaed017d064fea0618d453afbe027cf60f54b4a6d0b + languageName: node + linkType: hard + +"@storybook/icons@npm:^2.0.1": + version: 2.0.1 + resolution: "@storybook/icons@npm:2.0.1" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + checksum: 10c0/df2bbf1a5b50f12ab1bf78cae6de4dbf7c49df0e3a5f845553b51b20adbe8386a09fd172ea60342379f9284bb528cba2d0e2659cae6eb8d015cf92c8b32f1222 + languageName: node + linkType: hard + +"@storybook/react-dom-shim@npm:10.3.0": + version: 10.3.0 + resolution: "@storybook/react-dom-shim@npm:10.3.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + storybook: ^10.3.0 + checksum: 10c0/59690a34b39299853ae689e891b88b01dd3019b1b9da56aa9cfc318ccd3880ec3736ec2f36b08c924df6952e510ea62d2810c32d2fda5bb6db71d133b3c94984 + languageName: node + linkType: hard + "@szmarczak/http-timer@npm:^4.0.5": version: 4.0.6 resolution: "@szmarczak/http-timer@npm:4.0.6" @@ -6056,6 +7696,170 @@ __metadata: languageName: node linkType: hard +"@tailwindcss/node@npm:4.2.2": + version: 4.2.2 + resolution: "@tailwindcss/node@npm:4.2.2" + dependencies: + "@jridgewell/remapping": "npm:^2.3.5" + enhanced-resolve: "npm:^5.19.0" + jiti: "npm:^2.6.1" + lightningcss: "npm:1.32.0" + magic-string: "npm:^0.30.21" + source-map-js: "npm:^1.2.1" + tailwindcss: "npm:4.2.2" + checksum: 10c0/4c0019355cd85a08f93ba3e179de37b83cc233b8ded4bd7714e633f89dd108928742e50966593257c2c1ab8db8914ea187dae007b5c692c869ceace11aeccede + languageName: node + linkType: hard + +"@tailwindcss/oxide-android-arm64@npm:4.2.2": + version: 4.2.2 + resolution: "@tailwindcss/oxide-android-arm64@npm:4.2.2" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@tailwindcss/oxide-darwin-arm64@npm:4.2.2": + version: 4.2.2 + resolution: "@tailwindcss/oxide-darwin-arm64@npm:4.2.2" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@tailwindcss/oxide-darwin-x64@npm:4.2.2": + version: 4.2.2 + resolution: "@tailwindcss/oxide-darwin-x64@npm:4.2.2" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@tailwindcss/oxide-freebsd-x64@npm:4.2.2": + version: 4.2.2 + resolution: "@tailwindcss/oxide-freebsd-x64@npm:4.2.2" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@tailwindcss/oxide-linux-arm-gnueabihf@npm:4.2.2": + version: 4.2.2 + resolution: "@tailwindcss/oxide-linux-arm-gnueabihf@npm:4.2.2" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@tailwindcss/oxide-linux-arm64-gnu@npm:4.2.2": + version: 4.2.2 + resolution: "@tailwindcss/oxide-linux-arm64-gnu@npm:4.2.2" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@tailwindcss/oxide-linux-arm64-musl@npm:4.2.2": + version: 4.2.2 + resolution: "@tailwindcss/oxide-linux-arm64-musl@npm:4.2.2" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@tailwindcss/oxide-linux-x64-gnu@npm:4.2.2": + version: 4.2.2 + resolution: "@tailwindcss/oxide-linux-x64-gnu@npm:4.2.2" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@tailwindcss/oxide-linux-x64-musl@npm:4.2.2": + version: 4.2.2 + resolution: "@tailwindcss/oxide-linux-x64-musl@npm:4.2.2" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@tailwindcss/oxide-wasm32-wasi@npm:4.2.2": + version: 4.2.2 + resolution: "@tailwindcss/oxide-wasm32-wasi@npm:4.2.2" + dependencies: + "@emnapi/core": "npm:^1.8.1" + "@emnapi/runtime": "npm:^1.8.1" + "@emnapi/wasi-threads": "npm:^1.1.0" + "@napi-rs/wasm-runtime": "npm:^1.1.1" + "@tybys/wasm-util": "npm:^0.10.1" + tslib: "npm:^2.8.1" + conditions: cpu=wasm32 + languageName: node + linkType: hard + +"@tailwindcss/oxide-win32-arm64-msvc@npm:4.2.2": + version: 4.2.2 + resolution: "@tailwindcss/oxide-win32-arm64-msvc@npm:4.2.2" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@tailwindcss/oxide-win32-x64-msvc@npm:4.2.2": + version: 4.2.2 + resolution: "@tailwindcss/oxide-win32-x64-msvc@npm:4.2.2" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@tailwindcss/oxide@npm:4.2.2": + version: 4.2.2 + resolution: "@tailwindcss/oxide@npm:4.2.2" + dependencies: + "@tailwindcss/oxide-android-arm64": "npm:4.2.2" + "@tailwindcss/oxide-darwin-arm64": "npm:4.2.2" + "@tailwindcss/oxide-darwin-x64": "npm:4.2.2" + "@tailwindcss/oxide-freebsd-x64": "npm:4.2.2" + "@tailwindcss/oxide-linux-arm-gnueabihf": "npm:4.2.2" + "@tailwindcss/oxide-linux-arm64-gnu": "npm:4.2.2" + "@tailwindcss/oxide-linux-arm64-musl": "npm:4.2.2" + "@tailwindcss/oxide-linux-x64-gnu": "npm:4.2.2" + "@tailwindcss/oxide-linux-x64-musl": "npm:4.2.2" + "@tailwindcss/oxide-wasm32-wasi": "npm:4.2.2" + "@tailwindcss/oxide-win32-arm64-msvc": "npm:4.2.2" + "@tailwindcss/oxide-win32-x64-msvc": "npm:4.2.2" + dependenciesMeta: + "@tailwindcss/oxide-android-arm64": + optional: true + "@tailwindcss/oxide-darwin-arm64": + optional: true + "@tailwindcss/oxide-darwin-x64": + optional: true + "@tailwindcss/oxide-freebsd-x64": + optional: true + "@tailwindcss/oxide-linux-arm-gnueabihf": + optional: true + "@tailwindcss/oxide-linux-arm64-gnu": + optional: true + "@tailwindcss/oxide-linux-arm64-musl": + optional: true + "@tailwindcss/oxide-linux-x64-gnu": + optional: true + "@tailwindcss/oxide-linux-x64-musl": + optional: true + "@tailwindcss/oxide-wasm32-wasi": + optional: true + "@tailwindcss/oxide-win32-arm64-msvc": + optional: true + "@tailwindcss/oxide-win32-x64-msvc": + optional: true + checksum: 10c0/22f78d73ffcec2d0d91f9fbfc29fed23c260e3e53f510f0b2598e322bf56a92ceb7e6f5a1c88ad1e3c7cfee9dd8d39285c411de5ec3225cdae2cbfdb737862e5 + languageName: node + linkType: hard + +"@tailwindcss/postcss@npm:^4.0.0": + version: 4.2.2 + resolution: "@tailwindcss/postcss@npm:4.2.2" + dependencies: + "@alloc/quick-lru": "npm:^5.2.0" + "@tailwindcss/node": "npm:4.2.2" + "@tailwindcss/oxide": "npm:4.2.2" + postcss: "npm:^8.5.6" + tailwindcss: "npm:4.2.2" + checksum: 10c0/b2501269d9eb2d8e80b548769b4552115ada36f7f7777d3b7656f7c7fe8b12d22305f9deb8a1fb9e41b30b98685ed3a1920ebb0b0e782b63f9483af9bc6e58a5 + languageName: node + linkType: hard + "@techteamer/ocsp@npm:1.0.1": version: 1.0.1 resolution: "@techteamer/ocsp@npm:1.0.1" @@ -6069,6 +7873,52 @@ __metadata: languageName: node linkType: hard +"@testing-library/jest-dom@npm:^6.9.1": + version: 6.9.1 + resolution: "@testing-library/jest-dom@npm:6.9.1" + dependencies: + "@adobe/css-tools": "npm:^4.4.0" + aria-query: "npm:^5.0.0" + css.escape: "npm:^1.5.1" + dom-accessibility-api: "npm:^0.6.3" + picocolors: "npm:^1.1.1" + redent: "npm:^3.0.0" + checksum: 10c0/4291ebd2f0f38d14cefac142c56c337941775a5807e2a3d6f1a14c2fbd6be76a18e498ed189e95bedc97d9e8cf1738049bc76c85b5bc5e23fae7c9e10f7b3a12 + languageName: node + linkType: hard + +"@testing-library/user-event@npm:^14.6.1": + version: 14.6.1 + resolution: "@testing-library/user-event@npm:14.6.1" + peerDependencies: + "@testing-library/dom": ">=7.21.4" + checksum: 10c0/75fea130a52bf320d35d46ed54f3eec77e71a56911b8b69a3fe29497b0b9947b2dc80d30f04054ad4ce7f577856ae3e5397ea7dff0ef14944d3909784c7a93fe + languageName: node + linkType: hard + +"@thednp/event-listener@npm:^2.0.14": + version: 2.0.14 + resolution: "@thednp/event-listener@npm:2.0.14" + checksum: 10c0/de601f88ebd4b69334e85d8f0c29a3a37ec665d7582879c1f057a06d525992f540179823070144dbc5b9bb79a1c30a8792e513aac8f872704e2f81bd67820489 + languageName: node + linkType: hard + +"@thednp/position-observer@npm:^1.1.1": + version: 1.1.1 + resolution: "@thednp/position-observer@npm:1.1.1" + dependencies: + "@thednp/shorty": "npm:^2.0.13" + checksum: 10c0/4e54c7238555e4b82c30ba45aafb4b67cd66a18b4212ee2208035b00fca5f90bdeaad546d59fcf2e4cd4c447f65f956c713a727ead9b8f7f49b87eb406f6fe22 + languageName: node + linkType: hard + +"@thednp/shorty@npm:^2.0.13": + version: 2.0.13 + resolution: "@thednp/shorty@npm:2.0.13" + checksum: 10c0/dd156f2b911cb1462d6c64d180dacacde4e6a658290c1fea427c157d1243dfd586930f283dc369710e7de68a2d61e5dfab8ff18d9805998bf855e4d19f97e34c + languageName: node + linkType: hard + "@tootallnate/once@npm:2": version: 2.0.0 resolution: "@tootallnate/once@npm:2.0.0" @@ -6083,6 +7933,17 @@ __metadata: languageName: node linkType: hard +"@ts-morph/common@npm:~0.28.1": + version: 0.28.1 + resolution: "@ts-morph/common@npm:0.28.1" + dependencies: + minimatch: "npm:^10.0.1" + path-browserify: "npm:^1.0.1" + tinyglobby: "npm:^0.2.14" + checksum: 10c0/d51276d840997e0f8f83e04f8b1689135bb12588a7ddbed575f87848d5737eeae31e242685d6449de27573e8ed30892157fea643393cb875e175f2711200bc50 + languageName: node + linkType: hard + "@tufjs/canonical-json@npm:2.0.0": version: 2.0.0 resolution: "@tufjs/canonical-json@npm:2.0.0" @@ -6100,6 +7961,15 @@ __metadata: languageName: node linkType: hard +"@tybys/wasm-util@npm:^0.10.1": + version: 0.10.1 + resolution: "@tybys/wasm-util@npm:0.10.1" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/b255094f293794c6d2289300c5fbcafbb5532a3aed3a5ffd2f8dc1828e639b88d75f6a376dd8f94347a44813fd7a7149d8463477a9a49525c8b2dcaa38c2d1e8 + languageName: node + linkType: hard + "@types/body-parser@npm:*": version: 1.19.6 resolution: "@types/body-parser@npm:1.19.6" @@ -6138,6 +8008,16 @@ __metadata: languageName: node linkType: hard +"@types/chai@npm:^5.2.2": + version: 5.2.3 + resolution: "@types/chai@npm:5.2.3" + dependencies: + "@types/deep-eql": "npm:*" + assertion-error: "npm:^2.0.1" + checksum: 10c0/e0ef1de3b6f8045a5e473e867c8565788c444271409d155588504840ad1a53611011f85072188c2833941189400228c1745d78323dac13fcede9c2b28bacfb2f + languageName: node + linkType: hard + "@types/compression@npm:1.8.1": version: 1.8.1 resolution: "@types/compression@npm:1.8.1" @@ -6176,6 +8056,13 @@ __metadata: languageName: node linkType: hard +"@types/deep-eql@npm:*": + version: 4.0.2 + resolution: "@types/deep-eql@npm:4.0.2" + checksum: 10c0/bf3f811843117900d7084b9d0c852da9a044d12eb40e6de73b552598a6843c21291a8a381b0532644574beecd5e3491c5ff3a0365ab86b15d59862c025384844 + languageName: node + linkType: hard + "@types/eslint-scope@npm:^3.7.7": version: 3.7.7 resolution: "@types/eslint-scope@npm:3.7.7" @@ -6257,6 +8144,13 @@ __metadata: languageName: node linkType: hard +"@types/html-minifier-terser@npm:^6.0.0": + version: 6.1.0 + resolution: "@types/html-minifier-terser@npm:6.1.0" + checksum: 10c0/a62fb8588e2f3818d82a2d7b953ad60a4a52fd767ae04671de1c16f5788bd72f1ed3a6109ed63fd190c06a37d919e3c39d8adbc1793a005def76c15a3f5f5dab + languageName: node + linkType: hard + "@types/http-cache-semantics@npm:*": version: 4.0.4 resolution: "@types/http-cache-semantics@npm:4.0.4" @@ -6280,7 +8174,7 @@ __metadata: languageName: node linkType: hard -"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.9": +"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" checksum: 10c0/a996a745e6c5d60292f36731dd41341339d4eeed8180bb09226e5c8d23759067692b1d88e5d91d72ee83dfc00d3aca8e7bd43ea120516c17922cbcb7c3e252db @@ -6296,6 +8190,13 @@ __metadata: languageName: node linkType: hard +"@types/mdx@npm:^2.0.0": + version: 2.0.13 + resolution: "@types/mdx@npm:2.0.13" + checksum: 10c0/5edf1099505ac568da55f9ae8a93e7e314e8cbc13d3445d0be61b75941226b005e1390d9b95caecf5dcb00c9d1bab2f1f60f6ff9876dc091a48b547495007720 + languageName: node + linkType: hard + "@types/mime@npm:^1": version: 1.3.5 resolution: "@types/mime@npm:1.3.5" @@ -6556,6 +8457,19 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/project-service@npm:8.57.1": + version: 8.57.1 + resolution: "@typescript-eslint/project-service@npm:8.57.1" + dependencies: + "@typescript-eslint/tsconfig-utils": "npm:^8.57.1" + "@typescript-eslint/types": "npm:^8.57.1" + debug: "npm:^4.4.3" + peerDependencies: + typescript: ">=4.8.4 <6.0.0" + checksum: 10c0/7830f61e35364ba77799f4badeaca8bd8914bbcda6afe37b788821f94f4b88b9c49817c50f4bdba497e8e542a705e9d921d36f5e67960ebf33f4f3d3111cdfee + languageName: node + linkType: hard + "@typescript-eslint/scope-manager@npm:8.39.1": version: 8.39.1 resolution: "@typescript-eslint/scope-manager@npm:8.39.1" @@ -6586,6 +8500,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/scope-manager@npm:8.57.1": + version: 8.57.1 + resolution: "@typescript-eslint/scope-manager@npm:8.57.1" + dependencies: + "@typescript-eslint/types": "npm:8.57.1" + "@typescript-eslint/visitor-keys": "npm:8.57.1" + checksum: 10c0/42b0b54981318bf21be6b107df82910718497b7b7b2b60df635aa06d78e313759e4b675830c0e542b6d87104d35b49df41b9fb7739b8ae326eaba2d6f7116166 + languageName: node + linkType: hard + "@typescript-eslint/tsconfig-utils@npm:8.39.1, @typescript-eslint/tsconfig-utils@npm:^8.39.1": version: 8.39.1 resolution: "@typescript-eslint/tsconfig-utils@npm:8.39.1" @@ -6613,6 +8537,15 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/tsconfig-utils@npm:8.57.1, @typescript-eslint/tsconfig-utils@npm:^8.57.1": + version: 8.57.1 + resolution: "@typescript-eslint/tsconfig-utils@npm:8.57.1" + peerDependencies: + typescript: ">=4.8.4 <6.0.0" + checksum: 10c0/3d3c8d80621507d31e4656c693534f28a1c04dfb047538cb79b0b6da874ef41875f5df5e814fa3a38812451cff6d5a7ae38d0bf77eb7fec7867f9c80af361b00 + languageName: node + linkType: hard + "@typescript-eslint/type-utils@npm:8.39.1, @typescript-eslint/type-utils@npm:^8.39.1": version: 8.39.1 resolution: "@typescript-eslint/type-utils@npm:8.39.1" @@ -6666,6 +8599,13 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/types@npm:8.57.1, @typescript-eslint/types@npm:^8.57.1": + version: 8.57.1 + resolution: "@typescript-eslint/types@npm:8.57.1" + checksum: 10c0/f447015276a31871440b07e328c2bbcee8337d72dca90ae00ac91e87d09e28a8a9c2fe44726a5226fcaa7db9d5347aafa650d59f7577a074dc65ea1414d24da1 + languageName: node + linkType: hard + "@typescript-eslint/typescript-estree@npm:8.39.1": version: 8.39.1 resolution: "@typescript-eslint/typescript-estree@npm:8.39.1" @@ -6725,6 +8665,25 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/typescript-estree@npm:8.57.1": + version: 8.57.1 + resolution: "@typescript-eslint/typescript-estree@npm:8.57.1" + dependencies: + "@typescript-eslint/project-service": "npm:8.57.1" + "@typescript-eslint/tsconfig-utils": "npm:8.57.1" + "@typescript-eslint/types": "npm:8.57.1" + "@typescript-eslint/visitor-keys": "npm:8.57.1" + debug: "npm:^4.4.3" + minimatch: "npm:^10.2.2" + semver: "npm:^7.7.3" + tinyglobby: "npm:^0.2.15" + ts-api-utils: "npm:^2.4.0" + peerDependencies: + typescript: ">=4.8.4 <6.0.0" + checksum: 10c0/a87e1d920a8fd2231b6a98b279dc7680d10ceac072001e85a72cd43adce288ed471afcaf8f171378f5a3221c500b3cf0ffc10a75fd521fb69fbd8b26d4626677 + languageName: node + linkType: hard + "@typescript-eslint/utils@npm:8.39.1, @typescript-eslint/utils@npm:^8.39.1": version: 8.39.1 resolution: "@typescript-eslint/utils@npm:8.39.1" @@ -6770,6 +8729,21 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/utils@npm:^8.48.0": + version: 8.57.1 + resolution: "@typescript-eslint/utils@npm:8.57.1" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.9.1" + "@typescript-eslint/scope-manager": "npm:8.57.1" + "@typescript-eslint/types": "npm:8.57.1" + "@typescript-eslint/typescript-estree": "npm:8.57.1" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.0.0" + checksum: 10c0/c85d6e7c618dbf902fda98cc795883388bc512bc2c34c7ac0481ea43acb6dd3cd38d60bdb571b586f392419a17998c89330fd7b0b9a344161f4a595637dd3f55 + languageName: node + linkType: hard + "@typescript-eslint/visitor-keys@npm:8.39.1": version: 8.39.1 resolution: "@typescript-eslint/visitor-keys@npm:8.39.1" @@ -6800,6 +8774,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/visitor-keys@npm:8.57.1": + version: 8.57.1 + resolution: "@typescript-eslint/visitor-keys@npm:8.57.1" + dependencies: + "@typescript-eslint/types": "npm:8.57.1" + eslint-visitor-keys: "npm:^5.0.0" + checksum: 10c0/088a545c4aec6d9cabb266e1e40634f5fafa06cb05ef172526555957b0d99ac08822733fb788a09227071fdd6bd8b63f054393a0ecf9d4599c54b57918aa0e57 + languageName: node + linkType: hard + "@typespec/ts-http-runtime@npm:^0.3.0": version: 0.3.1 resolution: "@typespec/ts-http-runtime@npm:0.3.1" @@ -6820,6 +8804,48 @@ __metadata: languageName: node linkType: hard +"@vitest/expect@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/expect@npm:3.2.4" + dependencies: + "@types/chai": "npm:^5.2.2" + "@vitest/spy": "npm:3.2.4" + "@vitest/utils": "npm:3.2.4" + chai: "npm:^5.2.0" + tinyrainbow: "npm:^2.0.0" + checksum: 10c0/7586104e3fd31dbe1e6ecaafb9a70131e4197dce2940f727b6a84131eee3decac7b10f9c7c72fa5edbdb68b6f854353bd4c0fa84779e274207fb7379563b10db + languageName: node + linkType: hard + +"@vitest/pretty-format@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/pretty-format@npm:3.2.4" + dependencies: + tinyrainbow: "npm:^2.0.0" + checksum: 10c0/5ad7d4278e067390d7d633e307fee8103958806a419ca380aec0e33fae71b44a64415f7a9b4bc11635d3c13d4a9186111c581d3cef9c65cc317e68f077456887 + languageName: node + linkType: hard + +"@vitest/spy@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/spy@npm:3.2.4" + dependencies: + tinyspy: "npm:^4.0.3" + checksum: 10c0/6ebf0b4697dc238476d6b6a60c76ba9eb1dd8167a307e30f08f64149612fd50227682b876420e4c2e09a76334e73f72e3ebf0e350714dc22474258292e202024 + languageName: node + linkType: hard + +"@vitest/utils@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/utils@npm:3.2.4" + dependencies: + "@vitest/pretty-format": "npm:3.2.4" + loupe: "npm:^3.1.4" + tinyrainbow: "npm:^2.0.0" + checksum: 10c0/024a9b8c8bcc12cf40183c246c244b52ecff861c6deb3477cbf487ac8781ad44c68a9c5fd69f8c1361878e55b97c10d99d511f2597f1f7244b5e5101d028ba64 + languageName: node + linkType: hard + "@webassemblyjs/ast@npm:1.14.1, @webassemblyjs/ast@npm:^1.14.1": version: 1.14.1 resolution: "@webassemblyjs/ast@npm:1.14.1" @@ -7067,6 +9093,15 @@ __metadata: languageName: node linkType: hard +"acorn@npm:^8.16.0": + version: 8.16.0 + resolution: "acorn@npm:8.16.0" + bin: + acorn: bin/acorn + checksum: 10c0/c9c52697227661b68d0debaf972222d4f622aa06b185824164e153438afa7b08273432ca43ea792cadb24dada1d46f6f6bb1ef8de9956979288cc1b96bf9914e + languageName: node + linkType: hard + "adjust-sourcemap-loader@npm:^4.0.0": version: 4.0.0 resolution: "adjust-sourcemap-loader@npm:4.0.0" @@ -7131,6 +9166,15 @@ __metadata: languageName: node linkType: hard +"ajv-keywords@npm:^3.5.2": + version: 3.5.2 + resolution: "ajv-keywords@npm:3.5.2" + peerDependencies: + ajv: ^6.9.1 + checksum: 10c0/0c57a47cbd656e8cdfd99d7c2264de5868918ffa207c8d7a72a7f63379d4333254b2ba03d69e3c035e996a3fd3eb6d5725d7a1597cca10694296e32510546360 + languageName: node + linkType: hard + "ajv-keywords@npm:^5.1.0": version: 5.1.0 resolution: "ajv-keywords@npm:5.1.0" @@ -7154,6 +9198,18 @@ __metadata: languageName: node linkType: hard +"ajv@npm:8.18.0": + version: 8.18.0 + resolution: "ajv@npm:8.18.0" + dependencies: + fast-deep-equal: "npm:^3.1.3" + fast-uri: "npm:^3.0.1" + json-schema-traverse: "npm:^1.0.0" + require-from-string: "npm:^2.0.2" + checksum: 10c0/e7517c426173513a07391be951879932bdf3348feaebd2199f5b901c20f99d60db8cd1591502d4d551dc82f594e82a05c4fe1c70139b15b8937f7afeaed9532f + languageName: node + linkType: hard + "ajv@npm:^6.12.4": version: 6.12.6 resolution: "ajv@npm:6.12.6" @@ -7166,6 +9222,18 @@ __metadata: languageName: node linkType: hard +"ajv@npm:^6.12.5": + version: 6.14.0 + resolution: "ajv@npm:6.14.0" + dependencies: + fast-deep-equal: "npm:^3.1.1" + fast-json-stable-stringify: "npm:^2.0.0" + json-schema-traverse: "npm:^0.4.1" + uri-js: "npm:^4.2.2" + checksum: 10c0/a2bc39b0555dc9802c899f86990eb8eed6e366cddbf65be43d5aa7e4f3c4e1a199d5460fd7ca4fb3d864000dbbc049253b72faa83b3b30e641ca52cb29a68c22 + languageName: node + linkType: hard + "algoliasearch@npm:5.35.0": version: 5.35.0 resolution: "algoliasearch@npm:5.35.0" @@ -7225,7 +9293,7 @@ __metadata: languageName: node linkType: hard -"ansi-colors@npm:4.1.3, ansi-colors@npm:^4.1.1": +"ansi-colors@npm:4.1.3, ansi-colors@npm:^4.1.1, ansi-colors@npm:^4.1.3": version: 4.1.3 resolution: "ansi-colors@npm:4.1.3" checksum: 10c0/ec87a2f59902f74e61eada7f6e6fe20094a628dab765cfdbd03c3477599368768cffccdb5d3bb19a1b6c99126783a143b1fee31aab729b31ffe5836c7e5e28b9 @@ -7241,7 +9309,7 @@ __metadata: languageName: node linkType: hard -"ansi-html-community@npm:^0.0.8": +"ansi-html-community@npm:0.0.8, ansi-html-community@npm:^0.0.8": version: 0.0.8 resolution: "ansi-html-community@npm:0.0.8" bin: @@ -7304,6 +9372,22 @@ __metadata: languageName: node linkType: hard +"apache-crypt@npm:^1.1.2": + version: 1.2.6 + resolution: "apache-crypt@npm:1.2.6" + dependencies: + unix-crypt-td-js: "npm:^1.1.4" + checksum: 10c0/00ce45e671f256f3bbdcd47da57b9d9007af3e70102316304bfb1fb4f28610ea9b733e616a90079ee7c2bf1adebdda3fd99cafe2ac668ad55b0323c79df64f67 + languageName: node + linkType: hard + +"apache-md5@npm:^1.0.6": + version: 1.1.8 + resolution: "apache-md5@npm:1.1.8" + checksum: 10c0/423aa1baddcedc42e2fdf52efcf7fae2e7de9535e6ca7dd4a049f49fb5ec9b6a4469f327e02268088ed3dacdbec6f1ea4132941e2d75899c4e412421e6ffcbfc + languageName: node + linkType: hard + "arg@npm:^5.0.2": version: 5.0.2 resolution: "arg@npm:5.0.2" @@ -7318,7 +9402,7 @@ __metadata: languageName: node linkType: hard -"aria-query@npm:5.3.2": +"aria-query@npm:5.3.2, aria-query@npm:^5.0.0": version: 5.3.2 resolution: "aria-query@npm:5.3.2" checksum: 10c0/003c7e3e2cff5540bf7a7893775fc614de82b0c5dde8ae823d47b7a28a9d4da1f7ed85f340bdb93d5649caa927755f0e31ecc7ab63edfdfc00c8ef07e505e03e @@ -7378,6 +9462,13 @@ __metadata: languageName: node linkType: hard +"assertion-error@npm:^2.0.1": + version: 2.0.1 + resolution: "assertion-error@npm:2.0.1" + checksum: 10c0/bbbcb117ac6480138f8c93cf7f535614282dea9dc828f540cdece85e3c665e8f78958b96afac52f29ff883c72638e6a87d469ecc9fe5bc902df03ed24a55dba8 + languageName: node + linkType: hard + "ast-types@npm:^0.13.4": version: 0.13.4 resolution: "ast-types@npm:0.13.4" @@ -7387,6 +9478,15 @@ __metadata: languageName: node linkType: hard +"ast-types@npm:^0.16.1": + version: 0.16.1 + resolution: "ast-types@npm:0.16.1" + dependencies: + tslib: "npm:^2.0.1" + checksum: 10c0/abcc49e42eb921a7ebc013d5bec1154651fb6dbc3f497541d488859e681256901b2990b954d530ba0da4d0851271d484f7057d5eff5e07cb73e8b10909f711bf + languageName: node + linkType: hard + "async-retry@npm:^1.3.3": version: 1.3.3 resolution: "async-retry@npm:1.3.3" @@ -7517,6 +9617,13 @@ __metadata: languageName: node linkType: hard +"balanced-match@npm:^4.0.2": + version: 4.0.4 + resolution: "balanced-match@npm:4.0.4" + checksum: 10c0/07e86102a3eb2ee2a6a1a89164f29d0dbaebd28f2ca3f5ca786f36b8b23d9e417eb3be45a4acf754f837be5ac0a2317de90d3fcb7f4f4dc95720a1f36b26a17b + languageName: node + linkType: hard + "base64-js@npm:^1.3.0": version: 1.5.1 resolution: "base64-js@npm:1.5.1" @@ -7540,6 +9647,15 @@ __metadata: languageName: node linkType: hard +"basic-auth@npm:~2.0.1": + version: 2.0.1 + resolution: "basic-auth@npm:2.0.1" + dependencies: + safe-buffer: "npm:5.1.2" + checksum: 10c0/05f56db3a0fc31c89c86b605231e32ee143fb6ae38dc60616bc0970ae6a0f034172def99e69d3aed0e2c9e7cac84e2d63bc51a0b5ff6ab5fc8808cc8b29923c1 + languageName: node + linkType: hard + "basic-ftp@npm:^5.0.2": version: 5.0.5 resolution: "basic-ftp@npm:5.0.5" @@ -7554,6 +9670,13 @@ __metadata: languageName: node linkType: hard +"bcryptjs@npm:^2.4.3": + version: 2.4.3 + resolution: "bcryptjs@npm:2.4.3" + checksum: 10c0/b969467087ed7a01ff905a1c6a0c45014ec586248a448ea08370c8ed8bb314bda16a870ca23e0961d7d23bdce1a04c76fa70a9d680be814fa9ac7d8fc61870a3 + languageName: node + linkType: hard + "beasties@npm:0.3.5": version: 0.3.5 resolution: "beasties@npm:0.3.5" @@ -7665,6 +9788,23 @@ __metadata: languageName: node linkType: hard +"body-parser@npm:^2.2.2": + version: 2.2.2 + resolution: "body-parser@npm:2.2.2" + dependencies: + bytes: "npm:^3.1.2" + content-type: "npm:^1.0.5" + debug: "npm:^4.4.3" + http-errors: "npm:^2.0.0" + iconv-lite: "npm:^0.7.0" + on-finished: "npm:^2.4.1" + qs: "npm:^6.14.1" + raw-body: "npm:^3.0.1" + type-is: "npm:^2.0.1" + checksum: 10c0/95a830a003b38654b75166ca765358aa92ee3d561bf0e41d6ccdde0e1a0c9783cab6b90b20eb635d23172c010b59d3563a137a738e74da4ba714463510d05137 + languageName: node + linkType: hard + "bonjour-service@npm:^1.2.1": version: 1.3.0 resolution: "bonjour-service@npm:1.3.0" @@ -7682,6 +9822,17 @@ __metadata: languageName: node linkType: hard +"bootstrap.native@npm:^5.1.6": + version: 5.1.8 + resolution: "bootstrap.native@npm:5.1.8" + dependencies: + "@thednp/event-listener": "npm:^2.0.14" + "@thednp/position-observer": "npm:^1.1.1" + "@thednp/shorty": "npm:^2.0.13" + checksum: 10c0/d3926eb2288db75a6a565a133fb06e8824ce068b7eba1bc9b3824ad6e2eefc8af3068bc9a850e8b6346fd661d0d5d03e4f15860c904a72f17f10509225e2b141 + languageName: node + linkType: hard + "bowser@npm:^2.11.0": version: 2.12.1 resolution: "bowser@npm:2.12.1" @@ -7708,6 +9859,15 @@ __metadata: languageName: node linkType: hard +"brace-expansion@npm:^5.0.2": + version: 5.0.4 + resolution: "brace-expansion@npm:5.0.4" + dependencies: + balanced-match: "npm:^4.0.2" + checksum: 10c0/359cbcfa80b2eb914ca1f3440e92313fbfe7919ee6b274c35db55bec555aded69dac5ee78f102cec90c35f98c20fa43d10936d0cd9978158823c249257e1643a + languageName: node + linkType: hard + "braces@npm:^3.0.3, braces@npm:~3.0.2": version: 3.0.3 resolution: "braces@npm:3.0.3" @@ -7738,7 +9898,7 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.28.0": +"browserslist@npm:^4.28.0, browserslist@npm:^4.28.1": version: 4.28.1 resolution: "browserslist@npm:4.28.1" dependencies: @@ -7845,6 +10005,13 @@ __metadata: languageName: node linkType: hard +"callsite@npm:^1.0.0": + version: 1.0.0 + resolution: "callsite@npm:1.0.0" + checksum: 10c0/8b23d5ed879984b66fe3da381994d6c4b741e561226abc48b40c99c4896f7125db395ea4aa989071a7eb0712c3f83bc32fb1e798fdf54967acdf4af176e48572 + languageName: node + linkType: hard + "callsites@npm:^3.0.0": version: 3.1.0 resolution: "callsites@npm:3.1.0" @@ -7852,6 +10019,16 @@ __metadata: languageName: node linkType: hard +"camel-case@npm:^4.1.2": + version: 4.1.2 + resolution: "camel-case@npm:4.1.2" + dependencies: + pascal-case: "npm:^3.1.2" + tslib: "npm:^2.0.3" + checksum: 10c0/bf9eefaee1f20edbed2e9a442a226793bc72336e2b99e5e48c6b7252b6f70b080fc46d8246ab91939e2af91c36cdd422e0af35161e58dd089590f302f8f64c8a + languageName: node + linkType: hard + "camelcase-css@npm:^2.0.1": version: 2.0.1 resolution: "camelcase-css@npm:2.0.1" @@ -7873,6 +10050,26 @@ __metadata: languageName: node linkType: hard +"case-sensitive-paths-webpack-plugin@npm:^2.4.0": + version: 2.4.0 + resolution: "case-sensitive-paths-webpack-plugin@npm:2.4.0" + checksum: 10c0/310dab619b661a7fa44ed773870be6d6d7373faff6953ad92720f9553e2579e46dda5b9a79eae6d25ff3733cc15aa466b96e5811af16213f23c115aa220b4ab4 + languageName: node + linkType: hard + +"chai@npm:^5.2.0": + version: 5.3.3 + resolution: "chai@npm:5.3.3" + dependencies: + assertion-error: "npm:^2.0.1" + check-error: "npm:^2.1.1" + deep-eql: "npm:^5.0.1" + loupe: "npm:^3.1.0" + pathval: "npm:^2.0.0" + checksum: 10c0/b360fd4d38861622e5010c2f709736988b05c7f31042305fa3f4e9911f6adb80ccfb4e302068bf8ed10e835c2e2520cba0f5edc13d878b886987e5aa62483f53 + languageName: node + linkType: hard + "chalk@npm:3.0.0, chalk@npm:~3.0.0": version: 3.0.0 resolution: "chalk@npm:3.0.0" @@ -7883,7 +10080,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^4.0.0": +"chalk@npm:^4.0.0, chalk@npm:^4.1.0, chalk@npm:^4.1.2": version: 4.1.2 resolution: "chalk@npm:4.1.2" dependencies: @@ -7930,7 +10127,47 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:^3.5.3, chokidar@npm:^3.6.0": +"check-error@npm:^2.1.1": + version: 2.1.3 + resolution: "check-error@npm:2.1.3" + checksum: 10c0/878e99038fb6476316b74668cd6a498c7e66df3efe48158fa40db80a06ba4258742ac3ee2229c4a2a98c5e73f5dff84eb3e50ceb6b65bbd8f831eafc8338607d + languageName: node + linkType: hard + +"cheerio-select@npm:^2.1.0": + version: 2.1.0 + resolution: "cheerio-select@npm:2.1.0" + dependencies: + boolbase: "npm:^1.0.0" + css-select: "npm:^5.1.0" + css-what: "npm:^6.1.0" + domelementtype: "npm:^2.3.0" + domhandler: "npm:^5.0.3" + domutils: "npm:^3.0.1" + checksum: 10c0/2242097e593919dba4aacb97d7b8275def8b9ec70b00aa1f43335456870cfc9e284eae2080bdc832ed232dabb9eefcf56c722d152da4a154813fb8814a55d282 + languageName: node + linkType: hard + +"cheerio@npm:1.1.2": + version: 1.1.2 + resolution: "cheerio@npm:1.1.2" + dependencies: + cheerio-select: "npm:^2.1.0" + dom-serializer: "npm:^2.0.0" + domhandler: "npm:^5.0.3" + domutils: "npm:^3.2.2" + encoding-sniffer: "npm:^0.2.1" + htmlparser2: "npm:^10.0.0" + parse5: "npm:^7.3.0" + parse5-htmlparser2-tree-adapter: "npm:^7.1.0" + parse5-parser-stream: "npm:^7.1.2" + undici: "npm:^7.12.0" + whatwg-mimetype: "npm:^4.0.0" + checksum: 10c0/2c6d2274666fe122f54fdca457ee76453e1a993b19563acaa23eb565bf7776f0f01e4c3800092f00e84aa13c83a161f0cf000ac0a8332d1d7f2b2387d6ecc5fc + languageName: node + linkType: hard + +"chokidar@npm:^3.5.2, chokidar@npm:^3.5.3, chokidar@npm:^3.6.0": version: 3.6.0 resolution: "chokidar@npm:3.6.0" dependencies: @@ -7949,7 +10186,7 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:^4.0.0": +"chokidar@npm:^4.0.0, chokidar@npm:^4.0.1": version: 4.0.3 resolution: "chokidar@npm:4.0.3" dependencies: @@ -7958,6 +10195,15 @@ __metadata: languageName: node linkType: hard +"chokidar@npm:^5.0.0": + version: 5.0.0 + resolution: "chokidar@npm:5.0.0" + dependencies: + readdirp: "npm:^5.0.0" + checksum: 10c0/42fc907cb2a7ff5c9e220f84dae75380a77997f851c2a5e7865a2cf9ae45dd407a23557208cdcdbf3ac8c93341135a1748e4c48c31855f3bfa095e5159b6bdec + languageName: node + linkType: hard + "chownr@npm:^2.0.0": version: 2.0.0 resolution: "chownr@npm:2.0.0" @@ -7979,6 +10225,22 @@ __metadata: languageName: node linkType: hard +"cjs-module-lexer@npm:^1.2.3": + version: 1.4.3 + resolution: "cjs-module-lexer@npm:1.4.3" + checksum: 10c0/076b3af85adc4d65dbdab1b5b240fe5b45d44fcf0ef9d429044dd94d19be5589376805c44fb2d4b3e684e5fe6a9b7cf3e426476a6507c45283c5fc6ff95240be + languageName: node + linkType: hard + +"clean-css@npm:^5.2.2": + version: 5.3.3 + resolution: "clean-css@npm:5.3.3" + dependencies: + source-map: "npm:~0.6.0" + checksum: 10c0/381de7523e23f3762eb180e327dcc0cedafaf8cb1cd8c26b7cc1fc56e0829a92e734729c4f955394d65ed72fb62f82d8baf78af34b33b8a7d41ebad2accdd6fb + languageName: node + linkType: hard + "clean-stack@npm:^2.0.0": version: 2.2.0 resolution: "clean-stack@npm:2.2.0" @@ -8094,6 +10356,13 @@ __metadata: languageName: node linkType: hard +"code-block-writer@npm:^13.0.3": + version: 13.0.3 + resolution: "code-block-writer@npm:13.0.3" + checksum: 10c0/87db97b37583f71cfd7eced8bf3f0a0a0ca53af912751a734372b36c08cd27f3e8a4878ec05591c0cd9ae11bea8add1423e132d660edd86aab952656dd41fd66 + languageName: node + linkType: hard + "color-convert@npm:^2.0.1": version: 2.0.1 resolution: "color-convert@npm:2.0.1" @@ -8135,6 +10404,15 @@ __metadata: languageName: node linkType: hard +"color-support@npm:^1.1.3": + version: 1.1.3 + resolution: "color-support@npm:1.1.3" + bin: + color-support: bin.js + checksum: 10c0/8ffeaa270a784dc382f62d9be0a98581db43e11eee301af14734a6d089bd456478b1a8b3e7db7ca7dc5b18a75f828f775c44074020b51c05fc00e6d0992b1cc6 + languageName: node + linkType: hard + "color@npm:^5.0.2": version: 5.0.2 resolution: "color@npm:5.0.2" @@ -8152,6 +10430,13 @@ __metadata: languageName: node linkType: hard +"colors@npm:1.4.0": + version: 1.4.0 + resolution: "colors@npm:1.4.0" + checksum: 10c0/9af357c019da3c5a098a301cf64e3799d27549d8f185d86f79af23069e4f4303110d115da98483519331f6fb71c8568d5688fa1c6523600044fd4a54e97c4efb + languageName: node + linkType: hard + "combined-stream@npm:^1.0.8": version: 1.0.8 resolution: "combined-stream@npm:1.0.8" @@ -8189,6 +10474,13 @@ __metadata: languageName: node linkType: hard +"commander@npm:^8.3.0": + version: 8.3.0 + resolution: "commander@npm:8.3.0" + checksum: 10c0/8b043bb8322ea1c39664a1598a95e0495bfe4ca2fad0d84a92d7d1d8d213e2a155b441d2470c8e08de7c4a28cf2bc6e169211c49e1b21d9f7edc6ae4d9356060 + languageName: node + linkType: hard + "compare-func@npm:^2.0.0": version: 2.0.0 resolution: "compare-func@npm:2.0.0" @@ -8237,6 +10529,18 @@ __metadata: languageName: node linkType: hard +"connect@npm:^3.7.0": + version: 3.7.0 + resolution: "connect@npm:3.7.0" + dependencies: + debug: "npm:2.6.9" + finalhandler: "npm:1.1.2" + parseurl: "npm:~1.3.3" + utils-merge: "npm:1.0.1" + checksum: 10c0/f120c6116bb16a0a7d2703c0b4a0cd7ed787dc5ec91978097bf62aa967289020a9f41a9cd3c3276a7b92aaa36f382d2cd35fed7138fd466a55c8e9fdbed11ca8 + languageName: node + linkType: hard + "content-disposition@npm:0.5.4": version: 0.5.4 resolution: "content-disposition@npm:0.5.4" @@ -8349,6 +10653,21 @@ __metadata: languageName: node linkType: hard +"copy-webpack-plugin@npm:14.0.0": + version: 14.0.0 + resolution: "copy-webpack-plugin@npm:14.0.0" + dependencies: + glob-parent: "npm:^6.0.1" + normalize-path: "npm:^3.0.0" + schema-utils: "npm:^4.2.0" + serialize-javascript: "npm:^7.0.3" + tinyglobby: "npm:^0.2.12" + peerDependencies: + webpack: ^5.1.0 + checksum: 10c0/1296bec96c9b7bb603c11aac95bc9580810e3f6be062044d2d4442c54d11ac5a0cd535e118fee6d65a83709a7a440e231686c0a2755f36df73061f7e4a0024d6 + languageName: node + linkType: hard + "core-js-compat@npm:^3.43.0": version: 3.47.0 resolution: "core-js-compat@npm:3.47.0" @@ -8375,6 +10694,16 @@ __metadata: languageName: node linkType: hard +"cors@npm:latest": + version: 2.8.6 + resolution: "cors@npm:2.8.6" + dependencies: + object-assign: "npm:^4" + vary: "npm:^1" + checksum: 10c0/ab2bc57b8af8ef8476682a59647f7c55c1a7d406b559ac06119aa1c5f70b96d35036864d197b24cf86e228e4547231088f1f94ca05061dbb14d89cc0bc9d4cab + languageName: node + linkType: hard + "cosmiconfig-typescript-loader@npm:^6.1.0": version: 6.1.0 resolution: "cosmiconfig-typescript-loader@npm:6.1.0" @@ -8388,6 +10717,23 @@ __metadata: languageName: node linkType: hard +"cosmiconfig@npm:^8.2.0": + version: 8.3.6 + resolution: "cosmiconfig@npm:8.3.6" + dependencies: + import-fresh: "npm:^3.3.0" + js-yaml: "npm:^4.1.0" + parse-json: "npm:^5.2.0" + path-type: "npm:^4.0.0" + peerDependencies: + typescript: ">=4.9.5" + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/0382a9ed13208f8bfc22ca2f62b364855207dffdb73dc26e150ade78c3093f1cf56172df2dd460c8caf2afa91c0ed4ec8a88c62f8f9cd1cf423d26506aa8797a + languageName: node + linkType: hard + "cosmiconfig@npm:^9.0.0": version: 9.0.0 resolution: "cosmiconfig@npm:9.0.0" @@ -8412,7 +10758,7 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.5, cross-spawn@npm:^7.0.6": +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.5, cross-spawn@npm:^7.0.6": version: 7.0.6 resolution: "cross-spawn@npm:7.0.6" dependencies: @@ -8447,6 +10793,56 @@ __metadata: languageName: node linkType: hard +"css-loader@npm:^7.1.2": + version: 7.1.4 + resolution: "css-loader@npm:7.1.4" + dependencies: + icss-utils: "npm:^5.1.0" + postcss: "npm:^8.4.40" + postcss-modules-extract-imports: "npm:^3.1.0" + postcss-modules-local-by-default: "npm:^4.0.5" + postcss-modules-scope: "npm:^3.2.0" + postcss-modules-values: "npm:^4.0.0" + postcss-value-parser: "npm:^4.2.0" + semver: "npm:^7.6.3" + peerDependencies: + "@rspack/core": 0.x || ^1.0.0 || ^2.0.0-0 + webpack: ^5.27.0 + peerDependenciesMeta: + "@rspack/core": + optional: true + webpack: + optional: true + checksum: 10c0/a3a3a6b564d4fcf978961be8bc6ca06fb3836fc8fbd729ddae4b0b94166a0f5ccf119fb3301a6fecbe90608a8edbfd418bdc644cf053615e6271aa65b3fdc00b + languageName: node + linkType: hard + +"css-select@npm:^4.1.3": + version: 4.3.0 + resolution: "css-select@npm:4.3.0" + dependencies: + boolbase: "npm:^1.0.0" + css-what: "npm:^6.0.1" + domhandler: "npm:^4.3.1" + domutils: "npm:^2.8.0" + nth-check: "npm:^2.0.1" + checksum: 10c0/a489d8e5628e61063d5a8fe0fa1cc7ae2478cb334a388a354e91cf2908154be97eac9fa7ed4dffe87a3e06cf6fcaa6016553115335c4fd3377e13dac7bd5a8e1 + languageName: node + linkType: hard + +"css-select@npm:^5.1.0": + version: 5.2.2 + resolution: "css-select@npm:5.2.2" + dependencies: + boolbase: "npm:^1.0.0" + css-what: "npm:^6.1.0" + domhandler: "npm:^5.0.2" + domutils: "npm:^3.0.1" + nth-check: "npm:^2.0.1" + checksum: 10c0/d79fffa97106007f2802589f3ed17b8c903f1c961c0fc28aa8a051eee0cbad394d8446223862efd4c1b40445a6034f626bb639cf2035b0bfc468544177593c99 + languageName: node + linkType: hard + "css-select@npm:^6.0.0": version: 6.0.0 resolution: "css-select@npm:6.0.0" @@ -8460,6 +10856,13 @@ __metadata: languageName: node linkType: hard +"css-what@npm:^6.0.1, css-what@npm:^6.1.0": + version: 6.2.2 + resolution: "css-what@npm:6.2.2" + checksum: 10c0/91e24c26fb977b4ccef30d7007d2668c1c10ac0154cc3f42f7304410e9594fb772aea4f30c832d2993b132ca8d99338050866476210316345ec2e7d47b248a56 + languageName: node + linkType: hard + "css-what@npm:^7.0.0": version: 7.0.0 resolution: "css-what@npm:7.0.0" @@ -8467,6 +10870,13 @@ __metadata: languageName: node linkType: hard +"css.escape@npm:^1.5.1": + version: 1.5.1 + resolution: "css.escape@npm:1.5.1" + checksum: 10c0/5e09035e5bf6c2c422b40c6df2eb1529657a17df37fda5d0433d722609527ab98090baf25b13970ca754079a0f3161dd3dfc0e743563ded8cfa0749d861c1525 + languageName: node + linkType: hard + "cssesc@npm:^3.0.0": version: 3.0.0 resolution: "cssesc@npm:3.0.0" @@ -8595,6 +11005,15 @@ __metadata: languageName: node linkType: hard +"decache@npm:^4.6.2": + version: 4.6.2 + resolution: "decache@npm:4.6.2" + dependencies: + callsite: "npm:^1.0.0" + checksum: 10c0/7a27260a0bfc51b913db4956e8fe596d72151c0d4cb437daa30787950c274b3fa5c81235a334742b1e32f87ee55d7eb2a0d960ecdadf3583ef23b8f796aebad3 + languageName: node + linkType: hard + "decompress-response@npm:^6.0.0": version: 6.0.0 resolution: "decompress-response@npm:6.0.0" @@ -8604,6 +11023,13 @@ __metadata: languageName: node linkType: hard +"deep-eql@npm:^5.0.1": + version: 5.0.2 + resolution: "deep-eql@npm:5.0.2" + checksum: 10c0/7102cf3b7bb719c6b9c0db2e19bf0aa9318d141581befe8c7ce8ccd39af9eaa4346e5e05adef7f9bd7015da0f13a3a25dcfe306ef79dc8668aedbecb658dd247 + languageName: node + linkType: hard + "deep-is@npm:^0.1.3": version: 0.1.4 resolution: "deep-is@npm:0.1.4" @@ -8611,6 +11037,13 @@ __metadata: languageName: node linkType: hard +"deepmerge@npm:^4.2.2": + version: 4.3.1 + resolution: "deepmerge@npm:4.3.1" + checksum: 10c0/e53481aaf1aa2c4082b5342be6b6d8ad9dfe387bc92ce197a66dea08bd4265904a087e75e464f14d1347cf2ac8afe1e4c16b266e0561cc5df29382d3c5f80044 + languageName: node + linkType: hard + "default-browser-id@npm:^5.0.0": version: 5.0.0 resolution: "default-browser-id@npm:5.0.0" @@ -8635,6 +11068,13 @@ __metadata: languageName: node linkType: hard +"define-lazy-prop@npm:^2.0.0": + version: 2.0.0 + resolution: "define-lazy-prop@npm:2.0.0" + checksum: 10c0/db6c63864a9d3b7dc9def55d52764968a5af296de87c1b2cc71d8be8142e445208071953649e0386a8cc37cfcf9a2067a47207f1eb9ff250c2a269658fdae422 + languageName: node + linkType: hard + "define-lazy-prop@npm:^3.0.0": version: 3.0.0 resolution: "define-lazy-prop@npm:3.0.0" @@ -8697,6 +11137,13 @@ __metadata: languageName: node linkType: hard +"detect-libc@npm:^2.0.3": + version: 2.1.2 + resolution: "detect-libc@npm:2.1.2" + checksum: 10c0/acc675c29a5649fa1fb6e255f993b8ee829e510b6b56b0910666949c80c364738833417d0edb5f90e4e46be17228b0f2b66a010513984e18b15deeeac49369c4 + languageName: node + linkType: hard + "detect-node@npm:^2.0.4": version: 2.1.0 resolution: "detect-node@npm:2.1.0" @@ -8727,6 +11174,33 @@ __metadata: languageName: node linkType: hard +"dom-accessibility-api@npm:^0.6.3": + version: 0.6.3 + resolution: "dom-accessibility-api@npm:0.6.3" + checksum: 10c0/10bee5aa514b2a9a37c87cd81268db607a2e933a050074abc2f6fa3da9080ebed206a320cbc123567f2c3087d22292853bdfdceaffdd4334ffe2af9510b29360 + languageName: node + linkType: hard + +"dom-converter@npm:^0.2.0": + version: 0.2.0 + resolution: "dom-converter@npm:0.2.0" + dependencies: + utila: "npm:~0.4" + checksum: 10c0/e96aa63bd8c6ee3cd9ce19c3aecfc2c42e50a460e8087114794d4f5ecf3a4f052b34ea3bf2d73b5d80b4da619073b49905e6d7d788ceb7814ca4c29be5354a11 + languageName: node + linkType: hard + +"dom-serializer@npm:^1.0.1": + version: 1.4.1 + resolution: "dom-serializer@npm:1.4.1" + dependencies: + domelementtype: "npm:^2.0.1" + domhandler: "npm:^4.2.0" + entities: "npm:^2.0.0" + checksum: 10c0/67d775fa1ea3de52035c98168ddcd59418356943b5eccb80e3c8b3da53adb8e37edb2cc2f885802b7b1765bf5022aec21dfc32910d7f9e6de4c3148f095ab5e0 + languageName: node + linkType: hard + "dom-serializer@npm:^2.0.0": version: 2.0.0 resolution: "dom-serializer@npm:2.0.0" @@ -8738,13 +11212,22 @@ __metadata: languageName: node linkType: hard -"domelementtype@npm:^2.3.0": +"domelementtype@npm:^2.0.1, domelementtype@npm:^2.2.0, domelementtype@npm:^2.3.0": version: 2.3.0 resolution: "domelementtype@npm:2.3.0" checksum: 10c0/686f5a9ef0fff078c1412c05db73a0dce096190036f33e400a07e2a4518e9f56b1e324f5c576a0a747ef0e75b5d985c040b0d51945ce780c0dd3c625a18cd8c9 languageName: node linkType: hard +"domhandler@npm:^4.0.0, domhandler@npm:^4.2.0, domhandler@npm:^4.3.1": + version: 4.3.1 + resolution: "domhandler@npm:4.3.1" + dependencies: + domelementtype: "npm:^2.2.0" + checksum: 10c0/5c199c7468cb052a8b5ab80b13528f0db3d794c64fc050ba793b574e158e67c93f8336e87fd81e9d5ee43b0e04aea4d8b93ed7be4899cb726a1601b3ba18538b + languageName: node + linkType: hard + "domhandler@npm:^5.0.2, domhandler@npm:^5.0.3": version: 5.0.3 resolution: "domhandler@npm:5.0.3" @@ -8754,7 +11237,18 @@ __metadata: languageName: node linkType: hard -"domutils@npm:^3.2.1, domutils@npm:^3.2.2": +"domutils@npm:^2.5.2, domutils@npm:^2.8.0": + version: 2.8.0 + resolution: "domutils@npm:2.8.0" + dependencies: + dom-serializer: "npm:^1.0.1" + domelementtype: "npm:^2.2.0" + domhandler: "npm:^4.2.0" + checksum: 10c0/d58e2ae01922f0dd55894e61d18119924d88091837887bf1438f2327f32c65eb76426bd9384f81e7d6dcfb048e0f83c19b222ad7101176ad68cdc9c695b563db + languageName: node + linkType: hard + +"domutils@npm:^3.0.1, domutils@npm:^3.2.1, domutils@npm:^3.2.2": version: 3.2.2 resolution: "domutils@npm:3.2.2" dependencies: @@ -8765,6 +11259,16 @@ __metadata: languageName: node linkType: hard +"dot-case@npm:^3.0.4": + version: 3.0.4 + resolution: "dot-case@npm:3.0.4" + dependencies: + no-case: "npm:^3.0.4" + tslib: "npm:^2.0.3" + checksum: 10c0/5b859ea65097a7ea870e2c91b5768b72ddf7fa947223fd29e167bcdff58fe731d941c48e47a38ec8aa8e43044c8fbd15cd8fa21689a526bc34b6548197cd5b05 + languageName: node + linkType: hard + "dot-prop@npm:^5.1.0": version: 5.3.0 resolution: "dot-prop@npm:5.3.0" @@ -8774,6 +11278,13 @@ __metadata: languageName: node linkType: hard +"dot@npm:^2.0.0-beta.1": + version: 2.0.0-beta.1 + resolution: "dot@npm:2.0.0-beta.1" + checksum: 10c0/28876e214576210384fd49bcf2f3c4afc6478cec7de18e923c07a085dd1f3c565ff162c53911040267fc9ff96fa732dde8676c503ffd60d5a522101bc1ad1e21 + languageName: node + linkType: hard + "dotenv@npm:17.2.3": version: 17.2.3 resolution: "dotenv@npm:17.2.3" @@ -8781,6 +11292,13 @@ __metadata: languageName: node linkType: hard +"dotenv@npm:^17.2.3": + version: 17.3.1 + resolution: "dotenv@npm:17.3.1" + checksum: 10c0/c78e0c2d5a549c751e544cc60e2b95e7cb67e0c551f42e094d161c6b297aa44b630a3c2dcacf5569e529a6c2a6b84e2ab9be8d37b299d425df5a18b81ce4a35f + languageName: node + linkType: hard + "dunder-proto@npm:^1.0.1": version: 1.0.1 resolution: "dunder-proto@npm:1.0.1" @@ -8792,6 +11310,13 @@ __metadata: languageName: node linkType: hard +"duplexer@npm:^0.1.1, duplexer@npm:~0.1.1": + version: 0.1.2 + resolution: "duplexer@npm:0.1.2" + checksum: 10c0/c57bcd4bdf7e623abab2df43a7b5b23d18152154529d166c1e0da6bee341d84c432d157d7e97b32fecb1bf3a8b8857dd85ed81a915789f550637ed25b8e64fc2 + languageName: node + linkType: hard + "duplexify@npm:^4.1.3": version: 4.1.3 resolution: "duplexify@npm:4.1.3" @@ -8890,6 +11415,16 @@ __metadata: languageName: node linkType: hard +"encoding-sniffer@npm:^0.2.1": + version: 0.2.1 + resolution: "encoding-sniffer@npm:0.2.1" + dependencies: + iconv-lite: "npm:^0.6.3" + whatwg-encoding: "npm:^3.1.1" + checksum: 10c0/d6b591880788f3baf8dd1744636dd189d24a1ec93e6f9817267c60ac3458a5191ca70ab1a186fb67731beff1c3489c6527dfdc4718158ed8460ab2f400dd5e7d + languageName: node + linkType: hard + "encoding@npm:^0.1.13": version: 0.1.13 resolution: "encoding@npm:0.1.13" @@ -8918,6 +11453,16 @@ __metadata: languageName: node linkType: hard +"enhanced-resolve@npm:^5.19.0, enhanced-resolve@npm:^5.20.0, enhanced-resolve@npm:^5.7.0": + version: 5.20.1 + resolution: "enhanced-resolve@npm:5.20.1" + dependencies: + graceful-fs: "npm:^4.2.4" + tapable: "npm:^2.3.0" + checksum: 10c0/c6503ee1b2d725843e047e774445ecb12b779aa52db25d11ebe18d4b3adc148d3d993d2038b3d0c38ad836c9c4b3930fbc55df42f72b44785e2f94e5530eda69 + languageName: node + linkType: hard + "enquirer@npm:2.3.6": version: 2.3.6 resolution: "enquirer@npm:2.3.6" @@ -8927,6 +11472,13 @@ __metadata: languageName: node linkType: hard +"entities@npm:^2.0.0": + version: 2.2.0 + resolution: "entities@npm:2.2.0" + checksum: 10c0/7fba6af1f116300d2ba1c5673fc218af1961b20908638391b4e1e6d5850314ee2ac3ec22d741b3a8060479911c99305164aed19b6254bde75e7e6b1b2c3f3aa3 + languageName: node + linkType: hard + "entities@npm:^4.2.0": version: 4.5.0 resolution: "entities@npm:4.5.0" @@ -8996,13 +11548,20 @@ __metadata: languageName: node linkType: hard -"es-module-lexer@npm:^1.2.1": +"es-module-lexer@npm:^1.2.1, es-module-lexer@npm:^1.5.0": version: 1.7.0 resolution: "es-module-lexer@npm:1.7.0" checksum: 10c0/4c935affcbfeba7fb4533e1da10fa8568043df1e3574b869385980de9e2d475ddc36769891936dbb07036edb3c3786a8b78ccf44964cd130dedc1f2c984b6c7b languageName: node linkType: hard +"es-module-lexer@npm:^2.0.0": + version: 2.0.0 + resolution: "es-module-lexer@npm:2.0.0" + checksum: 10c0/ae78dbbd43035a4b972c46cfb6877e374ea290adfc62bc2f5a083fea242c0b2baaab25c5886af86be55f092f4a326741cb94334cd3c478c383fdc8a9ec5ff817 + languageName: node + linkType: hard + "es-object-atoms@npm:^1.0.0, es-object-atoms@npm:^1.1.1": version: 1.1.1 resolution: "es-object-atoms@npm:1.1.1" @@ -9024,6 +11583,13 @@ __metadata: languageName: node linkType: hard +"es6-shim@npm:^0.35.8": + version: 0.35.8 + resolution: "es6-shim@npm:0.35.8" + checksum: 10c0/e54e147677b9cd57c96bbc2332c3096ab861040b22daa27728204cacf9aa656d6a3eeb5367a037b276bfbe442ec866938a95b4612accf0cd24d01c209e48eaf9 + languageName: node + linkType: hard + "esbuild-wasm@npm:0.25.9": version: 0.25.9 resolution: "esbuild-wasm@npm:0.25.9" @@ -9122,6 +11688,95 @@ __metadata: languageName: node linkType: hard +"esbuild@npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0": + version: 0.27.4 + resolution: "esbuild@npm:0.27.4" + dependencies: + "@esbuild/aix-ppc64": "npm:0.27.4" + "@esbuild/android-arm": "npm:0.27.4" + "@esbuild/android-arm64": "npm:0.27.4" + "@esbuild/android-x64": "npm:0.27.4" + "@esbuild/darwin-arm64": "npm:0.27.4" + "@esbuild/darwin-x64": "npm:0.27.4" + "@esbuild/freebsd-arm64": "npm:0.27.4" + "@esbuild/freebsd-x64": "npm:0.27.4" + "@esbuild/linux-arm": "npm:0.27.4" + "@esbuild/linux-arm64": "npm:0.27.4" + "@esbuild/linux-ia32": "npm:0.27.4" + "@esbuild/linux-loong64": "npm:0.27.4" + "@esbuild/linux-mips64el": "npm:0.27.4" + "@esbuild/linux-ppc64": "npm:0.27.4" + "@esbuild/linux-riscv64": "npm:0.27.4" + "@esbuild/linux-s390x": "npm:0.27.4" + "@esbuild/linux-x64": "npm:0.27.4" + "@esbuild/netbsd-arm64": "npm:0.27.4" + "@esbuild/netbsd-x64": "npm:0.27.4" + "@esbuild/openbsd-arm64": "npm:0.27.4" + "@esbuild/openbsd-x64": "npm:0.27.4" + "@esbuild/openharmony-arm64": "npm:0.27.4" + "@esbuild/sunos-x64": "npm:0.27.4" + "@esbuild/win32-arm64": "npm:0.27.4" + "@esbuild/win32-ia32": "npm:0.27.4" + "@esbuild/win32-x64": "npm:0.27.4" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-arm64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/openharmony-arm64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 10c0/2a1c2bcccda279f2afd72a7f8259860cb4483b32453d17878e1ecb4ac416b9e7c1001e7aa0a25ba4c29c1e250a3ceaae5d8bb72a119815bc8db4e9b5f5321490 + languageName: node + linkType: hard + "esbuild@npm:^0.25.0": version: 0.25.6 resolution: "esbuild@npm:0.25.6" @@ -9250,6 +11905,18 @@ __metadata: languageName: node linkType: hard +"eslint-plugin-storybook@npm:^10.3.0": + version: 10.3.0 + resolution: "eslint-plugin-storybook@npm:10.3.0" + dependencies: + "@typescript-eslint/utils": "npm:^8.48.0" + peerDependencies: + eslint: ">=8" + storybook: ^10.3.0 + checksum: 10c0/1df055b7246c20626267d506d98c98791743c1678effdb84b751d51bffb25908c3f1e8a8106671cd93314779c130af67f4dd33bb6788ba092f7d8efdc2ddb4c2 + languageName: node + linkType: hard + "eslint-scope@npm:5.1.1": version: 5.1.1 resolution: "eslint-scope@npm:5.1.1" @@ -9296,6 +11963,13 @@ __metadata: languageName: node linkType: hard +"eslint-visitor-keys@npm:^5.0.0": + version: 5.0.1 + resolution: "eslint-visitor-keys@npm:5.0.1" + checksum: 10c0/16190bdf2cbae40a1109384c94450c526a79b0b9c3cb21e544256ed85ac48a4b84db66b74a6561d20fe6ab77447f150d711c2ad5ad74df4fcc133736bce99678 + languageName: node + linkType: hard + "eslint@npm:^9.39.1": version: 9.39.2 resolution: "eslint@npm:9.39.2" @@ -9356,7 +12030,7 @@ __metadata: languageName: node linkType: hard -"esprima@npm:^4.0.1": +"esprima@npm:^4.0.1, esprima@npm:~4.0.0": version: 4.0.1 resolution: "esprima@npm:4.0.1" bin: @@ -9412,6 +12086,21 @@ __metadata: languageName: node linkType: hard +"event-stream@npm:4.0.1": + version: 4.0.1 + resolution: "event-stream@npm:4.0.1" + dependencies: + duplexer: "npm:^0.1.1" + from: "npm:^0.1.7" + map-stream: "npm:0.0.7" + pause-stream: "npm:^0.0.11" + split: "npm:^1.0.1" + stream-combiner: "npm:^0.2.2" + through: "npm:^2.3.8" + checksum: 10c0/cedb3f7ffda81f1524b66c284b4a41bb8407246bd7fe461b89a07807d28753460596e430f1346c135a64c5ba88d2a5d0711d072379b39c2266756125877aebd5 + languageName: node + linkType: hard + "event-target-shim@npm:^5.0.0": version: 5.0.1 resolution: "event-target-shim@npm:5.0.1" @@ -9470,6 +12159,23 @@ __metadata: languageName: node linkType: hard +"execa@npm:^4.0.2": + version: 4.1.0 + resolution: "execa@npm:4.1.0" + dependencies: + cross-spawn: "npm:^7.0.0" + get-stream: "npm:^5.0.0" + human-signals: "npm:^1.1.1" + is-stream: "npm:^2.0.0" + merge-stream: "npm:^2.0.0" + npm-run-path: "npm:^4.0.0" + onetime: "npm:^5.1.0" + signal-exit: "npm:^3.0.2" + strip-final-newline: "npm:^2.0.0" + checksum: 10c0/02211601bb1c52710260edcc68fb84c3c030dc68bafc697c90ada3c52cc31375337de8c24826015b8382a58d63569ffd203b79c94fef217d65503e3e8d2c52ba + languageName: node + linkType: hard + "expand-tilde@npm:^2.0.2": version: 2.0.2 resolution: "expand-tilde@npm:2.0.2" @@ -9607,6 +12313,15 @@ __metadata: languageName: node linkType: hard +"fancy-log@npm:^2.0.0": + version: 2.0.0 + resolution: "fancy-log@npm:2.0.0" + dependencies: + color-support: "npm:^1.1.3" + checksum: 10c0/a6e116f3346756a7363eea343b551c1375d2cd2afc2a92d224feb78589b6b3cff85db9dc5d5df89792a0f7c1e17f731f52cb3d2807302f0516422be6269b95a8 + languageName: node + linkType: hard + "fast-copy@npm:^3.0.2": version: 3.0.2 resolution: "fast-copy@npm:3.0.2" @@ -9635,7 +12350,7 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:3.3.3, fast-glob@npm:^3.3.2": +"fast-glob@npm:3.3.3, fast-glob@npm:^3.3.2, fast-glob@npm:^3.3.3": version: 3.3.3 resolution: "fast-glob@npm:3.3.3" dependencies: @@ -9732,7 +12447,7 @@ __metadata: languageName: node linkType: hard -"faye-websocket@npm:^0.11.3": +"faye-websocket@npm:0.11.x, faye-websocket@npm:^0.11.3": version: 0.11.4 resolution: "faye-websocket@npm:0.11.4" dependencies: @@ -9807,6 +12522,21 @@ __metadata: languageName: node linkType: hard +"finalhandler@npm:1.1.2": + version: 1.1.2 + resolution: "finalhandler@npm:1.1.2" + dependencies: + debug: "npm:2.6.9" + encodeurl: "npm:~1.0.2" + escape-html: "npm:~1.0.3" + on-finished: "npm:~2.3.0" + parseurl: "npm:~1.3.3" + statuses: "npm:~1.5.0" + unpipe: "npm:~1.0.0" + checksum: 10c0/6a96e1f5caab085628c11d9fdceb82ba608d5e426c6913d4d918409baa271037a47f28fbba73279e8ad614f0b8fa71ea791d265e408d760793829edd8c2f4584 + languageName: node + linkType: hard + "finalhandler@npm:1.3.1": version: 1.3.1 resolution: "finalhandler@npm:1.3.1" @@ -9920,6 +12650,29 @@ __metadata: languageName: node linkType: hard +"fork-ts-checker-webpack-plugin@npm:^9.1.0": + version: 9.1.0 + resolution: "fork-ts-checker-webpack-plugin@npm:9.1.0" + dependencies: + "@babel/code-frame": "npm:^7.16.7" + chalk: "npm:^4.1.2" + chokidar: "npm:^4.0.1" + cosmiconfig: "npm:^8.2.0" + deepmerge: "npm:^4.2.2" + fs-extra: "npm:^10.0.0" + memfs: "npm:^3.4.1" + minimatch: "npm:^3.0.4" + node-abort-controller: "npm:^3.0.1" + schema-utils: "npm:^3.1.1" + semver: "npm:^7.3.5" + tapable: "npm:^2.2.1" + peerDependencies: + typescript: ">3.6.0" + webpack: ^5.11.0 + checksum: 10c0/b4acdf400862af5f57d3e159b3a444e7f9f73e9f4609d54604c3810f75f8adcea0165a8b17ee856ed3c65591d058ffd73cd08d273e289d4952844e75f6efa85d + languageName: node + linkType: hard + "form-data@npm:^2.5.5": version: 2.5.5 resolution: "form-data@npm:2.5.5" @@ -9984,6 +12737,35 @@ __metadata: languageName: node linkType: hard +"from@npm:^0.1.7": + version: 0.1.7 + resolution: "from@npm:0.1.7" + checksum: 10c0/3aab5aea8fe8e1f12a5dee7f390d46a93431ce691b6222dcd5701c5d34378e51ca59b44967da1105a0f90fcdf5d7629d963d51e7ccd79827d19693bdcfb688d4 + languageName: node + linkType: hard + +"fs-extra@npm:^10.0.0": + version: 10.1.0 + resolution: "fs-extra@npm:10.1.0" + dependencies: + graceful-fs: "npm:^4.2.0" + jsonfile: "npm:^6.0.1" + universalify: "npm:^2.0.0" + checksum: 10c0/5f579466e7109719d162a9249abbeffe7f426eb133ea486e020b89bc6d67a741134076bf439983f2eb79276ceaf6bd7b7c1e43c3fd67fe889863e69072fb0a5e + languageName: node + linkType: hard + +"fs-extra@npm:^11.1.1, fs-extra@npm:^11.3.3": + version: 11.3.4 + resolution: "fs-extra@npm:11.3.4" + dependencies: + graceful-fs: "npm:^4.2.0" + jsonfile: "npm:^6.0.1" + universalify: "npm:^2.0.0" + checksum: 10c0/e08276f767a62496ae97d711aaa692c6a478177f24a85979b6a2881c9db9c68b8c2ad5da0bcf92c0b2a474cea6e935ec245656441527958fd8372cb647087df0 + languageName: node + linkType: hard + "fs-minipass@npm:^2.0.0": version: 2.1.0 resolution: "fs-minipass@npm:2.1.0" @@ -10002,6 +12784,13 @@ __metadata: languageName: node linkType: hard +"fs-monkey@npm:^1.0.4": + version: 1.1.0 + resolution: "fs-monkey@npm:1.1.0" + checksum: 10c0/45596fe14753ae8f3fa180724106383de68c8de2836eb24d1647cacf18a6d05335402f3611d32e00234072a60d2f3371024c00cd295593bfbce35b84ff9f6a34 + languageName: node + linkType: hard + "fsevents@npm:2.3.2": version: 2.3.2 resolution: "fsevents@npm:2.3.2" @@ -10163,7 +12952,7 @@ __metadata: languageName: node linkType: hard -"get-stream@npm:^5.1.0": +"get-stream@npm:^5.0.0, get-stream@npm:^5.1.0": version: 5.2.0 resolution: "get-stream@npm:5.2.0" dependencies: @@ -10251,6 +13040,17 @@ __metadata: languageName: node linkType: hard +"glob@npm:^13.0.0": + version: 13.0.6 + resolution: "glob@npm:13.0.6" + dependencies: + minimatch: "npm:^10.2.2" + minipass: "npm:^7.1.3" + path-scurry: "npm:^2.0.2" + checksum: 10c0/269c236f11a9b50357fe7a8c6aadac667e01deb5242b19c84975628f05f4438d8ee1354bb62c5d6c10f37fd59911b54d7799730633a2786660d8c69f1d18120a + languageName: node + linkType: hard + "global-directory@npm:^4.0.1": version: 4.0.1 resolution: "global-directory@npm:4.0.1" @@ -10336,7 +13136,7 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6": +"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 @@ -10377,6 +13177,24 @@ __metadata: languageName: node linkType: hard +"handlebars@npm:^4.7.8": + version: 4.7.8 + resolution: "handlebars@npm:4.7.8" + dependencies: + minimist: "npm:^1.2.5" + neo-async: "npm:^2.6.2" + source-map: "npm:^0.6.1" + uglify-js: "npm:^3.1.4" + wordwrap: "npm:^1.0.0" + dependenciesMeta: + uglify-js: + optional: true + bin: + handlebars: bin/handlebars + checksum: 10c0/7aff423ea38a14bb379316f3857fe0df3c5d66119270944247f155ba1f08e07a92b340c58edaa00cfe985c21508870ee5183e0634dcb53dd405f35c93ef7f10d + languageName: node + linkType: hard + "has-flag@npm:^4.0.0": version: 4.0.0 resolution: "has-flag@npm:4.0.0" @@ -10409,6 +13227,15 @@ __metadata: languageName: node linkType: hard +"he@npm:^1.2.0": + version: 1.2.0 + resolution: "he@npm:1.2.0" + bin: + he: bin/he + checksum: 10c0/a27d478befe3c8192f006cdd0639a66798979dfa6e2125c6ac582a19a5ebfec62ad83e8382e6036170d873f46e4536a7e795bf8b95bf7c247f4cc0825ccc8c17 + languageName: node + linkType: hard + "help-me@npm:^5.0.0": version: 5.0.0 resolution: "help-me@npm:5.0.0" @@ -10455,13 +13282,51 @@ __metadata: languageName: node linkType: hard -"html-entities@npm:^2.5.2": +"html-entities@npm:^2.1.0, html-entities@npm:^2.5.2, html-entities@npm:^2.6.0": version: 2.6.0 resolution: "html-entities@npm:2.6.0" checksum: 10c0/7c8b15d9ea0cd00dc9279f61bab002ba6ca8a7a0f3c36ed2db3530a67a9621c017830d1d2c1c65beb9b8e3436ea663e9cf8b230472e0e413359399413b27c8b7 languageName: node linkType: hard +"html-minifier-terser@npm:^6.0.2": + version: 6.1.0 + resolution: "html-minifier-terser@npm:6.1.0" + dependencies: + camel-case: "npm:^4.1.2" + clean-css: "npm:^5.2.2" + commander: "npm:^8.3.0" + he: "npm:^1.2.0" + param-case: "npm:^3.0.4" + relateurl: "npm:^0.2.7" + terser: "npm:^5.10.0" + bin: + html-minifier-terser: cli.js + checksum: 10c0/1aa4e4f01cf7149e3ac5ea84fb7a1adab86da40d38d77a6fff42852b5ee3daccb78b615df97264e3a6a5c33e57f0c77f471d607ca1e1debd1dab9b58286f4b5a + languageName: node + linkType: hard + +"html-webpack-plugin@npm:^5.5.0": + version: 5.6.6 + resolution: "html-webpack-plugin@npm:5.6.6" + dependencies: + "@types/html-minifier-terser": "npm:^6.0.0" + html-minifier-terser: "npm:^6.0.2" + lodash: "npm:^4.17.21" + pretty-error: "npm:^4.0.0" + tapable: "npm:^2.0.0" + peerDependencies: + "@rspack/core": 0.x || 1.x + webpack: ^5.20.0 + peerDependenciesMeta: + "@rspack/core": + optional: true + webpack: + optional: true + checksum: 10c0/30c07c46c6125d51f9779e4fc3dd1bf30ebd0ef78e9628d918f8e4c45e116e79a31ca5ba3444d2743833335405616b8772a68d6183b0663f016529802422ca9e + languageName: node + linkType: hard + "htmlparser2@npm:^10.0.0": version: 10.0.0 resolution: "htmlparser2@npm:10.0.0" @@ -10474,6 +13339,37 @@ __metadata: languageName: node linkType: hard +"htmlparser2@npm:^6.1.0": + version: 6.1.0 + resolution: "htmlparser2@npm:6.1.0" + dependencies: + domelementtype: "npm:^2.0.1" + domhandler: "npm:^4.0.0" + domutils: "npm:^2.5.2" + entities: "npm:^2.0.0" + checksum: 10c0/3058499c95634f04dc66be8c2e0927cd86799413b2d6989d8ae542ca4dbf5fa948695d02c27d573acf44843af977aec6d9a7bdd0f6faa6b2d99e2a729b2a31b6 + languageName: node + linkType: hard + +"http-auth-connect@npm:^1.0.5": + version: 1.0.6 + resolution: "http-auth-connect@npm:1.0.6" + checksum: 10c0/167aa1c3109f495990a59a004e66eafcbbe8ec8d7b6df83fba6033196af4327b9c3df99c91eaaedf4b38f3d85044ececfb955b0ce92cbd10bb6492a91beb54d2 + languageName: node + linkType: hard + +"http-auth@npm:4.1.9": + version: 4.1.9 + resolution: "http-auth@npm:4.1.9" + dependencies: + apache-crypt: "npm:^1.1.2" + apache-md5: "npm:^1.0.6" + bcryptjs: "npm:^2.4.3" + uuid: "npm:^8.3.2" + checksum: 10c0/d13ee4ce0ac063597634a27f59840091c8b24030d576dd2a81d93ac10dc2797a780a3f59fa4f3fde65448ef215ee702984322a733d3da1dc4341be28b2b8658b + languageName: node + linkType: hard + "http-cache-semantics@npm:^4.0.0, http-cache-semantics@npm:^4.1.1": version: 4.2.0 resolution: "http-cache-semantics@npm:4.2.0" @@ -10514,7 +13410,7 @@ __metadata: languageName: node linkType: hard -"http-errors@npm:^2.0.0, http-errors@npm:~2.0.1": +"http-errors@npm:^2.0.0, http-errors@npm:^2.0.1, http-errors@npm:~2.0.1": version: 2.0.1 resolution: "http-errors@npm:2.0.1" dependencies: @@ -10640,6 +13536,13 @@ __metadata: languageName: node linkType: hard +"human-signals@npm:^1.1.1": + version: 1.1.1 + resolution: "human-signals@npm:1.1.1" + checksum: 10c0/18810ed239a7a5e23fb6c32d0fd4be75d7cd337a07ad59b8dbf0794cb0761e6e628349ee04c409e605fe55344716eab5d0a47a62ba2a2d0d367c89a2b4247b1e + languageName: node + linkType: hard + "husky@npm:^9.1.7": version: 9.1.7 resolution: "husky@npm:9.1.7" @@ -10656,6 +13559,20 @@ __metadata: languageName: node linkType: hard +"i18next@npm:25.7.4": + version: 25.7.4 + resolution: "i18next@npm:25.7.4" + dependencies: + "@babel/runtime": "npm:^7.28.4" + peerDependencies: + typescript: ^5 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/d30e4f9a1c31adc0570c9f4a22ab226257620f2465e2275f8cdd5ef7f52668716cc9be3b741031aeacb39e2196be5a5f656e12d89787b4248098f681e99f72ea + languageName: node + linkType: hard + "iconv-lite@npm:0.4.24, iconv-lite@npm:^0.4.4": version: 0.4.24 resolution: "iconv-lite@npm:0.4.24" @@ -10665,7 +13582,7 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": +"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": version: 0.6.3 resolution: "iconv-lite@npm:0.6.3" dependencies: @@ -10846,7 +13763,7 @@ __metadata: languageName: node linkType: hard -"is-docker@npm:^2.0.0": +"is-docker@npm:^2.0.0, is-docker@npm:^2.1.1": version: 2.2.1 resolution: "is-docker@npm:2.2.1" bin: @@ -11009,7 +13926,7 @@ __metadata: languageName: node linkType: hard -"is-wsl@npm:^2.1.1": +"is-wsl@npm:^2.1.1, is-wsl@npm:^2.2.0": version: 2.2.0 resolution: "is-wsl@npm:2.2.0" dependencies: @@ -11113,7 +14030,16 @@ __metadata: resolution: "jiti@npm:2.5.1" bin: jiti: lib/jiti-cli.mjs - checksum: 10c0/f0a38d7d8842cb35ffe883038166aa2d52ffd21f1a4fc839ae4076ea7301c22a1f11373f8fc52e2667de7acde8f3e092835620dd6f72a0fbe9296b268b0874bb + checksum: 10c0/f0a38d7d8842cb35ffe883038166aa2d52ffd21f1a4fc839ae4076ea7301c22a1f11373f8fc52e2667de7acde8f3e092835620dd6f72a0fbe9296b268b0874bb + languageName: node + linkType: hard + +"jiti@npm:^2.5.1, jiti@npm:^2.6.1": + version: 2.6.1 + resolution: "jiti@npm:2.6.1" + bin: + jiti: lib/jiti-cli.mjs + checksum: 10c0/79b2e96a8e623f66c1b703b98ec1b8be4500e1d217e09b09e343471bbb9c105381b83edbb979d01cef18318cc45ce6e153571b6c83122170eefa531c64b6789b languageName: node linkType: hard @@ -11201,7 +14127,7 @@ __metadata: languageName: node linkType: hard -"jsesc@npm:^3.0.2": +"jsesc@npm:^3.0.2, jsesc@npm:~3.1.0": version: 3.1.0 resolution: "jsesc@npm:3.1.0" bin: @@ -11277,7 +14203,7 @@ __metadata: languageName: node linkType: hard -"json5@npm:^2.1.2, json5@npm:^2.2.3": +"json5@npm:^2.1.2, json5@npm:^2.2.2, json5@npm:^2.2.3": version: 2.2.3 resolution: "json5@npm:2.2.3" bin: @@ -11293,6 +14219,19 @@ __metadata: languageName: node linkType: hard +"jsonfile@npm:^6.0.1": + version: 6.2.0 + resolution: "jsonfile@npm:6.2.0" + dependencies: + graceful-fs: "npm:^4.1.6" + universalify: "npm:^2.0.0" + dependenciesMeta: + graceful-fs: + optional: true + checksum: 10c0/7f4f43b08d1869ded8a6822213d13ae3b99d651151d77efd1557ced0889c466296a7d9684e397bd126acf5eb2cfcb605808c3e681d0fdccd2fe5a04b47e76c0d + languageName: node + linkType: hard + "jsonparse@npm:^1.2.0, jsonparse@npm:^1.3.1": version: 1.3.1 resolution: "jsonparse@npm:1.3.1" @@ -11567,12 +14506,66 @@ __metadata: husky: "npm:^9.1.7" lint-staged: "npm:^16.2.7" prettier: "npm:^3.7.4" + prettier-plugin-organize-imports: "npm:^4.2.0" + prettier-plugin-tailwindcss: "npm:^0.6.14" tslib: "npm:^2.8.1" turbo: "npm:^2.6.3" typescript: "npm:5.8.3" languageName: unknown linkType: soft +"lfx@workspace:apps/lfx": + version: 0.0.0-use.local + resolution: "lfx@workspace:apps/lfx" + dependencies: + "@angular-devkit/build-angular": "npm:^20.3.13" + "@angular-eslint/builder": "npm:21.0.1" + "@angular/build": "npm:^20.3.13" + "@angular/cli": "npm:^20.3.13" + "@angular/common": "npm:^20.3.15" + "@angular/compiler": "npm:^20.3.15" + "@angular/compiler-cli": "npm:^20.3.15" + "@angular/core": "npm:^20.3.15" + "@angular/forms": "npm:^20.3.15" + "@angular/platform-browser": "npm:^20.3.15" + "@angular/platform-browser-dynamic": "npm:^20.3.15" + "@angular/platform-server": "npm:^20.3.15" + "@angular/router": "npm:^20.3.15" + "@angular/ssr": "npm:^20.3.13" + "@compodoc/compodoc": "npm:^1.2.1" + "@eslint/js": "npm:^9.39.1" + "@lfx-one/shared": "workspace:*" + "@storybook/addon-docs": "npm:^10.3.0" + "@storybook/angular": "npm:^10.3.0" + "@tailwindcss/postcss": "npm:^4.0.0" + "@types/compression": "npm:1.8.1" + "@types/express": "npm:^4.17.17" + "@types/node": "npm:^18.18.0" + angular-eslint: "npm:21.0.1" + compression: "npm:^1.8.1" + dotenv: "npm:^17.2.3" + eslint: "npm:^9.39.1" + eslint-plugin-storybook: "npm:^10.3.0" + express: "npm:^4.18.2" + express-openid-connect: "npm:^2.19.2" + pino: "npm:^10.3.0" + pino-http: "npm:^11.0.0" + pino-pretty: "npm:^13.1.1" + postcss: "npm:^8.5.6" + postcss-loader: "npm:^8.1.1" + prettier: "npm:^3.7.4" + prettier-plugin-organize-imports: "npm:^4.2.0" + prettier-plugin-tailwindcss: "npm:^0.6.14" + rxjs: "npm:~7.8.2" + storybook: "npm:^10.3.0" + style-loader: "npm:^4.0.0" + tailwindcss: "npm:^4.0.0" + tslib: "npm:^2.8.1" + typescript: "npm:~5.9.3" + typescript-eslint: "npm:8.46.4" + languageName: unknown + linkType: soft + "license-webpack-plugin@npm:4.0.2": version: 4.0.2 resolution: "license-webpack-plugin@npm:4.0.2" @@ -11587,6 +14580,126 @@ __metadata: languageName: node linkType: hard +"lightningcss-android-arm64@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-android-arm64@npm:1.32.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"lightningcss-darwin-arm64@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-darwin-arm64@npm:1.32.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"lightningcss-darwin-x64@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-darwin-x64@npm:1.32.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"lightningcss-freebsd-x64@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-freebsd-x64@npm:1.32.0" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"lightningcss-linux-arm-gnueabihf@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-linux-arm-gnueabihf@npm:1.32.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"lightningcss-linux-arm64-gnu@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-linux-arm64-gnu@npm:1.32.0" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"lightningcss-linux-arm64-musl@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-linux-arm64-musl@npm:1.32.0" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"lightningcss-linux-x64-gnu@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-linux-x64-gnu@npm:1.32.0" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"lightningcss-linux-x64-musl@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-linux-x64-musl@npm:1.32.0" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"lightningcss-win32-arm64-msvc@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-win32-arm64-msvc@npm:1.32.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"lightningcss-win32-x64-msvc@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss-win32-x64-msvc@npm:1.32.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"lightningcss@npm:1.32.0": + version: 1.32.0 + resolution: "lightningcss@npm:1.32.0" + dependencies: + detect-libc: "npm:^2.0.3" + lightningcss-android-arm64: "npm:1.32.0" + lightningcss-darwin-arm64: "npm:1.32.0" + lightningcss-darwin-x64: "npm:1.32.0" + lightningcss-freebsd-x64: "npm:1.32.0" + lightningcss-linux-arm-gnueabihf: "npm:1.32.0" + lightningcss-linux-arm64-gnu: "npm:1.32.0" + lightningcss-linux-arm64-musl: "npm:1.32.0" + lightningcss-linux-x64-gnu: "npm:1.32.0" + lightningcss-linux-x64-musl: "npm:1.32.0" + lightningcss-win32-arm64-msvc: "npm:1.32.0" + lightningcss-win32-x64-msvc: "npm:1.32.0" + dependenciesMeta: + lightningcss-android-arm64: + optional: true + lightningcss-darwin-arm64: + optional: true + lightningcss-darwin-x64: + optional: true + lightningcss-freebsd-x64: + optional: true + lightningcss-linux-arm-gnueabihf: + optional: true + lightningcss-linux-arm64-gnu: + optional: true + lightningcss-linux-arm64-musl: + optional: true + lightningcss-linux-x64-gnu: + optional: true + lightningcss-linux-x64-musl: + optional: true + lightningcss-win32-arm64-msvc: + optional: true + lightningcss-win32-x64-msvc: + optional: true + checksum: 10c0/70945bd55097af46fc9fab7f5ed09cd5869d85940a2acab7ee06d0117004a1d68155708a2d462531cea2fc3c67aefc9333a7068c80b0b78dd404c16838809e03 + languageName: node + linkType: hard + "lilconfig@npm:^3.0.0, lilconfig@npm:^3.1.3": version: 3.1.3 resolution: "lilconfig@npm:3.1.3" @@ -11691,6 +14804,13 @@ __metadata: languageName: node linkType: hard +"loader-runner@npm:^4.3.1": + version: 4.3.1 + resolution: "loader-runner@npm:4.3.1" + checksum: 10c0/a523b6329f114e0a98317158e30a7dfce044b731521be5399464010472a93a15ece44757d1eaed1d8845019869c5390218bc1c7c3110f4eeaef5157394486eac + languageName: node + linkType: hard + "loader-utils@npm:3.3.1": version: 3.3.1 resolution: "loader-utils@npm:3.3.1" @@ -11874,6 +14994,13 @@ __metadata: languageName: node linkType: hard +"lodash@npm:^4.17.20, lodash@npm:^4.17.21": + version: 4.17.23 + resolution: "lodash@npm:4.17.23" + checksum: 10c0/1264a90469f5bb95d4739c43eb6277d15b6d9e186df4ac68c3620443160fc669e2f14c11e7d8b2ccf078b81d06147c01a8ccced9aab9f9f63d50dcf8cace6bf6 + languageName: node + linkType: hard + "log-symbols@npm:^6.0.0": version: 6.0.0 resolution: "log-symbols@npm:6.0.0" @@ -11921,6 +15048,36 @@ __metadata: languageName: node linkType: hard +"loglevel-plugin-prefix@npm:^0.8.4": + version: 0.8.4 + resolution: "loglevel-plugin-prefix@npm:0.8.4" + checksum: 10c0/357524eec4c165ff823b5bbf72e8373ff529e5cb95c1f4b20749847bd5b5b16ab328d6d33d1a9019f1a2dc52e28fca5d595e52f2ee20e24986182a6f9552a9ec + languageName: node + linkType: hard + +"loglevel@npm:^1.9.2": + version: 1.9.2 + resolution: "loglevel@npm:1.9.2" + checksum: 10c0/1e317fa4648fe0b4a4cffef6de037340592cee8547b07d4ce97a487abe9153e704b98451100c799b032c72bb89c9366d71c9fb8192ada8703269263ae77acdc7 + languageName: node + linkType: hard + +"loupe@npm:^3.1.0, loupe@npm:^3.1.4": + version: 3.2.1 + resolution: "loupe@npm:3.2.1" + checksum: 10c0/910c872cba291309664c2d094368d31a68907b6f5913e989d301b5c25f30e97d76d77f23ab3bf3b46d0f601ff0b6af8810c10c31b91d2c6b2f132809ca2cc705 + languageName: node + linkType: hard + +"lower-case@npm:^2.0.2": + version: 2.0.2 + resolution: "lower-case@npm:2.0.2" + dependencies: + tslib: "npm:^2.0.3" + checksum: 10c0/3d925e090315cf7dc1caa358e0477e186ffa23947740e4314a7429b6e62d72742e0bbe7536a5ae56d19d7618ce998aba05caca53c2902bd5742fdca5fc57fd7b + languageName: node + linkType: hard + "lowercase-keys@npm:^2.0.0": version: 2.0.0 resolution: "lowercase-keys@npm:2.0.0" @@ -11935,6 +15092,13 @@ __metadata: languageName: node linkType: hard +"lru-cache@npm:^11.0.0": + version: 11.2.7 + resolution: "lru-cache@npm:11.2.7" + checksum: 10c0/549cdb59488baa617135fc12159cafb1a97f91079f35093bb3bcad72e849fc64ace636d244212c181dfdf1a99bbfa90757ff303f98561958ee4d0f885d9bd5f7 + languageName: node + linkType: hard + "lru-cache@npm:^11.1.0": version: 11.2.4 resolution: "lru-cache@npm:11.2.4" @@ -11967,6 +15131,20 @@ __metadata: languageName: node linkType: hard +"lunr@npm:^2.3.9": + version: 2.3.9 + resolution: "lunr@npm:2.3.9" + checksum: 10c0/77d7dbb4fbd602aac161e2b50887d8eda28c0fa3b799159cee380fbb311f1e614219126ecbbd2c3a9c685f1720a8109b3c1ca85cc893c39b6c9cc6a62a1d8a8b + languageName: node + linkType: hard + +"macos-release@npm:^2.5.0": + version: 2.5.1 + resolution: "macos-release@npm:2.5.1" + checksum: 10c0/fd03674e0b91e88a82cabecb75d75bc562863b186a22eac857f7d90c117486e44e02bede0926315637749aaaa934415bd1c2d0c0b53b78a86b729f3c165c5850 + languageName: node + linkType: hard + "magic-string@npm:0.30.17": version: 0.30.17 resolution: "magic-string@npm:0.30.17" @@ -11976,7 +15154,7 @@ __metadata: languageName: node linkType: hard -"magic-string@npm:0.30.21": +"magic-string@npm:0.30.21, magic-string@npm:^0.30.21, magic-string@npm:^0.30.5": version: 0.30.21 resolution: "magic-string@npm:0.30.21" dependencies: @@ -12021,6 +15199,22 @@ __metadata: languageName: node linkType: hard +"map-stream@npm:0.0.7": + version: 0.0.7 + resolution: "map-stream@npm:0.0.7" + checksum: 10c0/77da244656dad5013bd147b0eef6f0343a212f14761332b97364fe348d4d70f0b8a0903457d6fc88772ec7c3d4d048b24f8db3aa5c0f77a8ce8bf2391473b8ec + languageName: node + linkType: hard + +"marked@npm:7.0.3": + version: 7.0.3 + resolution: "marked@npm:7.0.3" + bin: + marked: bin/marked.js + checksum: 10c0/0d57c2a320feff963f20877c3b9ab3dc609ed7810ddb6cd8c1f8cf6a5fc29556018fdb4f356f872f4daae7cba4a5d9966f0d7af0099037214e092c75bd6aa5ff + languageName: node + linkType: hard + "marked@npm:^17.0.4": version: 17.0.4 resolution: "marked@npm:17.0.4" @@ -12030,6 +15224,15 @@ __metadata: languageName: node linkType: hard +"matchit@npm:^1.0.0": + version: 1.1.0 + resolution: "matchit@npm:1.1.0" + dependencies: + "@arr/every": "npm:^1.0.0" + checksum: 10c0/f2cd8702ea37dd9859cf1df762581c822180eb72372b9240397a80320cb4ffb4828b3d8ed0beff2429daf500d1ec746c2963dbb3c6386f1b5b9eb969e0f1caaa + languageName: node + linkType: hard + "math-intrinsics@npm:^1.1.0": version: 1.1.0 resolution: "math-intrinsics@npm:1.1.0" @@ -12051,6 +15254,15 @@ __metadata: languageName: node linkType: hard +"memfs@npm:^3.4.1, memfs@npm:^3.4.12": + version: 3.5.3 + resolution: "memfs@npm:3.5.3" + dependencies: + fs-monkey: "npm:^1.0.4" + checksum: 10c0/038fc81bce17ea92dde15aaa68fa0fdaf4960c721ce3ffc7c2cb87a259333f5159784ea48b3b72bf9e054254d9d0d0d5209d0fdc3d07d08653a09933b168fbd7 + languageName: node + linkType: hard + "memfs@npm:^4.6.0": version: 4.17.2 resolution: "memfs@npm:4.17.2" @@ -12138,7 +15350,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:^3.0.0, mime-types@npm:^3.0.1": +"mime-types@npm:^3.0.0, mime-types@npm:^3.0.1, mime-types@npm:^3.0.2": version: 3.0.2 resolution: "mime-types@npm:3.0.2" dependencies: @@ -12165,6 +15377,13 @@ __metadata: languageName: node linkType: hard +"mimic-fn@npm:^2.1.0": + version: 2.1.0 + resolution: "mimic-fn@npm:2.1.0" + checksum: 10c0/b26f5479d7ec6cc2bce275a08f146cf78f5e7b661b18114e2506dd91ec7ec47e7a25bf4360e5438094db0560bcc868079fb3b1fb3892b833c1ecbf63f80c95a4 + languageName: node + linkType: hard + "mimic-function@npm:^5.0.0": version: 5.0.1 resolution: "mimic-function@npm:5.0.1" @@ -12186,6 +15405,13 @@ __metadata: languageName: node linkType: hard +"min-indent@npm:^1.0.0": + version: 1.0.1 + resolution: "min-indent@npm:1.0.1" + checksum: 10c0/7e207bd5c20401b292de291f02913230cb1163abca162044f7db1d951fa245b174dc00869d40dd9a9f32a885ad6a5f3e767ee104cf278f399cb4e92d3f582d5c + languageName: node + linkType: hard + "mini-css-extract-plugin@npm:2.9.4": version: 2.9.4 resolution: "mini-css-extract-plugin@npm:2.9.4" @@ -12205,6 +15431,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:^10.0.1, minimatch@npm:^10.2.2": + version: 10.2.4 + resolution: "minimatch@npm:10.2.4" + dependencies: + brace-expansion: "npm:^5.0.2" + checksum: 10c0/35f3dfb7b99b51efd46afd378486889f590e7efb10e0f6a10ba6800428cf65c9a8dedb74427d0570b318d749b543dc4e85f06d46d2858bc8cac7e1eb49a95945 + languageName: node + linkType: hard + "minimatch@npm:^10.0.3": version: 10.1.1 resolution: "minimatch@npm:10.1.1" @@ -12214,6 +15449,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:^3.0.4": + version: 3.1.5 + resolution: "minimatch@npm:3.1.5" + dependencies: + brace-expansion: "npm:^1.1.7" + checksum: 10c0/2ecbdc0d33f07bddb0315a8b5afbcb761307a8778b48f0b312418ccbced99f104a2d17d8aca7573433c70e8ccd1c56823a441897a45e384ea76ef401a26ace70 + languageName: node + linkType: hard + "minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" @@ -12232,7 +15476,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.2.6, minimist@npm:^1.2.8": +"minimist@npm:^1.2.5, minimist@npm:^1.2.6, minimist@npm:^1.2.8": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 10c0/19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6 @@ -12313,6 +15557,13 @@ __metadata: languageName: node linkType: hard +"minipass@npm:^7.1.3": + version: 7.1.3 + resolution: "minipass@npm:7.1.3" + checksum: 10c0/539da88daca16533211ea5a9ee98dc62ff5742f531f54640dd34429e621955e91cc280a91a776026264b7f9f6735947629f920944e9c1558369e8bf22eb33fbb + languageName: node + linkType: hard + "minizlib@npm:^2.1.1": version: 2.1.2 resolution: "minizlib@npm:2.1.2" @@ -12373,7 +15624,20 @@ __metadata: languageName: node linkType: hard -"mrmime@npm:2.0.1": +"morgan@npm:^1.10.0": + version: 1.10.1 + resolution: "morgan@npm:1.10.1" + dependencies: + basic-auth: "npm:~2.0.1" + debug: "npm:2.6.9" + depd: "npm:~2.0.0" + on-finished: "npm:~2.3.0" + on-headers: "npm:~1.1.0" + checksum: 10c0/2ecd68504d29151b516a6233839e4f27ae0312acc4dbcb1fe84ff9b5db0eb9b25f31258a931dcf689184b4858839572095fcc62eef3cbd7339287d59f1424346 + languageName: node + linkType: hard + +"mrmime@npm:2.0.1, mrmime@npm:^2.0.0": version: 2.0.1 resolution: "mrmime@npm:2.0.1" checksum: 10c0/af05afd95af202fdd620422f976ad67dc18e6ee29beb03dd1ce950ea6ef664de378e44197246df4c7cdd73d47f2e7143a6e26e473084b9e4aa2095c0ad1e1761 @@ -12559,6 +15823,13 @@ __metadata: languageName: node linkType: hard +"neotraverse@npm:^0.6.18": + version: 0.6.18 + resolution: "neotraverse@npm:0.6.18" + checksum: 10c0/46f4c53cbbdc53671150916b544a9f46e27781f8003985237507542190173bec131168d89b846535f9c34c0a2a7debb1ab3a4f7a93d08218e2c194a363708ffa + languageName: node + linkType: hard + "netmask@npm:^2.0.2": version: 2.0.2 resolution: "netmask@npm:2.0.2" @@ -12588,6 +15859,23 @@ __metadata: languageName: node linkType: hard +"no-case@npm:^3.0.4": + version: 3.0.4 + resolution: "no-case@npm:3.0.4" + dependencies: + lower-case: "npm:^2.0.2" + tslib: "npm:^2.0.3" + checksum: 10c0/8ef545f0b3f8677c848f86ecbd42ca0ff3cd9dd71c158527b344c69ba14710d816d8489c746b6ca225e7b615108938a0bda0a54706f8c255933703ac1cf8e703 + languageName: node + linkType: hard + +"node-abort-controller@npm:^3.0.1": + version: 3.1.1 + resolution: "node-abort-controller@npm:3.1.1" + checksum: 10c0/f7ad0e7a8e33809d4f3a0d1d65036a711c39e9d23e0319d80ebe076b9a3b4432b4d6b86a7fab65521de3f6872ffed36fc35d1327487c48eb88c517803403eda3 + languageName: node + linkType: hard + "node-addon-api@npm:^6.1.0": version: 6.1.0 resolution: "node-addon-api@npm:6.1.0" @@ -12811,7 +16099,16 @@ __metadata: languageName: node linkType: hard -"nth-check@npm:^2.1.1": +"npm-run-path@npm:^4.0.0": + version: 4.0.1 + resolution: "npm-run-path@npm:4.0.1" + dependencies: + path-key: "npm:^3.0.0" + checksum: 10c0/6f9353a95288f8455cf64cbeb707b28826a7f29690244c1e4bb61ec573256e021b6ad6651b394eb1ccfd00d6ec50147253aba2c5fe58a57ceb111fad62c519ac + languageName: node + linkType: hard + +"nth-check@npm:^2.0.1, nth-check@npm:^2.1.1": version: 2.1.1 resolution: "nth-check@npm:2.1.1" dependencies: @@ -12827,7 +16124,7 @@ __metadata: languageName: node linkType: hard -"object-assign@npm:^4, object-assign@npm:^4.0.1": +"object-assign@npm:^4, object-assign@npm:^4.0.1, object-assign@npm:latest": version: 4.1.1 resolution: "object-assign@npm:4.1.1" checksum: 10c0/1f4df9945120325d041ccf7b86f31e8bcc14e73d29171e37a7903050e96b81323784ec59f93f102ec635bcf6fa8034ba3ea0a8c7e69fa202b87ae3b6cec5a414 @@ -12885,6 +16182,15 @@ __metadata: languageName: node linkType: hard +"on-finished@npm:~2.3.0": + version: 2.3.0 + resolution: "on-finished@npm:2.3.0" + dependencies: + ee-first: "npm:1.1.1" + checksum: 10c0/c904f9e518b11941eb60279a3cbfaf1289bd0001f600a950255b1dede9fe3df8cd74f38483550b3bb9485165166acb5db500c3b4c4337aec2815c88c96fcc2ea + languageName: node + linkType: hard + "on-headers@npm:^1.1.0, on-headers@npm:~1.1.0": version: 1.1.0 resolution: "on-headers@npm:1.1.0" @@ -12910,6 +16216,15 @@ __metadata: languageName: node linkType: hard +"onetime@npm:^5.1.0": + version: 5.1.2 + resolution: "onetime@npm:5.1.2" + dependencies: + mimic-fn: "npm:^2.1.0" + checksum: 10c0/ffcef6fbb2692c3c40749f31ea2e22677a876daea92959b8a80b521d95cca7a668c884d8b2045d1d8ee7d56796aa405c405462af112a1477594cc63531baeb8f + languageName: node + linkType: hard + "onetime@npm:^7.0.0": version: 7.0.0 resolution: "onetime@npm:7.0.0" @@ -12919,7 +16234,7 @@ __metadata: languageName: node linkType: hard -"open@npm:10.2.0, open@npm:^10.0.3, open@npm:^10.1.0": +"open@npm:10.2.0, open@npm:^10.0.3, open@npm:^10.1.0, open@npm:^10.2.0": version: 10.2.0 resolution: "open@npm:10.2.0" dependencies: @@ -12931,6 +16246,17 @@ __metadata: languageName: node linkType: hard +"open@npm:8.4.0": + version: 8.4.0 + resolution: "open@npm:8.4.0" + dependencies: + define-lazy-prop: "npm:^2.0.0" + is-docker: "npm:^2.1.1" + is-wsl: "npm:^2.2.0" + checksum: 10c0/585596580226cbeb7262f36b5acc7eed05211dc26980020a2527f829336b8b07fd79cdc4240f4d995b5615f635e0a59ebb0261c4419fef91edd5d4604c463f18 + languageName: node + linkType: hard + "open@npm:^7.3.1": version: 7.4.2 resolution: "open@npm:7.4.2" @@ -12941,6 +16267,15 @@ __metadata: languageName: node linkType: hard +"opencollective-postinstall@npm:^2.0.3": + version: 2.0.3 + resolution: "opencollective-postinstall@npm:2.0.3" + bin: + opencollective-postinstall: index.js + checksum: 10c0/8a0104a218bc1afaae943f0af378461eeb2836f9848bad872bbd067ec5d1d9791636f307454ab77d0746f10341366f295384656a340ebdb87a2585058e8567e5 + languageName: node + linkType: hard + "openid-client@npm:^4.9.1": version: 4.9.1 resolution: "openid-client@npm:4.9.1" @@ -13011,6 +16346,16 @@ __metadata: languageName: node linkType: hard +"os-name@npm:4.0.1": + version: 4.0.1 + resolution: "os-name@npm:4.0.1" + dependencies: + macos-release: "npm:^2.5.0" + windows-release: "npm:^4.0.0" + checksum: 10c0/2a78bb1a25afa04ec53a972ed164948432fee93d9e039afaec3a27ffe30473ffc85afb03c0776ca3e01c8d806f99f61cb85ad3fbc060bc3e37a549c0a4867f3f + languageName: node + linkType: hard + "p-cancelable@npm:^2.0.0": version: 2.1.1 resolution: "p-cancelable@npm:2.1.1" @@ -13139,6 +16484,16 @@ __metadata: languageName: node linkType: hard +"param-case@npm:^3.0.4": + version: 3.0.4 + resolution: "param-case@npm:3.0.4" + dependencies: + dot-case: "npm:^3.0.4" + tslib: "npm:^2.0.3" + checksum: 10c0/ccc053f3019f878eca10e70ec546d92f51a592f762917dafab11c8b532715dcff58356118a6f350976e4ab109e321756f05739643ed0ca94298e82291e6f9e76 + languageName: node + linkType: hard + "parchment@npm:^3.0.0": version: 3.0.0 resolution: "parchment@npm:3.0.0" @@ -13192,6 +16547,25 @@ __metadata: languageName: node linkType: hard +"parse5-htmlparser2-tree-adapter@npm:^7.1.0": + version: 7.1.0 + resolution: "parse5-htmlparser2-tree-adapter@npm:7.1.0" + dependencies: + domhandler: "npm:^5.0.3" + parse5: "npm:^7.0.0" + checksum: 10c0/e5a4e0b834c84c9e244b5749f8d007f4baaeafac7a1da2c54be3421ffd9ef8fdec4f198bf55cda22e88e6ba95e9943f6ed5aa3ae5900b39972ebf5dc8c3f4722 + languageName: node + linkType: hard + +"parse5-parser-stream@npm:^7.1.2": + version: 7.1.2 + resolution: "parse5-parser-stream@npm:7.1.2" + dependencies: + parse5: "npm:^7.0.0" + checksum: 10c0/e236c61000d38ecad369e725a48506b051cebad8abb00e6d4e8bff7aa85c183820fcb45db1559cc90955bdbbdbd665ea94c41259594e74566fff411478dc7fcb + languageName: node + linkType: hard + "parse5-sax-parser@npm:^8.0.0": version: 8.0.0 resolution: "parse5-sax-parser@npm:8.0.0" @@ -13201,6 +16575,15 @@ __metadata: languageName: node linkType: hard +"parse5@npm:^7.0.0, parse5@npm:^7.3.0": + version: 7.3.0 + resolution: "parse5@npm:7.3.0" + dependencies: + entities: "npm:^6.0.0" + checksum: 10c0/7fd2e4e247e85241d6f2a464d0085eed599a26d7b0a5233790c49f53473232eb85350e8133344d9b3fd58b89339e7ad7270fe1f89d28abe50674ec97b87f80b5 + languageName: node + linkType: hard + "parse5@npm:^8.0.0": version: 8.0.0 resolution: "parse5@npm:8.0.0" @@ -13217,6 +16600,23 @@ __metadata: languageName: node linkType: hard +"pascal-case@npm:^3.1.2": + version: 3.1.2 + resolution: "pascal-case@npm:3.1.2" + dependencies: + no-case: "npm:^3.0.4" + tslib: "npm:^2.0.3" + checksum: 10c0/05ff7c344809fd272fc5030ae0ee3da8e4e63f36d47a1e0a4855ca59736254192c5a27b5822ed4bae96e54048eec5f6907713cfcfff7cdf7a464eaf7490786d8 + languageName: node + linkType: hard + +"path-browserify@npm:^1.0.1": + version: 1.0.1 + resolution: "path-browserify@npm:1.0.1" + checksum: 10c0/8b8c3fd5c66bd340272180590ae4ff139769e9ab79522e2eb82e3d571a89b8117c04147f65ad066dccfb42fcad902e5b7d794b3d35e0fd840491a8ddbedf8c66 + languageName: node + linkType: hard + "path-exists@npm:^4.0.0": version: 4.0.0 resolution: "path-exists@npm:4.0.0" @@ -13231,7 +16631,7 @@ __metadata: languageName: node linkType: hard -"path-key@npm:^3.1.0": +"path-key@npm:^3.0.0, path-key@npm:^3.1.0": version: 3.1.1 resolution: "path-key@npm:3.1.1" checksum: 10c0/748c43efd5a569c039d7a00a03b58eecd1d75f3999f5a28303d75f521288df4823bc057d8784eb72358b2895a05f29a070bc9f1f17d28226cc4e62494cc58c4c @@ -13255,6 +16655,16 @@ __metadata: languageName: node linkType: hard +"path-scurry@npm:^2.0.2": + version: 2.0.2 + resolution: "path-scurry@npm:2.0.2" + dependencies: + lru-cache: "npm:^11.0.0" + minipass: "npm:^7.1.2" + checksum: 10c0/b35ad37cf6557a87fd057121ce2be7695380c9138d93e87ae928609da259ea0a170fac6f3ef1eb3ece8a068e8b7f2f3adf5bb2374cf4d4a57fe484954fcc9482 + languageName: node + linkType: hard + "path-to-regexp@npm:0.1.12": version: 0.1.12 resolution: "path-to-regexp@npm:0.1.12" @@ -13269,6 +16679,29 @@ __metadata: languageName: node linkType: hard +"path-type@npm:^4.0.0": + version: 4.0.0 + resolution: "path-type@npm:4.0.0" + checksum: 10c0/666f6973f332f27581371efaf303fd6c272cc43c2057b37aa99e3643158c7e4b2626549555d88626e99ea9e046f82f32e41bbde5f1508547e9a11b149b52387c + languageName: node + linkType: hard + +"pathval@npm:^2.0.0": + version: 2.0.1 + resolution: "pathval@npm:2.0.1" + checksum: 10c0/460f4709479fbf2c45903a65655fc8f0a5f6d808f989173aeef5fdea4ff4f303dc13f7870303999add60ec49d4c14733895c0a869392e9866f1091fa64fd7581 + languageName: node + linkType: hard + +"pause-stream@npm:^0.0.11": + version: 0.0.11 + resolution: "pause-stream@npm:0.0.11" + dependencies: + through: "npm:~2.3" + checksum: 10c0/86f12c64cdaaa8e45ebaca4e39a478e1442db8b4beabc280b545bfaf79c0e2f33c51efb554aace5c069cc441c7b924ba484837b345eaa4ba6fc940d62f826802 + languageName: node + linkType: hard + "picocolors@npm:^1.0.0, picocolors@npm:^1.1.1": version: 1.1.1 resolution: "picocolors@npm:1.1.1" @@ -13349,7 +16782,7 @@ __metadata: languageName: node linkType: hard -"pino-http@npm:11.0.0": +"pino-http@npm:11.0.0, pino-http@npm:^11.0.0": version: 11.0.0 resolution: "pino-http@npm:11.0.0" dependencies: @@ -13412,6 +16845,27 @@ __metadata: languageName: node linkType: hard +"pino@npm:^10.3.0": + version: 10.3.1 + resolution: "pino@npm:10.3.1" + dependencies: + "@pinojs/redact": "npm:^0.4.0" + atomic-sleep: "npm:^1.0.0" + on-exit-leak-free: "npm:^2.1.0" + pino-abstract-transport: "npm:^3.0.0" + pino-std-serializers: "npm:^7.0.0" + process-warning: "npm:^5.0.0" + quick-format-unescaped: "npm:^4.0.3" + real-require: "npm:^0.2.0" + safe-stable-stringify: "npm:^2.3.1" + sonic-boom: "npm:^4.0.1" + thread-stream: "npm:^4.0.0" + bin: + pino: bin.js + checksum: 10c0/ae1c57f2baac85dd5d63a3500746d5ea1cfc4bfcbf356eaec94d42a782eeb80caa4d4614de43a036cf48e2aed46d855a7ff21b126f55a63811def52a894ef937 + languageName: node + linkType: hard + "pirates@npm:^4.0.1": version: 4.0.7 resolution: "pirates@npm:4.0.7" @@ -13585,6 +17039,16 @@ __metadata: languageName: node linkType: hard +"polka@npm:^0.5.2": + version: 0.5.2 + resolution: "polka@npm:0.5.2" + dependencies: + "@polka/url": "npm:^0.5.0" + trouter: "npm:^2.0.1" + checksum: 10c0/113005fe146e1ee67bc6e1a5438c71e1b59ac05a8bc435d593be210e21f712e6b9ba4d163072e3c941f8efbb7516df9c55bf18934948f91623d03dc9657a1410 + languageName: node + linkType: hard + "postcss-import@npm:^15.1.0": version: 15.1.0 resolution: "postcss-import@npm:15.1.0" @@ -13647,6 +17111,26 @@ __metadata: languageName: node linkType: hard +"postcss-loader@npm:^8.1.1": + version: 8.2.1 + resolution: "postcss-loader@npm:8.2.1" + dependencies: + cosmiconfig: "npm:^9.0.0" + jiti: "npm:^2.5.1" + semver: "npm:^7.6.2" + peerDependencies: + "@rspack/core": 0.x || ^1.0.0 || ^2.0.0-0 + postcss: ^7.0.0 || ^8.0.1 + webpack: ^5.0.0 + peerDependenciesMeta: + "@rspack/core": + optional: true + webpack: + optional: true + checksum: 10c0/8ef4687f05972a85b4ad8e714f692fceec16f334d99edaa09c222dc08d01afcdcf7bed2b3a45f7888900cb9fd3324b9741d98ce694e33e87bebdc038dd17e30b + languageName: node + linkType: hard + "postcss-media-query-parser@npm:^0.2.3": version: 0.2.3 resolution: "postcss-media-query-parser@npm:0.2.3" @@ -13747,6 +17231,17 @@ __metadata: languageName: node linkType: hard +"postcss@npm:^8.4.40": + version: 8.5.8 + resolution: "postcss@npm:8.5.8" + dependencies: + nanoid: "npm:^3.3.11" + picocolors: "npm:^1.1.1" + source-map-js: "npm:^1.2.1" + checksum: 10c0/dd918f7127ee7c60a0295bae2e72b3787892296e1d1c3c564d7a2a00c68d8df83cadc3178491259daa19ccc54804fb71ed8c937c6787e08d8bd4bedf8d17044c + languageName: node + linkType: hard + "preact@npm:~10.12.1": version: 10.12.1 resolution: "preact@npm:10.12.1" @@ -13848,6 +17343,16 @@ __metadata: languageName: node linkType: hard +"pretty-error@npm:^4.0.0": + version: 4.0.0 + resolution: "pretty-error@npm:4.0.0" + dependencies: + lodash: "npm:^4.17.20" + renderkid: "npm:^3.0.0" + checksum: 10c0/dc292c087e2857b2e7592784ab31e37a40f3fa918caa11eba51f9fb2853e1d4d6e820b219917e35f5721d833cfd20fdf4f26ae931a90fd1ad0cae2125c345138 + languageName: node + linkType: hard + "primeng@npm:^20.4.0": version: 20.4.0 resolution: "primeng@npm:20.4.0" @@ -13869,6 +17374,13 @@ __metadata: languageName: node linkType: hard +"prismjs@npm:^1.30.0": + version: 1.30.0 + resolution: "prismjs@npm:1.30.0" + checksum: 10c0/f56205bfd58ef71ccfcbcb691fd0eb84adc96c6ff21b0b69fc6fdcf02be42d6ef972ba4aed60466310de3d67733f6a746f89f2fb79c00bf217406d465b3e8f23 + languageName: node + linkType: hard + "proc-log@npm:^5.0.0": version: 5.0.0 resolution: "proc-log@npm:5.0.0" @@ -13949,6 +17461,13 @@ __metadata: languageName: node linkType: hard +"proxy-middleware@npm:latest": + version: 0.15.0 + resolution: "proxy-middleware@npm:0.15.0" + checksum: 10c0/cb45deab207c69872721cf19b4787132a3589846ed098b1037b7337a97f9092fdcc8216908114310b4122eba3b96530745ca1337489e545d07d40d170c9aeb1b + languageName: node + linkType: hard + "prr@npm:~1.0.1": version: 1.0.1 resolution: "prr@npm:1.0.1" @@ -13991,6 +17510,15 @@ __metadata: languageName: node linkType: hard +"qs@npm:^6.14.1": + version: 6.15.0 + resolution: "qs@npm:6.15.0" + dependencies: + side-channel: "npm:^1.1.0" + checksum: 10c0/ff341078a78a991d8a48b4524d52949211447b4b1ad907f489cac0770cbc346a28e47304455c0320e5fb000f8762d64b03331e3b71865f663bf351bcba8cdb4b + languageName: node + linkType: hard + "queue-microtask@npm:^1.2.2": version: 1.2.3 resolution: "queue-microtask@npm:1.2.3" @@ -14075,6 +17603,24 @@ __metadata: languageName: node linkType: hard +"react-dom@npm:^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0": + version: 19.2.4 + resolution: "react-dom@npm:19.2.4" + dependencies: + scheduler: "npm:^0.27.0" + peerDependencies: + react: ^19.2.4 + checksum: 10c0/f0c63f1794dedb154136d4d0f59af00b41907f4859571c155940296808f4b94bf9c0c20633db75b5b2112ec13d8d7dd4f9bf57362ed48782f317b11d05a44f35 + languageName: node + linkType: hard + +"react@npm:^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0": + version: 19.2.4 + resolution: "react@npm:19.2.4" + checksum: 10c0/cd2c9ff67a720799cc3b38a516009986f7fc4cb8d3e15716c6211cf098d1357ee3e348ab05ad0600042bbb0fd888530ba92e329198c92eafa0994f5213396596 + languageName: node + linkType: hard + "read-cache@npm:^1.0.0": version: 1.0.0 resolution: "read-cache@npm:1.0.0" @@ -14126,6 +17672,13 @@ __metadata: languageName: node linkType: hard +"readdirp@npm:^5.0.0": + version: 5.0.0 + resolution: "readdirp@npm:5.0.0" + checksum: 10c0/faf1ec57cff2020f473128da3f8d2a57813cc3a08a36c38cae1c9af32c1579906cc50ba75578043b35bade77e945c098233665797cf9730ba3613a62d6e79219 + languageName: node + linkType: hard + "readdirp@npm:~3.6.0": version: 3.6.0 resolution: "readdirp@npm:3.6.0" @@ -14142,6 +17695,29 @@ __metadata: languageName: node linkType: hard +"recast@npm:^0.23.5": + version: 0.23.11 + resolution: "recast@npm:0.23.11" + dependencies: + ast-types: "npm:^0.16.1" + esprima: "npm:~4.0.0" + source-map: "npm:~0.6.1" + tiny-invariant: "npm:^1.3.3" + tslib: "npm:^2.0.1" + checksum: 10c0/45b520a8f0868a5a24ecde495be9de3c48e69a54295d82a7331106554b75cfba75d16c909959d056e9ceed47a1be5e061e2db8b9ecbcd6ba44c2f3ef9a47bd18 + languageName: node + linkType: hard + +"redent@npm:^3.0.0": + version: 3.0.0 + resolution: "redent@npm:3.0.0" + dependencies: + indent-string: "npm:^4.0.0" + strip-indent: "npm:^3.0.0" + checksum: 10c0/d64a6b5c0b50eb3ddce3ab770f866658a2b9998c678f797919ceb1b586bab9259b311407280bd80b804e2a7c7539b19238ae6a2a20c843f1a7fcff21d48c2eae + languageName: node + linkType: hard + "reflect-metadata@npm:^0.2.0": version: 0.2.2 resolution: "reflect-metadata@npm:0.2.2" @@ -14158,6 +17734,15 @@ __metadata: languageName: node linkType: hard +"regenerate-unicode-properties@npm:^10.2.2": + version: 10.2.2 + resolution: "regenerate-unicode-properties@npm:10.2.2" + dependencies: + regenerate: "npm:^1.4.2" + checksum: 10c0/66a1d6a1dbacdfc49afd88f20b2319a4c33cee56d245163e4d8f5f283e0f45d1085a78f7f7406dd19ea3a5dd7a7799cd020cd817c97464a7507f9d10fbdce87c + languageName: node + linkType: hard + "regenerate@npm:^1.4.2": version: 1.4.2 resolution: "regenerate@npm:1.4.2" @@ -14186,6 +17771,20 @@ __metadata: languageName: node linkType: hard +"regexpu-core@npm:^6.3.1": + version: 6.4.0 + resolution: "regexpu-core@npm:6.4.0" + dependencies: + regenerate: "npm:^1.4.2" + regenerate-unicode-properties: "npm:^10.2.2" + regjsgen: "npm:^0.8.0" + regjsparser: "npm:^0.13.0" + unicode-match-property-ecmascript: "npm:^2.0.0" + unicode-match-property-value-ecmascript: "npm:^2.2.1" + checksum: 10c0/1eed9783c023dd06fb1f3ce4b6e3fdf0bc1e30cb036f30aeb2019b351e5e0b74355b40462282ea5db092c79a79331c374c7e9897e44a5ca4509e9f0b570263de + languageName: node + linkType: hard + "regjsgen@npm:^0.8.0": version: 0.8.0 resolution: "regjsgen@npm:0.8.0" @@ -14204,6 +17803,37 @@ __metadata: languageName: node linkType: hard +"regjsparser@npm:^0.13.0": + version: 0.13.0 + resolution: "regjsparser@npm:0.13.0" + dependencies: + jsesc: "npm:~3.1.0" + bin: + regjsparser: bin/parser + checksum: 10c0/4702f85cda09f67747c1b2fb673a0f0e5d1ba39d55f177632265a0be471ba59e3f320623f411649141f752b126b8126eac3ff4c62d317921e430b0472bfc6071 + languageName: node + linkType: hard + +"relateurl@npm:^0.2.7": + version: 0.2.7 + resolution: "relateurl@npm:0.2.7" + checksum: 10c0/c248b4e3b32474f116a804b537fa6343d731b80056fb506dffd91e737eef4cac6be47a65aae39b522b0db9d0b1011d1a12e288d82a109ecd94a5299d82f6573a + languageName: node + linkType: hard + +"renderkid@npm:^3.0.0": + version: 3.0.0 + resolution: "renderkid@npm:3.0.0" + dependencies: + css-select: "npm:^4.1.3" + dom-converter: "npm:^0.2.0" + htmlparser2: "npm:^6.1.0" + lodash: "npm:^4.17.21" + strip-ansi: "npm:^6.0.1" + checksum: 10c0/24a9fae4cc50e731d059742d1b3eec163dc9e3872b12010d120c3fcbd622765d9cda41f79a1bbb4bf63c1d3442f18a08f6e1642cb5d7ebf092a0ce3f7a3bd143 + languageName: node + linkType: hard + "require-directory@npm:^2.1.1": version: 2.1.1 resolution: "require-directory@npm:2.1.1" @@ -14435,6 +18065,96 @@ __metadata: languageName: node linkType: hard +"rollup@npm:4.59.0": + version: 4.59.0 + resolution: "rollup@npm:4.59.0" + dependencies: + "@rollup/rollup-android-arm-eabi": "npm:4.59.0" + "@rollup/rollup-android-arm64": "npm:4.59.0" + "@rollup/rollup-darwin-arm64": "npm:4.59.0" + "@rollup/rollup-darwin-x64": "npm:4.59.0" + "@rollup/rollup-freebsd-arm64": "npm:4.59.0" + "@rollup/rollup-freebsd-x64": "npm:4.59.0" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.59.0" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.59.0" + "@rollup/rollup-linux-arm64-gnu": "npm:4.59.0" + "@rollup/rollup-linux-arm64-musl": "npm:4.59.0" + "@rollup/rollup-linux-loong64-gnu": "npm:4.59.0" + "@rollup/rollup-linux-loong64-musl": "npm:4.59.0" + "@rollup/rollup-linux-ppc64-gnu": "npm:4.59.0" + "@rollup/rollup-linux-ppc64-musl": "npm:4.59.0" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.59.0" + "@rollup/rollup-linux-riscv64-musl": "npm:4.59.0" + "@rollup/rollup-linux-s390x-gnu": "npm:4.59.0" + "@rollup/rollup-linux-x64-gnu": "npm:4.59.0" + "@rollup/rollup-linux-x64-musl": "npm:4.59.0" + "@rollup/rollup-openbsd-x64": "npm:4.59.0" + "@rollup/rollup-openharmony-arm64": "npm:4.59.0" + "@rollup/rollup-win32-arm64-msvc": "npm:4.59.0" + "@rollup/rollup-win32-ia32-msvc": "npm:4.59.0" + "@rollup/rollup-win32-x64-gnu": "npm:4.59.0" + "@rollup/rollup-win32-x64-msvc": "npm:4.59.0" + "@types/estree": "npm:1.0.8" + fsevents: "npm:~2.3.2" + dependenciesMeta: + "@rollup/rollup-android-arm-eabi": + optional: true + "@rollup/rollup-android-arm64": + optional: true + "@rollup/rollup-darwin-arm64": + optional: true + "@rollup/rollup-darwin-x64": + optional: true + "@rollup/rollup-freebsd-arm64": + optional: true + "@rollup/rollup-freebsd-x64": + optional: true + "@rollup/rollup-linux-arm-gnueabihf": + optional: true + "@rollup/rollup-linux-arm-musleabihf": + optional: true + "@rollup/rollup-linux-arm64-gnu": + optional: true + "@rollup/rollup-linux-arm64-musl": + optional: true + "@rollup/rollup-linux-loong64-gnu": + optional: true + "@rollup/rollup-linux-loong64-musl": + optional: true + "@rollup/rollup-linux-ppc64-gnu": + optional: true + "@rollup/rollup-linux-ppc64-musl": + optional: true + "@rollup/rollup-linux-riscv64-gnu": + optional: true + "@rollup/rollup-linux-riscv64-musl": + optional: true + "@rollup/rollup-linux-s390x-gnu": + optional: true + "@rollup/rollup-linux-x64-gnu": + optional: true + "@rollup/rollup-linux-x64-musl": + optional: true + "@rollup/rollup-openbsd-x64": + optional: true + "@rollup/rollup-openharmony-arm64": + optional: true + "@rollup/rollup-win32-arm64-msvc": + optional: true + "@rollup/rollup-win32-ia32-msvc": + optional: true + "@rollup/rollup-win32-x64-gnu": + optional: true + "@rollup/rollup-win32-x64-msvc": + optional: true + fsevents: + optional: true + bin: + rollup: dist/bin/rollup + checksum: 10c0/f38742da34cfee5e899302615fa157aa77cb6a2a1495e5e3ce4cc9c540d3262e235bbe60caa31562bbfe492b01fdb3e7a8c43c39d842d3293bcf843123b766fc + languageName: node + linkType: hard + "rollup@npm:^4.43.0": version: 4.53.3 resolution: "rollup@npm:4.53.3" @@ -14561,6 +18281,13 @@ __metadata: languageName: node linkType: hard +"safe-buffer@npm:5.1.2, safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": + version: 5.1.2 + resolution: "safe-buffer@npm:5.1.2" + checksum: 10c0/780ba6b5d99cc9a40f7b951d47152297d0e260f0df01472a1b99d4889679a4b94a13d644f7dbc4f022572f09ae9005fa2fbb93bbbd83643316f365a3e9a45b21 + languageName: node + linkType: hard + "safe-buffer@npm:5.2.1, safe-buffer@npm:>=5.1.0, safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:^5.2.1, safe-buffer@npm:~5.2.0": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" @@ -14568,13 +18295,6 @@ __metadata: languageName: node linkType: hard -"safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": - version: 5.1.2 - resolution: "safe-buffer@npm:5.1.2" - checksum: 10c0/780ba6b5d99cc9a40f7b951d47152297d0e260f0df01472a1b99d4889679a4b94a13d644f7dbc4f022572f09ae9005fa2fbb93bbbd83643316f365a3e9a45b21 - languageName: node - linkType: hard - "safe-stable-stringify@npm:^2.3.1": version: 2.5.0 resolution: "safe-stable-stringify@npm:2.5.0" @@ -14639,6 +18359,24 @@ __metadata: languageName: node linkType: hard +"scheduler@npm:^0.27.0": + version: 0.27.0 + resolution: "scheduler@npm:0.27.0" + checksum: 10c0/4f03048cb05a3c8fddc45813052251eca00688f413a3cee236d984a161da28db28ba71bd11e7a3dd02f7af84ab28d39fb311431d3b3772fed557945beb00c452 + languageName: node + linkType: hard + +"schema-utils@npm:^3.1.1": + version: 3.3.0 + resolution: "schema-utils@npm:3.3.0" + dependencies: + "@types/json-schema": "npm:^7.0.8" + ajv: "npm:^6.12.5" + ajv-keywords: "npm:^3.5.2" + checksum: 10c0/fafdbde91ad8aa1316bc543d4b61e65ea86970aebbfb750bfb6d8a6c287a23e415e0e926c2498696b242f63af1aab8e585252637fabe811fd37b604351da6500 + languageName: node + linkType: hard + "schema-utils@npm:^4.0.0, schema-utils@npm:^4.2.0, schema-utils@npm:^4.3.0": version: 4.3.2 resolution: "schema-utils@npm:4.3.2" @@ -14651,7 +18389,7 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^4.3.2": +"schema-utils@npm:^4.3.2, schema-utils@npm:^4.3.3": version: 4.3.3 resolution: "schema-utils@npm:4.3.3" dependencies: @@ -14723,6 +18461,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^7.6.3": + version: 7.7.4 + resolution: "semver@npm:7.7.4" + bin: + semver: bin/semver.js + checksum: 10c0/5215ad0234e2845d4ea5bb9d836d42b03499546ddafb12075566899fc617f68794bb6f146076b6881d755de17d6c6cc73372555879ec7dce2c2feee947866ad2 + languageName: node + linkType: hard + "semver@npm:~7.5.0, semver@npm:~7.5.4": version: 7.5.4 resolution: "semver@npm:7.5.4" @@ -14774,6 +18521,25 @@ __metadata: languageName: node linkType: hard +"send@npm:latest": + version: 1.2.1 + resolution: "send@npm:1.2.1" + dependencies: + debug: "npm:^4.4.3" + encodeurl: "npm:^2.0.0" + escape-html: "npm:^1.0.3" + etag: "npm:^1.8.1" + fresh: "npm:^2.0.0" + http-errors: "npm:^2.0.1" + mime-types: "npm:^3.0.2" + ms: "npm:^2.1.3" + on-finished: "npm:^2.4.1" + range-parser: "npm:^1.2.1" + statuses: "npm:^2.0.2" + checksum: 10c0/fbbbbdc902a913d65605274be23f3d604065cfc3ee3d78bf9fc8af1dc9fc82667c50d3d657f5e601ac657bac9b396b50ee97bd29cd55436320cf1cddebdcec72 + languageName: node + linkType: hard + "serialize-javascript@npm:^6.0.2": version: 6.0.2 resolution: "serialize-javascript@npm:6.0.2" @@ -14783,6 +18549,13 @@ __metadata: languageName: node linkType: hard +"serialize-javascript@npm:^7.0.3": + version: 7.0.4 + resolution: "serialize-javascript@npm:7.0.4" + checksum: 10c0/f3da6f994c41306fbfabb55eefe280a46da05592939a84b0d95c84e296c92ba9e6a3d86cf7bbd71e7a59e1cfcd8481745910af109bedbd3ed853b444d32f9ee9 + languageName: node + linkType: hard + "serve-index@npm:^1.9.1": version: 1.9.1 resolution: "serve-index@npm:1.9.1" @@ -14923,7 +18696,7 @@ __metadata: languageName: node linkType: hard -"signal-exit@npm:^3.0.3": +"signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3": version: 3.0.7 resolution: "signal-exit@npm:3.0.7" checksum: 10c0/25d272fa73e146048565e08f3309d5b942c1979a6f4a58a8c59d5fa299728e9c2fcd1a759ec870863b1fd38653670240cd420dad2ad9330c71f36608a6a1c912 @@ -14958,6 +18731,17 @@ __metadata: languageName: node linkType: hard +"sirv@npm:^3.0.2": + version: 3.0.2 + resolution: "sirv@npm:3.0.2" + dependencies: + "@polka/url": "npm:^1.0.0-next.24" + mrmime: "npm:^2.0.0" + totalist: "npm:^3.0.0" + checksum: 10c0/5930e4397afdb14fbae13751c3be983af4bda5c9aadec832607dc2af15a7162f7d518c71b30e83ae3644b9a24cea041543cc969e5fe2b80af6ce8ea3174b2d04 + languageName: node + linkType: hard + "slice-ansi@npm:^5.0.0": version: 5.0.0 resolution: "slice-ansi@npm:5.0.0" @@ -15101,7 +18885,7 @@ __metadata: languageName: node linkType: hard -"source-map@npm:0.6.1, source-map@npm:^0.6.0, source-map@npm:~0.6.0, source-map@npm:~0.6.1": +"source-map@npm:0.6.1, source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.0, source-map@npm:~0.6.1": version: 0.6.1 resolution: "source-map@npm:0.6.1" checksum: 10c0/ab55398007c5e5532957cb0beee2368529618ac0ab372d789806f5718123cc4367d57de3904b4e6a4170eb5a0b0f41373066d02ca0735a0c4d75c7d328d3e011 @@ -15183,6 +18967,15 @@ __metadata: languageName: node linkType: hard +"split@npm:^1.0.1": + version: 1.0.1 + resolution: "split@npm:1.0.1" + dependencies: + through: "npm:2" + checksum: 10c0/7f489e7ed5ff8a2e43295f30a5197ffcb2d6202c9cf99357f9690d645b19c812bccf0be3ff336fea5054cda17ac96b91d67147d95dbfc31fbb5804c61962af85 + languageName: node + linkType: hard + "sprintf-js@npm:1.1.2": version: 1.1.2 resolution: "sprintf-js@npm:1.1.2" @@ -15220,24 +19013,61 @@ __metadata: languageName: node linkType: hard -"statuses@npm:>= 1.4.0 < 2, statuses@npm:>= 1.5.0 < 2": +"statuses@npm:>= 1.4.0 < 2, statuses@npm:>= 1.5.0 < 2, statuses@npm:~1.5.0": version: 1.5.0 resolution: "statuses@npm:1.5.0" checksum: 10c0/e433900956357b3efd79b1c547da4d291799ac836960c016d10a98f6a810b1b5c0dcc13b5a7aa609a58239b5190e1ea176ad9221c2157d2fd1c747393e6b2940 languageName: node linkType: hard -"statuses@npm:^2.0.1, statuses@npm:~2.0.2": +"statuses@npm:^2.0.1, statuses@npm:^2.0.2, statuses@npm:~2.0.2": version: 2.0.2 resolution: "statuses@npm:2.0.2" checksum: 10c0/a9947d98ad60d01f6b26727570f3bcceb6c8fa789da64fe6889908fe2e294d57503b14bf2b5af7605c2d36647259e856635cd4c49eab41667658ec9d0080ec3f languageName: node linkType: hard -"stdin-discarder@npm:^0.2.2": +"stdin-discarder@npm:^0.2.2": + version: 0.2.2 + resolution: "stdin-discarder@npm:0.2.2" + checksum: 10c0/c78375e82e956d7a64be6e63c809c7f058f5303efcaf62ea48350af072bacdb99c06cba39209b45a071c1acbd49116af30df1df9abb448df78a6005b72f10537 + languageName: node + linkType: hard + +"storybook@npm:^10.3.0": + version: 10.3.0 + resolution: "storybook@npm:10.3.0" + dependencies: + "@storybook/global": "npm:^5.0.0" + "@storybook/icons": "npm:^2.0.1" + "@testing-library/jest-dom": "npm:^6.9.1" + "@testing-library/user-event": "npm:^14.6.1" + "@vitest/expect": "npm:3.2.4" + "@vitest/spy": "npm:3.2.4" + esbuild: "npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0" + open: "npm:^10.2.0" + recast: "npm:^0.23.5" + semver: "npm:^7.7.3" + use-sync-external-store: "npm:^1.5.0" + ws: "npm:^8.18.0" + peerDependencies: + prettier: ^2 || ^3 + peerDependenciesMeta: + prettier: + optional: true + bin: + storybook: ./dist/bin/dispatcher.js + checksum: 10c0/aaab242fb36948c122b8a9bd6b45120418e25af105e96c303f565ef19d08001adb17aaa9810c9f44b4d494fab999a53e58e4789c6202e0880d1e701e93f10e21 + languageName: node + linkType: hard + +"stream-combiner@npm:^0.2.2": version: 0.2.2 - resolution: "stdin-discarder@npm:0.2.2" - checksum: 10c0/c78375e82e956d7a64be6e63c809c7f058f5303efcaf62ea48350af072bacdb99c06cba39209b45a071c1acbd49116af30df1df9abb448df78a6005b72f10537 + resolution: "stream-combiner@npm:0.2.2" + dependencies: + duplexer: "npm:~0.1.1" + through: "npm:~2.3.4" + checksum: 10c0/b5d2782fbfa9251c88e01af1b1f54bc183673a776989dce2842b345be7fc3ce7eb2eade363b3c198ba0e5153a20a96e0014d0d0e884153f885d7ee919f22b639 languageName: node linkType: hard @@ -15352,6 +19182,29 @@ __metadata: languageName: node linkType: hard +"strip-bom@npm:^3.0.0": + version: 3.0.0 + resolution: "strip-bom@npm:3.0.0" + checksum: 10c0/51201f50e021ef16672593d7434ca239441b7b760e905d9f33df6e4f3954ff54ec0e0a06f100d028af0982d6f25c35cd5cda2ce34eaebccd0250b8befb90d8f1 + languageName: node + linkType: hard + +"strip-final-newline@npm:^2.0.0": + version: 2.0.0 + resolution: "strip-final-newline@npm:2.0.0" + checksum: 10c0/bddf8ccd47acd85c0e09ad7375409d81653f645fda13227a9d459642277c253d877b68f2e5e4d819fe75733b0e626bac7e954c04f3236f6d196f79c94fa4a96f + languageName: node + linkType: hard + +"strip-indent@npm:^3.0.0": + version: 3.0.0 + resolution: "strip-indent@npm:3.0.0" + dependencies: + min-indent: "npm:^1.0.0" + checksum: 10c0/ae0deaf41c8d1001c5d4fbe16cb553865c1863da4fae036683b474fa926af9fc121e155cb3fc57a68262b2ae7d5b8420aa752c97a6428c315d00efe2a3875679 + languageName: node + linkType: hard + "strip-json-comments@npm:3.1.1, strip-json-comments@npm:^3.1.1": version: 3.1.1 resolution: "strip-json-comments@npm:3.1.1" @@ -15387,6 +19240,15 @@ __metadata: languageName: node linkType: hard +"style-loader@npm:^4.0.0": + version: 4.0.0 + resolution: "style-loader@npm:4.0.0" + peerDependencies: + webpack: ^5.27.0 + checksum: 10c0/214bc0f3b018f8c374f79b9fa16da43df78c7fef2261e9a99e36c2f8387601fad10ac75a171aa8edba75903db214bc46952ae08b94a1f8544bd146c2c8d07d27 + languageName: node + linkType: hard + "sucrase@npm:^3.35.0": version: 3.35.0 resolution: "sucrase@npm:3.35.0" @@ -15430,6 +19292,13 @@ __metadata: languageName: node linkType: hard +"svg-pan-zoom@npm:^3.6.2": + version: 3.6.2 + resolution: "svg-pan-zoom@npm:3.6.2" + checksum: 10c0/dc05030bd6545d523de71e38d79d6830f780a74416a609269cc378fe8778796e794cb3e27f0f5b20bd7ee930597820e5b4463e4e4e0708127bed81e020339ec0 + languageName: node + linkType: hard + "systeminformation@npm:^5.7": version: 5.27.8 resolution: "systeminformation@npm:5.27.8" @@ -15439,6 +19308,13 @@ __metadata: languageName: node linkType: hard +"tablesort@npm:^5.7.0": + version: 5.7.0 + resolution: "tablesort@npm:5.7.0" + checksum: 10c0/dc61815aa1cf612bd0dbd669945f33e0beda859a3333b3a1a28de19a5d48126f6d84116fc91ab6234b97c88e6c5e395604947148c7e8d8afba049d067384309c + languageName: node + linkType: hard + "tailwindcss-primeui@npm:^0.6.1": version: 0.6.1 resolution: "tailwindcss-primeui@npm:0.6.1" @@ -15448,6 +19324,13 @@ __metadata: languageName: node linkType: hard +"tailwindcss@npm:4.2.2, tailwindcss@npm:^4.0.0": + version: 4.2.2 + resolution: "tailwindcss@npm:4.2.2" + checksum: 10c0/6eae8a125c35d504ba6c518d26ec64fba694ff4a9ab9b9cd9883050128e0b7afdf491388c472d9bed2624664c1c7d4a133d19b653151a6b52e6ce6953168a857 + languageName: node + linkType: hard + "tailwindcss@npm:^3.4.17": version: 3.4.17 resolution: "tailwindcss@npm:3.4.17" @@ -15481,6 +19364,13 @@ __metadata: languageName: node linkType: hard +"tapable@npm:^2.0.0, tapable@npm:^2.3.0": + version: 2.3.0 + resolution: "tapable@npm:2.3.0" + checksum: 10c0/cb9d67cc2c6a74dedc812ef3085d9d681edd2c1fa18e4aef57a3c0605fdbe44e6b8ea00bd9ef21bc74dd45314e39d31227aa031ebf2f5e38164df514136f2681 + languageName: node + linkType: hard + "tapable@npm:^2.1.1, tapable@npm:^2.2.0, tapable@npm:^2.2.1": version: 2.2.2 resolution: "tapable@npm:2.2.2" @@ -15529,6 +19419,13 @@ __metadata: languageName: node linkType: hard +"telejson@npm:8.0.0": + version: 8.0.0 + resolution: "telejson@npm:8.0.0" + checksum: 10c0/518d4aefee5a6630de9a91cffa8927e961df8b59b3a65eb4eb01e23e6f0a0716067b69d38b255c9a5711b426f66a720ff8407f23106ba0b8542bd7fe36a7adf3 + languageName: node + linkType: hard + "terser-webpack-plugin@npm:^5.3.11": version: 5.3.14 resolution: "terser-webpack-plugin@npm:5.3.14" @@ -15551,6 +19448,27 @@ __metadata: languageName: node linkType: hard +"terser-webpack-plugin@npm:^5.3.14, terser-webpack-plugin@npm:^5.3.16, terser-webpack-plugin@npm:^5.3.17": + version: 5.4.0 + resolution: "terser-webpack-plugin@npm:5.4.0" + dependencies: + "@jridgewell/trace-mapping": "npm:^0.3.25" + jest-worker: "npm:^27.4.5" + schema-utils: "npm:^4.3.0" + terser: "npm:^5.31.1" + peerDependencies: + webpack: ^5.1.0 + peerDependenciesMeta: + "@swc/core": + optional: true + esbuild: + optional: true + uglify-js: + optional: true + checksum: 10c0/1feed4b9575af795dae6af0c8f0d76d6e1fb7b357b8628d90e834c23a651b918a58cdc48d0ae6c1f0581f74bc8169b33c3b8d049f2d2190bac4e310964e59fde + languageName: node + linkType: hard + "terser@npm:5.43.1, terser@npm:^5.31.1": version: 5.43.1 resolution: "terser@npm:5.43.1" @@ -15565,6 +19483,20 @@ __metadata: languageName: node linkType: hard +"terser@npm:^5.10.0": + version: 5.46.1 + resolution: "terser@npm:5.46.1" + dependencies: + "@jridgewell/source-map": "npm:^0.3.3" + acorn: "npm:^8.15.0" + commander: "npm:^2.20.0" + source-map-support: "npm:~0.5.20" + bin: + terser: bin/terser + checksum: 10c0/45ba6566af976c518ff4e140250348d606761af822e23ea28d95b30fcf60fb69d3fabd93c6fafa4085d9fe31b67207e58b8480a64370b6cca07066c434101602 + languageName: node + linkType: hard + "text-extensions@npm:^2.0.0": version: 2.4.0 resolution: "text-extensions@npm:2.4.0" @@ -15615,7 +19547,7 @@ __metadata: languageName: node linkType: hard -"through@npm:>=2.2.7 <3": +"through@npm:2, through@npm:>=2.2.7 <3, through@npm:^2.3.8, through@npm:~2.3, through@npm:~2.3.4": version: 2.3.8 resolution: "through@npm:2.3.8" checksum: 10c0/4b09f3774099de0d4df26d95c5821a62faee32c7e96fb1f4ebd54a2d7c11c57fe88b0a0d49cf375de5fee5ae6bf4eb56dbbf29d07366864e2ee805349970d3cc @@ -15629,6 +19561,13 @@ __metadata: languageName: node linkType: hard +"tiny-invariant@npm:^1.3.3": + version: 1.3.3 + resolution: "tiny-invariant@npm:1.3.3" + checksum: 10c0/65af4a07324b591a059b35269cd696aba21bef2107f29b9f5894d83cc143159a204b299553435b03874ebb5b94d019afa8b8eff241c8a4cfee95872c2e1c1c4a + languageName: node + linkType: hard + "tinyexec@npm:^1.0.0": version: 1.0.1 resolution: "tinyexec@npm:1.0.1" @@ -15646,7 +19585,7 @@ __metadata: languageName: node linkType: hard -"tinyglobby@npm:^0.2.15": +"tinyglobby@npm:^0.2.14, tinyglobby@npm:^0.2.15": version: 0.2.15 resolution: "tinyglobby@npm:0.2.15" dependencies: @@ -15656,6 +19595,20 @@ __metadata: languageName: node linkType: hard +"tinyrainbow@npm:^2.0.0": + version: 2.0.0 + resolution: "tinyrainbow@npm:2.0.0" + checksum: 10c0/c83c52bef4e0ae7fb8ec6a722f70b5b6fa8d8be1c85792e829f56c0e1be94ab70b293c032dc5048d4d37cfe678f1f5babb04bdc65fd123098800148ca989184f + languageName: node + linkType: hard + +"tinyspy@npm:^4.0.3": + version: 4.0.4 + resolution: "tinyspy@npm:4.0.4" + checksum: 10c0/a8020fc17799251e06a8398dcc352601d2770aa91c556b9531ecd7a12581161fd1c14e81cbdaff0c1306c93bfdde8ff6d1c1a3f9bbe6d91604f0fd4e01e2f1eb + languageName: node + linkType: hard + "to-regex-range@npm:^5.0.1": version: 5.0.1 resolution: "to-regex-range@npm:5.0.1" @@ -15679,6 +19632,13 @@ __metadata: languageName: node linkType: hard +"totalist@npm:^3.0.0": + version: 3.0.1 + resolution: "totalist@npm:3.0.1" + checksum: 10c0/4bb1fadb69c3edbef91c73ebef9d25b33bbf69afe1e37ce544d5f7d13854cda15e47132f3e0dc4cafe300ddb8578c77c50a65004d8b6e97e77934a69aa924863 + languageName: node + linkType: hard + "tr46@npm:~0.0.3": version: 0.0.3 resolution: "tr46@npm:0.0.3" @@ -15711,6 +19671,15 @@ __metadata: languageName: node linkType: hard +"trouter@npm:^2.0.1": + version: 2.0.1 + resolution: "trouter@npm:2.0.1" + dependencies: + matchit: "npm:^1.0.0" + checksum: 10c0/9d294dbe74d45649d929d3abf0d4cb8e508985a2ea0f8be41b3b097a985352b14f65dd76b68ae651731128995eceddba375b15719356c419bbfe754c5fb5673c + languageName: node + linkType: hard + "ts-api-utils@npm:^2.1.0": version: 2.1.0 resolution: "ts-api-utils@npm:2.1.0" @@ -15729,6 +19698,13 @@ __metadata: languageName: node linkType: hard +"ts-dedent@npm:^2.0.0": + version: 2.2.0 + resolution: "ts-dedent@npm:2.2.0" + checksum: 10c0/175adea838468cc2ff7d5e97f970dcb798bbcb623f29c6088cb21aa2880d207c5784be81ab1741f56b9ac37840cbaba0c0d79f7f8b67ffe61c02634cafa5c303 + languageName: node + linkType: hard + "ts-interface-checker@npm:^0.1.9": version: 0.1.13 resolution: "ts-interface-checker@npm:0.1.13" @@ -15736,6 +19712,39 @@ __metadata: languageName: node linkType: hard +"ts-morph@npm:^27.0.2": + version: 27.0.2 + resolution: "ts-morph@npm:27.0.2" + dependencies: + "@ts-morph/common": "npm:~0.28.1" + code-block-writer: "npm:^13.0.3" + checksum: 10c0/224715cc6d97b8ff5afd3986f9629f912a0ebd83eaecbdca91c35cf10a98f607c663f666e7ea5e6afab00563d00dc80fa7a13552cc7f1cef735261c3217d0863 + languageName: node + linkType: hard + +"tsconfig-paths-webpack-plugin@npm:^4.0.1": + version: 4.2.0 + resolution: "tsconfig-paths-webpack-plugin@npm:4.2.0" + dependencies: + chalk: "npm:^4.1.0" + enhanced-resolve: "npm:^5.7.0" + tapable: "npm:^2.2.1" + tsconfig-paths: "npm:^4.1.2" + checksum: 10c0/495c5ab7c1cb079217d98fe25d61def01e4bab38047c7ab25ec11876cc8c697ff01f43ea6c9933181875e51e49835407fc71afd92ea6cca1ba1bebf513dfb510 + languageName: node + linkType: hard + +"tsconfig-paths@npm:^4.1.2": + version: 4.2.0 + resolution: "tsconfig-paths@npm:4.2.0" + dependencies: + json5: "npm:^2.2.2" + minimist: "npm:^1.2.6" + strip-bom: "npm:^3.0.0" + checksum: 10c0/09a5877402d082bb1134930c10249edeebc0211f36150c35e1c542e5b91f1047b1ccf7da1e59babca1ef1f014c525510f4f870de7c9bda470c73bb4e2721b3ea + languageName: node + linkType: hard + "tslib@npm:1.9.3": version: 1.9.3 resolution: "tslib@npm:1.9.3" @@ -15743,7 +19752,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:2.8.1, tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.1.0, tslib@npm:^2.2.0, tslib@npm:^2.3.0, tslib@npm:^2.6.2, tslib@npm:^2.8.0, tslib@npm:^2.8.1": +"tslib@npm:2.8.1, tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.2.0, tslib@npm:^2.3.0, tslib@npm:^2.4.0, tslib@npm:^2.6.2, tslib@npm:^2.8.0, tslib@npm:^2.8.1": version: 2.8.1 resolution: "tslib@npm:2.8.1" checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62 @@ -15917,7 +19926,7 @@ __metadata: languageName: node linkType: hard -"typescript@npm:~5.9.3": +"typescript@npm:^5.0.4, typescript@npm:~5.9.3": version: 5.9.3 resolution: "typescript@npm:5.9.3" bin: @@ -15937,7 +19946,7 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@npm%3A~5.9.3#optional!builtin": +"typescript@patch:typescript@npm%3A^5.0.4#optional!builtin, typescript@patch:typescript@npm%3A~5.9.3#optional!builtin": version: 5.9.3 resolution: "typescript@patch:typescript@npm%3A5.9.3#optional!builtin::version=5.9.3&hash=5786d5" bin: @@ -15947,6 +19956,15 @@ __metadata: languageName: node linkType: hard +"uglify-js@npm:^3.1.4": + version: 3.19.3 + resolution: "uglify-js@npm:3.19.3" + bin: + uglifyjs: bin/uglifyjs + checksum: 10c0/83b0a90eca35f778e07cad9622b80c448b6aad457c9ff8e568afed978212b42930a95f9e1be943a1ffa4258a3340fbb899f41461131c05bb1d0a9c303aed8479 + languageName: node + linkType: hard + "undici-types@npm:~5.26.4": version: 5.26.5 resolution: "undici-types@npm:5.26.5" @@ -15968,6 +19986,13 @@ __metadata: languageName: node linkType: hard +"undici@npm:^7.12.0": + version: 7.24.4 + resolution: "undici@npm:7.24.4" + checksum: 10c0/cb302e81fadb7f0b7946ab77595715c0961b46a025ccecae79ba599432d0bc8d1e3da4dfe7ff66bc74f115c1b8ff0f099bc4e9bf313db4562da23995872c6d17 + languageName: node + linkType: hard + "unicode-canonical-property-names-ecmascript@npm:^2.0.0": version: 2.0.1 resolution: "unicode-canonical-property-names-ecmascript@npm:2.0.1" @@ -15992,6 +20017,13 @@ __metadata: languageName: node linkType: hard +"unicode-match-property-value-ecmascript@npm:^2.2.1": + version: 2.2.1 + resolution: "unicode-match-property-value-ecmascript@npm:2.2.1" + checksum: 10c0/93acd1ad9496b600e5379d1aaca154cf551c5d6d4a0aefaf0984fc2e6288e99220adbeb82c935cde461457fb6af0264a1774b8dfd4d9a9e31548df3352a4194d + languageName: node + linkType: hard + "unicode-property-aliases-ecmascript@npm:^2.0.0": version: 2.1.0 resolution: "unicode-property-aliases-ecmascript@npm:2.1.0" @@ -16024,6 +20056,20 @@ __metadata: languageName: node linkType: hard +"universalify@npm:^2.0.0": + version: 2.0.1 + resolution: "universalify@npm:2.0.1" + checksum: 10c0/73e8ee3809041ca8b818efb141801a1004e3fc0002727f1531f4de613ea281b494a40909596dae4a042a4fb6cd385af5d4db2e137b1362e0e91384b828effd3a + languageName: node + linkType: hard + +"unix-crypt-td-js@npm:^1.1.4": + version: 1.1.4 + resolution: "unix-crypt-td-js@npm:1.1.4" + checksum: 10c0/c4e3abd0d7ebcf39df7faff8be2cd137f477add743a2793c551682e04ec4e4f466e806a67e391d5a097229e4465b7cae4cb459990b9eb61dfe0b37d2388c6266 + languageName: node + linkType: hard + "unpipe@npm:1.0.0, unpipe@npm:~1.0.0": version: 1.0.0 resolution: "unpipe@npm:1.0.0" @@ -16031,6 +20077,18 @@ __metadata: languageName: node linkType: hard +"unplugin@npm:^2.3.5": + version: 2.3.11 + resolution: "unplugin@npm:2.3.11" + dependencies: + "@jridgewell/remapping": "npm:^2.3.5" + acorn: "npm:^8.15.0" + picomatch: "npm:^4.0.3" + webpack-virtual-modules: "npm:^0.6.2" + checksum: 10c0/273c1eab0eca4470c7317428689295c31dbe8ab0b306504de9f03cd20c156debb4131bef24b27ac615862958c5dd950a3951d26c0723ea774652ab3624149cff + languageName: node + linkType: hard + "update-browserslist-db@npm:^1.1.3": version: 1.1.3 resolution: "update-browserslist-db@npm:1.1.3" @@ -16075,6 +20133,15 @@ __metadata: languageName: node linkType: hard +"use-sync-external-store@npm:^1.5.0": + version: 1.6.0 + resolution: "use-sync-external-store@npm:1.6.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + checksum: 10c0/35e1179f872a53227bdf8a827f7911da4c37c0f4091c29b76b1e32473d1670ebe7bcd880b808b7549ba9a5605c233350f800ffab963ee4a4ee346ee983b6019b + languageName: node + linkType: hard + "util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2, util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" @@ -16082,6 +20149,13 @@ __metadata: languageName: node linkType: hard +"utila@npm:~0.4": + version: 0.4.0 + resolution: "utila@npm:0.4.0" + checksum: 10c0/2791604e09ca4f77ae314df83e80d1805f867eb5c7e13e7413caee01273c278cf2c9a3670d8d25c889a877f7b149d892fe61b0181a81654b425e9622ab23d42e + languageName: node + linkType: hard + "utils-merge@npm:1.0.1": version: 1.0.1 resolution: "utils-merge@npm:1.0.1" @@ -16089,6 +20163,15 @@ __metadata: languageName: node linkType: hard +"uuid@npm:11.1.0": + version: 11.1.0 + resolution: "uuid@npm:11.1.0" + bin: + uuid: dist/esm/bin/uuid + checksum: 10c0/34aa51b9874ae398c2b799c88a127701408cd581ee89ec3baa53509dd8728cbb25826f2a038f9465f8b7be446f0fbf11558862965b18d21c993684297628d4d3 + languageName: node + linkType: hard + "uuid@npm:^8.0.0, uuid@npm:^8.3.0, uuid@npm:^8.3.2": version: 8.3.2 resolution: "uuid@npm:8.3.2" @@ -16131,6 +20214,20 @@ __metadata: languageName: node linkType: hard +"vis-network@npm:^10.0.2": + version: 10.0.2 + resolution: "vis-network@npm:10.0.2" + peerDependencies: + "@egjs/hammerjs": ^2.0.0 + component-emitter: ^1.3.0 || ^2.0.0 + keycharm: ^0.2.0 || ^0.3.0 || ^0.4.0 + uuid: ^3.4.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^13.0.0 + vis-data: ">=8.0.0" + vis-util: ">=6.0.0" + checksum: 10c0/c28750254abe82e6aecf1014a7bb1d3ac7955c3f731a333fb6386522cf4922ecf47abd503f394cfcd8c00b457a14747f2bcc10e7eec56a2105df4334204a0116 + languageName: node + linkType: hard + "vite@npm:7.1.11": version: 7.1.11 resolution: "vite@npm:7.1.11" @@ -16208,6 +20305,16 @@ __metadata: languageName: node linkType: hard +"watchpack@npm:^2.5.1": + version: 2.5.1 + resolution: "watchpack@npm:2.5.1" + dependencies: + glob-to-regexp: "npm:^0.4.1" + graceful-fs: "npm:^4.1.2" + checksum: 10c0/dffbb483d1f61be90dc570630a1eb308581e2227d507d783b1d94a57ac7b705ecd9a1a4b73d73c15eab596d39874e5276a3d9cb88bbb698bafc3f8d08c34cf17 + languageName: node + linkType: hard + "wbuf@npm:^1.1.0, wbuf@npm:^1.7.3": version: 1.7.3 resolution: "wbuf@npm:1.7.3" @@ -16257,6 +20364,24 @@ __metadata: languageName: node linkType: hard +"webpack-dev-middleware@npm:^6.1.2": + version: 6.1.3 + resolution: "webpack-dev-middleware@npm:6.1.3" + dependencies: + colorette: "npm:^2.0.10" + memfs: "npm:^3.4.12" + mime-types: "npm:^2.1.31" + range-parser: "npm:^1.2.1" + schema-utils: "npm:^4.0.0" + peerDependencies: + webpack: ^5.0.0 + peerDependenciesMeta: + webpack: + optional: true + checksum: 10c0/0f31670835f3c0f588392235a6183facf314c0dca312467254a56458142be6fee746f7f6b304f281c740364fd36f256c597ab37d87e5971633cee2f70a8cd5e7 + languageName: node + linkType: hard + "webpack-dev-server@npm:5.2.2": version: 5.2.2 resolution: "webpack-dev-server@npm:5.2.2" @@ -16302,6 +20427,17 @@ __metadata: languageName: node linkType: hard +"webpack-hot-middleware@npm:^2.25.1": + version: 2.26.1 + resolution: "webpack-hot-middleware@npm:2.26.1" + dependencies: + ansi-html-community: "npm:0.0.8" + html-entities: "npm:^2.1.0" + strip-ansi: "npm:^6.0.0" + checksum: 10c0/13a3e78009e373b4ee990ffe1d4d49046e9893148a7106f063e11f962d02b744ea58b1dec25f5e76723c9dce678b9e68c883e7f2af2940aaf4de7aab31264c83 + languageName: node + linkType: hard + "webpack-merge@npm:6.0.1": version: 6.0.1 resolution: "webpack-merge@npm:6.0.1" @@ -16320,6 +20456,13 @@ __metadata: languageName: node linkType: hard +"webpack-sources@npm:^3.3.4": + version: 3.3.4 + resolution: "webpack-sources@npm:3.3.4" + checksum: 10c0/94a42508531338eb41939cf1d48a4a8a6db97f3a47e5453cff2133a68d3169ca779d4bcbe9dfed072ce16611959eba1e16f085bc2dc56714e1a1c1783fd661a3 + languageName: node + linkType: hard + "webpack-subresource-integrity@npm:5.1.0": version: 5.1.0 resolution: "webpack-subresource-integrity@npm:5.1.0" @@ -16335,6 +20478,51 @@ __metadata: languageName: node linkType: hard +"webpack-virtual-modules@npm:^0.6.0, webpack-virtual-modules@npm:^0.6.2": + version: 0.6.2 + resolution: "webpack-virtual-modules@npm:0.6.2" + checksum: 10c0/5ffbddf0e84bf1562ff86cf6fcf039c74edf09d78358a6904a09bbd4484e8bb6812dc385fe14330b715031892dcd8423f7a88278b57c9f5002c84c2860179add + languageName: node + linkType: hard + +"webpack@npm:5": + version: 5.105.4 + resolution: "webpack@npm:5.105.4" + dependencies: + "@types/eslint-scope": "npm:^3.7.7" + "@types/estree": "npm:^1.0.8" + "@types/json-schema": "npm:^7.0.15" + "@webassemblyjs/ast": "npm:^1.14.1" + "@webassemblyjs/wasm-edit": "npm:^1.14.1" + "@webassemblyjs/wasm-parser": "npm:^1.14.1" + acorn: "npm:^8.16.0" + acorn-import-phases: "npm:^1.0.3" + browserslist: "npm:^4.28.1" + chrome-trace-event: "npm:^1.0.2" + enhanced-resolve: "npm:^5.20.0" + es-module-lexer: "npm:^2.0.0" + eslint-scope: "npm:5.1.1" + events: "npm:^3.2.0" + glob-to-regexp: "npm:^0.4.1" + graceful-fs: "npm:^4.2.11" + json-parse-even-better-errors: "npm:^2.3.1" + loader-runner: "npm:^4.3.1" + mime-types: "npm:^2.1.27" + neo-async: "npm:^2.6.2" + schema-utils: "npm:^4.3.3" + tapable: "npm:^2.3.0" + terser-webpack-plugin: "npm:^5.3.17" + watchpack: "npm:^2.5.1" + webpack-sources: "npm:^3.3.4" + peerDependenciesMeta: + webpack-cli: + optional: true + bin: + webpack: bin/webpack.js + checksum: 10c0/e9896d20bac351b119d59942b7efae5b117056ecf203acc0d1a84ecbf0a5a9a80ca733735f96bd163e3530be6ab7f615cd67e5320bd3c47d709c9bfe376c3280 + languageName: node + linkType: hard + "webpack@npm:5.101.2": version: 5.101.2 resolution: "webpack@npm:5.101.2" @@ -16373,6 +20561,44 @@ __metadata: languageName: node linkType: hard +"webpack@npm:5.105.0": + version: 5.105.0 + resolution: "webpack@npm:5.105.0" + dependencies: + "@types/eslint-scope": "npm:^3.7.7" + "@types/estree": "npm:^1.0.8" + "@types/json-schema": "npm:^7.0.15" + "@webassemblyjs/ast": "npm:^1.14.1" + "@webassemblyjs/wasm-edit": "npm:^1.14.1" + "@webassemblyjs/wasm-parser": "npm:^1.14.1" + acorn: "npm:^8.15.0" + acorn-import-phases: "npm:^1.0.3" + browserslist: "npm:^4.28.1" + chrome-trace-event: "npm:^1.0.2" + enhanced-resolve: "npm:^5.19.0" + es-module-lexer: "npm:^2.0.0" + eslint-scope: "npm:5.1.1" + events: "npm:^3.2.0" + glob-to-regexp: "npm:^0.4.1" + graceful-fs: "npm:^4.2.11" + json-parse-even-better-errors: "npm:^2.3.1" + loader-runner: "npm:^4.3.1" + mime-types: "npm:^2.1.27" + neo-async: "npm:^2.6.2" + schema-utils: "npm:^4.3.3" + tapable: "npm:^2.3.0" + terser-webpack-plugin: "npm:^5.3.16" + watchpack: "npm:^2.5.1" + webpack-sources: "npm:^3.3.3" + peerDependenciesMeta: + webpack-cli: + optional: true + bin: + webpack: bin/webpack.js + checksum: 10c0/4aea6b976485b5364e122f301c08f48efa84ddb2c0cb5d09f27445d1f2da0b9875cd889e41b58cac3ff05618a9c965be716df52586d151b5f52a7bbed7662174 + languageName: node + linkType: hard + "websocket-driver@npm:>=0.5.1, websocket-driver@npm:^0.7.4": version: 0.7.4 resolution: "websocket-driver@npm:0.7.4" @@ -16391,6 +20617,22 @@ __metadata: languageName: node linkType: hard +"whatwg-encoding@npm:^3.1.1": + version: 3.1.1 + resolution: "whatwg-encoding@npm:3.1.1" + dependencies: + iconv-lite: "npm:0.6.3" + checksum: 10c0/273b5f441c2f7fda3368a496c3009edbaa5e43b71b09728f90425e7f487e5cef9eb2b846a31bd760dd8077739c26faf6b5ca43a5f24033172b003b72cf61a93e + languageName: node + linkType: hard + +"whatwg-mimetype@npm:^4.0.0": + version: 4.0.0 + resolution: "whatwg-mimetype@npm:4.0.0" + checksum: 10c0/a773cdc8126b514d790bdae7052e8bf242970cebd84af62fb2f35a33411e78e981f6c0ab9ed1fe6ec5071b09d5340ac9178e05b52d35a9c4bcf558ba1b1551df + languageName: node + linkType: hard + "whatwg-url@npm:^5.0.0": version: 5.0.0 resolution: "whatwg-url@npm:5.0.0" @@ -16430,6 +20672,15 @@ __metadata: languageName: node linkType: hard +"windows-release@npm:^4.0.0": + version: 4.0.0 + resolution: "windows-release@npm:4.0.0" + dependencies: + execa: "npm:^4.0.2" + checksum: 10c0/5c0ce2603a85e25e9a5c78eb1ef646aac7036da2fb942643f2120b11fc33ed94fbcdd340b2abbf27daa522efc9e52df36fe95b1c03cd9acd8d6c6c39f88f106b + languageName: node + linkType: hard + "winston-transport@npm:^4.9.0": version: 4.9.0 resolution: "winston-transport@npm:4.9.0" @@ -16467,6 +20718,13 @@ __metadata: languageName: node linkType: hard +"wordwrap@npm:^1.0.0": + version: 1.0.0 + resolution: "wordwrap@npm:1.0.0" + checksum: 10c0/7ed2e44f3c33c5c3e3771134d2b0aee4314c9e49c749e37f464bf69f2bcdf0cbf9419ca638098e2717cff4875c47f56a007532f6111c3319f557a2ca91278e92 + languageName: node + linkType: hard + "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0": version: 7.0.0 resolution: "wrap-ansi@npm:7.0.0"