diff --git a/.env.example b/.env.example index 06d509a3ae..db09bb471f 100644 --- a/.env.example +++ b/.env.example @@ -64,6 +64,8 @@ CONSOLE_JSON=false DEBUG_LOGGING=true DEBUG_CONSOLE=false +# Set to true to enable agent debug logging +AGENT_DEBUG_LOGGING=false # Enable memory diagnostics (logs heap/RSS snapshots every 60s, auto-enabled with --inspect) # MEM_DIAG=true @@ -540,6 +542,8 @@ OPENID_ON_BEHALF_FLOW_USERINFO_SCOPE="user.read" # example for Scope Needed for OPENID_USE_END_SESSION_ENDPOINT= # URL to redirect to after OpenID logout (defaults to ${DOMAIN_CLIENT}/login) OPENID_POST_LOGOUT_REDIRECT_URI= +# Maximum logout URL length before using logout_hint instead of id_token_hint (default: 2000) +OPENID_MAX_LOGOUT_URL_LENGTH= #========================# # SharePoint Integration # @@ -623,6 +627,7 @@ EMAIL_PORT=25 EMAIL_ENCRYPTION= EMAIL_ENCRYPTION_HOSTNAME= EMAIL_ALLOW_SELFSIGNED= +# Leave both empty for SMTP servers that do not require authentication EMAIL_USERNAME= EMAIL_PASSWORD= EMAIL_FROM_NAME= @@ -677,7 +682,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 # @@ -849,3 +855,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/.gitignore b/.gitignore index 86d4a3ddae..ff2ae59633 100644 --- a/.gitignore +++ b/.gitignore @@ -154,16 +154,16 @@ claude-flow.config.json .swarm/ .hive-mind/ .claude-flow/ -memory/ -coordination/ -memory/claude-flow-data.json -memory/sessions/* -!memory/sessions/README.md -memory/agents/* -!memory/agents/README.md -coordination/memory_bank/* -coordination/subtasks/* -coordination/orchestration/* +/memory/ +/coordination/ +/memory/claude-flow-data.json +/memory/sessions/* +!/memory/sessions/README.md +/memory/agents/* +!/memory/agents/README.md +/coordination/memory_bank/* +/coordination/subtasks/* +/coordination/orchestration/* *.db *.db-journal *.db-wal @@ -171,5 +171,7 @@ coordination/orchestration/* *.sqlite-journal *.sqlite-wal claude-flow +.playwright-mcp/* # Removed Windows wrapper files per user request hive-mind-prompt-*.txt +CLAUDE.md diff --git a/.husky/pre-commit b/.husky/pre-commit index 23c736d1de..70fef90065 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,2 +1,3 @@ +#!/bin/sh [ -n "$CI" ] && exit 0 npx lint-staged --config ./.husky/lint-staged.config.js diff --git a/AGENTS.md b/AGENTS.md index 23b5fc0fbb..ec44607aa7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -149,7 +149,15 @@ Multi-line imports count total character length across all lines. Consolidate va - 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. -- Mock data-provider hooks and external dependencies. + +### 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. --- diff --git a/Dockerfile b/Dockerfile index 5019060ab7..19d275eb31 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,9 @@ -# v0.8.3-rc2 +# v0.8.4 # Base node image FROM node:20-alpine AS node -# Install jemalloc +RUN apk upgrade --no-cache RUN apk add --no-cache jemalloc RUN apk add --no-cache python3 py3-pip uv diff --git a/Dockerfile.multi b/Dockerfile.multi index 9178c184cb..bf5570f386 100644 --- a/Dockerfile.multi +++ b/Dockerfile.multi @@ -1,12 +1,12 @@ # Dockerfile.multi -# v0.8.3-rc2 +# v0.8.4 # Set configurable max-old-space-size with default ARG NODE_MAX_OLD_SPACE_SIZE=6144 # Base for all builds FROM node:20-alpine AS base-min -# Install jemalloc +RUN apk upgrade --no-cache RUN apk add --no-cache jemalloc # Set environment variable to use jemalloc ENV LD_PRELOAD=/usr/lib/libjemalloc.so.2 diff --git a/README.md b/README.md index e82b3ebc2c..7da34974e3 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,11 @@

+

+ English · + 中文 +

+

+ +

+ + + +

+ LibreChat +

+

+ +

+ English · + 中文 +

+ +

+ + + + + + + + + + + + +

+ +

+ + Deploy on Railway + + + Deploy on Zeabur + + + Deploy on Sealos + +

+ +

+ + 翻译进度 + +

+ + +# ✨ 功能 + +- 🖥️ **UI 与体验**:受 ChatGPT 启发,并具备更强的设计与功能。 + +- 🤖 **AI 模型选择**: + - Anthropic (Claude), AWS Bedrock, OpenAI, Azure OpenAI, Google, Vertex AI, OpenAI Responses API (包含 Azure) + - [自定义端点 (Custom Endpoints)](https://www.librechat.ai/docs/quick_start/custom_endpoints):LibreChat 支持任何兼容 OpenAI 规范的 API,无需代理。 + - 兼容[本地与远程 AI 服务商](https://www.librechat.ai/docs/configuration/librechat_yaml/ai_endpoints): + - Ollama, groq, Cohere, Mistral AI, Apple MLX, koboldcpp, together.ai, + - OpenRouter, Helicone, Perplexity, ShuttleAI, Deepseek, Qwen 等。 + +- 🔧 **[代码解释器 (Code Interpreter) API](https://www.librechat.ai/docs/features/code_interpreter)**: + - 安全的沙箱执行环境,支持 Python, Node.js (JS/TS), Go, C/C++, Java, PHP, Rust 和 Fortran。 + - 无缝文件处理:直接上传、处理并下载文件。 + - 隐私无忧:完全隔离且安全的执行环境。 + +- 🔦 **智能体与工具集成**: + - **[LibreChat 智能体 (Agents)](https://www.librechat.ai/docs/features/agents)**: + - 无代码定制助手:无需编程即可构建专业化的 AI 驱动助手。 + - 智能体市场:发现并部署社区构建的智能体。 + - 协作共享:与特定用户和群组共享智能体。 + - 灵活且可扩展:支持 MCP 服务器、工具、文件搜索、代码执行等。 + - 兼容自定义端点、OpenAI, Azure, Anthropic, AWS Bedrock, Google, Vertex AI, Responses API 等。 + - [支持模型上下文协议 (MCP)](https://modelcontextprotocol.io/clients#librechat) 用于工具调用。 + +- 🔍 **网页搜索**: + - 搜索互联网并检索相关信息以增强 AI 上下文。 + - 结合搜索提供商、内容爬虫和结果重排序,确保最佳检索效果。 + - **可定制 Jina 重排序**:配置自定义 Jina API URL 用于重排序服务。 + - **[了解更多 →](https://www.librechat.ai/docs/features/web_search)** + +- 🪄 **支持代码 Artifacts 的生成式 UI**: + - [代码 Artifacts](https://youtu.be/GfTj7O4gmd0?si=WJbdnemZpJzBrJo3) 允许在对话中直接创建 React 组件、HTML 页面和 Mermaid 图表。 + +- 🎨 **图像生成与编辑**: + - 使用 [GPT-Image-1](https://www.librechat.ai/docs/features/image_gen#1--openai-image-tools-recommended) 进行文生图与图生图。 + - 支持 [DALL-E (3/2)](https://www.librechat.ai/docs/features/image_gen#2--dalle-legacy), [Stable Diffusion](https://www.librechat.ai/docs/features/image_gen#3--stable-diffusion-local), [Flux](https://www.librechat.ai/docs/features/image_gen#4--flux) 或任何 [MCP 服务器](https://www.librechat.ai/docs/features/image_gen#5--model-context-protocol-mcp)。 + - 根据提示词生成惊艳的视觉效果,或通过指令精修现有图像。 + +- 💾 **预设与上下文管理**: + - 创建、保存并分享自定义预设。 + - 在对话中随时切换 AI 端点和预设。 + - 编辑、重新提交并通过对话分支继续消息。 + - 创建并与特定用户和群组共享提示词。 + - [消息与对话分叉 (Fork)](https://www.librechat.ai/docs/features/fork) 以实现高级上下文控制。 + +- 💬 **多模态与文件交互**: + - 使用 Claude 3, GPT-4.5, GPT-4o, o1, Llama-Vision 和 Gemini 上传并分析图像 📸。 + - 支持通过自定义端点、OpenAI, Azure, Anthropic, AWS Bedrock 和 Google 进行文件对话 🗃️。 + +- 🌎 **多语言 UI**: + - English, 中文 (简体), 中文 (繁體), العربية, Deutsch, Español, Français, Italiano + - Polski, Português (PT), Português (BR), Русский, 日本語, Svenska, 한국어, Tiếng Việt + - Türkçe, Nederlands, עברית, Català, Čeština, Dansk, Eesti, فارسی + - Suomi, Magyar, Հայերեն, Bahasa Indonesia, ქართული, Latviešu, ไทย, ئۇيغۇرچە + +- 🧠 **推理 UI**: + - 针对 DeepSeek-R1 等思维链/推理 AI 模型的动态推理 UI。 + +- 🎨 **可定制界面**: + - 可定制的下拉菜单和界面,同时适配高级用户和初学者。 + +- 🌊 **[可恢复流 (Resumable Streams)](https://www.librechat.ai/docs/features/resumable_streams)**: + - 永不丢失响应:AI 响应在连接中断后自动重连并继续。 + - 多标签页与多设备同步:在多个标签页打开同一对话,或在另一设备上继续。 + - 生产级可靠性:支持从单机部署到基于 Redis 的水平扩展。 + +- 🗣️ **语音与音频**: + - 通过语音转文字和文字转语音实现免提对话。 + - 自动发送并播放音频。 + - 支持 OpenAI, Azure OpenAI 和 Elevenlabs。 + +- 📥 **导入与导出对话**: + - 从 LibreChat, ChatGPT, Chatbot UI 导入对话。 + - 将对话导出为截图、Markdown、文本、JSON。 + +- 🔍 **搜索与发现**: + - 搜索所有消息和对话。 + +- 👥 **多用户与安全访问**: + - 支持 OAuth2, LDAP 和电子邮件登录的多用户安全认证。 + - 内置审核系统和 Token 消耗管理工具。 + +- ⚙️ **配置与部署**: + - 支持代理、反向代理、Docker 及多种部署选项。 + - 可完全本地运行或部署在云端。 + +- 📖 **开源与社区**: + - 完全开源且在公众监督下开发。 + - 社区驱动的开发、支持与反馈。 + +[查看我们的文档了解更多功能详情](https://docs.librechat.ai/) 📚 + +## 🪶 LibreChat:全方位的 AI 对话平台 + +LibreChat 是一个自托管的 AI 对话平台,在一个注重隐私的统一界面中整合了所有主流 AI 服务商。 + +除了对话功能外,LibreChat 还提供 AI 智能体、模型上下文协议 (MCP) 支持、Artifacts、代码解释器、自定义操作、对话搜索,以及企业级多用户认证。 + +开源、活跃开发中,专为重视 AI 基础设施自主可控的用户而构建。 + +--- + +## 🌐 资源 + +**GitHub 仓库:** + - **RAG API:** [github.com/danny-avila/rag_api](https://github.com/danny-avila/rag_api) + - **网站:** [github.com/LibreChat-AI/librechat.ai](https://github.com/LibreChat-AI/librechat.ai) + +**其他:** + - **官方网站:** [librechat.ai](https://librechat.ai) + - **帮助文档:** [librechat.ai/docs](https://librechat.ai/docs) + - **博客:** [librechat.ai/blog](https://librechat.ai/blog) + +--- + +## 📝 更新日志 + +访问发布页面和更新日志以了解最新动态: +- [发布页面 (Releases)](https://github.com/danny-avila/LibreChat/releases) +- [更新日志 (Changelog)](https://www.librechat.ai/changelog) + +**⚠️ 在更新前请务必查看[更新日志](https://www.librechat.ai/changelog)以了解破坏性更改。** + +--- + +## ⭐ Star 历史 + +

+ + Star History Chart + +

+

+ + danny-avila%2FLibreChat | Trendshift + + + ROSS Index - 2024年第一季度增长最快的开源初创公司 | Runa Capital + +

+ +--- + +## ✨ 贡献 + +欢迎任何形式的贡献、建议、错误报告和修复! + +对于新功能、组件或扩展,请在发送 PR 前开启 issue 进行讨论。 + +如果您想帮助我们将 LibreChat 翻译成您的母语,我们非常欢迎!改进翻译不仅能让全球用户更轻松地使用 LibreChat,还能提升整体用户体验。请查看我们的[翻译指南](https://www.librechat.ai/docs/translation)。 + +--- + +## 💖 感谢所有贡献者 + + + + + +--- + +## 🎉 特别鸣谢 + +感谢 [Locize](https://locize.com) 提供的翻译管理工具,支持 LibreChat 的多语言功能。 + +

+ + Locize Logo + +

diff --git a/api/app/clients/BaseClient.js b/api/app/clients/BaseClient.js index 8f931f8a5e..ae2d362773 100644 --- a/api/app/clients/BaseClient.js +++ b/api/app/clients/BaseClient.js @@ -3,6 +3,7 @@ const fetch = require('node-fetch'); const { logger } = require('@librechat/data-schemas'); const { countTokens, + checkBalance, getBalanceConfig, buildMessageFiles, extractFileContext, @@ -12,7 +13,6 @@ const { } = require('@librechat/api'); const { Constants, - ErrorTypes, FileSources, ContentTypes, excludedKeys, @@ -23,18 +23,10 @@ const { supportsBalanceCheck, isBedrockDocumentType, } = require('librechat-data-provider'); -const { - updateMessage, - getMessages, - saveMessage, - saveConvo, - getConvo, - getFiles, -} = require('~/models'); const { getStrategyFunctions } = require('~/server/services/Files/strategies'); -const { checkBalance } = require('~/models/balanceMethods'); -const { truncateToolCallOutputs } = require('./prompts'); +const { logViolation } = require('~/cache'); const TextStream = require('./TextStream'); +const db = require('~/models'); class BaseClient { constructor(apiKey, options = {}) { @@ -339,45 +331,6 @@ class BaseClient { return payload; } - async handleTokenCountMap(tokenCountMap) { - if (this.clientName === EModelEndpoint.agents) { - return; - } - if (this.currentMessages.length === 0) { - return; - } - - for (let i = 0; i < this.currentMessages.length; i++) { - // Skip the last message, which is the user message. - if (i === this.currentMessages.length - 1) { - break; - } - - const message = this.currentMessages[i]; - const { messageId } = message; - const update = {}; - - if (messageId === tokenCountMap.summaryMessage?.messageId) { - logger.debug(`[BaseClient] Adding summary props to ${messageId}.`); - - update.summary = tokenCountMap.summaryMessage.content; - update.summaryTokenCount = tokenCountMap.summaryMessage.tokenCount; - } - - if (message.tokenCount && !update.summaryTokenCount) { - logger.debug(`[BaseClient] Skipping ${messageId}: already had a token count.`); - continue; - } - - const tokenCount = tokenCountMap[messageId]; - if (tokenCount) { - message.tokenCount = tokenCount; - update.tokenCount = tokenCount; - await this.updateMessageInDatabase({ messageId, ...update }); - } - } - } - concatenateMessages(messages) { return messages.reduce((acc, message) => { const nameOrRole = message.name ?? message.role; @@ -448,154 +401,6 @@ class BaseClient { }; } - async handleContextStrategy({ - instructions, - orderedMessages, - formattedMessages, - buildTokenMap = true, - }) { - let _instructions; - let tokenCount; - - if (instructions) { - ({ tokenCount, ..._instructions } = instructions); - } - - _instructions && logger.debug('[BaseClient] instructions tokenCount: ' + tokenCount); - if (tokenCount && tokenCount > this.maxContextTokens) { - const info = `${tokenCount} / ${this.maxContextTokens}`; - const errorMessage = `{ "type": "${ErrorTypes.INPUT_LENGTH}", "info": "${info}" }`; - logger.warn(`Instructions token count exceeds max token count (${info}).`); - throw new Error(errorMessage); - } - - if (this.clientName === EModelEndpoint.agents) { - const { dbMessages, editedIndices } = truncateToolCallOutputs( - orderedMessages, - this.maxContextTokens, - this.getTokenCountForMessage.bind(this), - ); - - if (editedIndices.length > 0) { - logger.debug('[BaseClient] Truncated tool call outputs:', editedIndices); - for (const index of editedIndices) { - formattedMessages[index].content = dbMessages[index].content; - } - orderedMessages = dbMessages; - } - } - - let orderedWithInstructions = this.addInstructions(orderedMessages, instructions); - - let { context, remainingContextTokens, messagesToRefine } = - await this.getMessagesWithinTokenLimit({ - messages: orderedWithInstructions, - instructions, - }); - - logger.debug('[BaseClient] Context Count (1/2)', { - remainingContextTokens, - maxContextTokens: this.maxContextTokens, - }); - - let summaryMessage; - let summaryTokenCount; - let { shouldSummarize } = this; - - // Calculate the difference in length to determine how many messages were discarded if any - let payload; - let { length } = formattedMessages; - length += instructions != null ? 1 : 0; - const diff = length - context.length; - const firstMessage = orderedWithInstructions[0]; - const usePrevSummary = - shouldSummarize && - diff === 1 && - firstMessage?.summary && - this.previous_summary.messageId === firstMessage.messageId; - - if (diff > 0) { - payload = formattedMessages.slice(diff); - logger.debug( - `[BaseClient] Difference between original payload (${length}) and context (${context.length}): ${diff}`, - ); - } - - payload = this.addInstructions(payload ?? formattedMessages, _instructions); - - const latestMessage = orderedWithInstructions[orderedWithInstructions.length - 1]; - if (payload.length === 0 && !shouldSummarize && latestMessage) { - const info = `${latestMessage.tokenCount} / ${this.maxContextTokens}`; - const errorMessage = `{ "type": "${ErrorTypes.INPUT_LENGTH}", "info": "${info}" }`; - logger.warn(`Prompt token count exceeds max token count (${info}).`); - throw new Error(errorMessage); - } else if ( - _instructions && - payload.length === 1 && - payload[0].content === _instructions.content - ) { - const info = `${tokenCount + 3} / ${this.maxContextTokens}`; - const errorMessage = `{ "type": "${ErrorTypes.INPUT_LENGTH}", "info": "${info}" }`; - logger.warn( - `Including instructions, the prompt token count exceeds remaining max token count (${info}).`, - ); - throw new Error(errorMessage); - } - - if (usePrevSummary) { - summaryMessage = { role: 'system', content: firstMessage.summary }; - summaryTokenCount = firstMessage.summaryTokenCount; - payload.unshift(summaryMessage); - remainingContextTokens -= summaryTokenCount; - } else if (shouldSummarize && messagesToRefine.length > 0) { - ({ summaryMessage, summaryTokenCount } = await this.summarizeMessages({ - messagesToRefine, - remainingContextTokens, - })); - summaryMessage && payload.unshift(summaryMessage); - remainingContextTokens -= summaryTokenCount; - } - - // Make sure to only continue summarization logic if the summary message was generated - shouldSummarize = summaryMessage != null && shouldSummarize === true; - - logger.debug('[BaseClient] Context Count (2/2)', { - remainingContextTokens, - maxContextTokens: this.maxContextTokens, - }); - - /** @type {Record | undefined} */ - let tokenCountMap; - if (buildTokenMap) { - const currentPayload = shouldSummarize ? orderedWithInstructions : context; - tokenCountMap = currentPayload.reduce((map, message, index) => { - const { messageId } = message; - if (!messageId) { - return map; - } - - if (shouldSummarize && index === messagesToRefine.length - 1 && !usePrevSummary) { - map.summaryMessage = { ...summaryMessage, messageId, tokenCount: summaryTokenCount }; - } - - map[messageId] = currentPayload[index].tokenCount; - return map; - }, {}); - } - - const promptTokens = this.maxContextTokens - remainingContextTokens; - - logger.debug('[BaseClient] tokenCountMap:', tokenCountMap); - logger.debug('[BaseClient]', { - promptTokens, - remainingContextTokens, - payloadSize: payload.length, - maxContextTokens: this.maxContextTokens, - }); - - return { payload, tokenCountMap, promptTokens, messages: orderedWithInstructions }; - } - async sendMessage(message, opts = {}) { const appConfig = this.options.req?.config; /** @type {Promise} */ @@ -664,17 +469,13 @@ class BaseClient { opts, ); - if (tokenCountMap) { - if (tokenCountMap[userMessage.messageId]) { - userMessage.tokenCount = tokenCountMap[userMessage.messageId]; - logger.debug('[BaseClient] userMessage', { - messageId: userMessage.messageId, - tokenCount: userMessage.tokenCount, - conversationId: userMessage.conversationId, - }); - } - - this.handleTokenCountMap(tokenCountMap); + if (tokenCountMap && tokenCountMap[userMessage.messageId]) { + userMessage.tokenCount = tokenCountMap[userMessage.messageId]; + logger.debug('[BaseClient] userMessage', { + messageId: userMessage.messageId, + tokenCount: userMessage.tokenCount, + conversationId: userMessage.conversationId, + }); } if (!isEdited && !this.skipSaveUserMessage) { @@ -700,18 +501,26 @@ class BaseClient { balanceConfig?.enabled && supportsBalanceCheck[this.options.endpointType ?? this.options.endpoint] ) { - await checkBalance({ - req: this.options.req, - res: this.options.res, - txData: { - user: this.user, - tokenType: 'prompt', - amount: promptTokens, - endpoint: this.options.endpoint, - model: this.modelOptions?.model ?? this.model, - endpointTokenConfig: this.options.endpointTokenConfig, + await checkBalance( + { + req: this.options.req, + res: this.options.res, + txData: { + user: this.user, + tokenType: 'prompt', + amount: promptTokens, + endpoint: this.options.endpoint, + model: this.modelOptions?.model ?? this.model, + endpointTokenConfig: this.options.endpointTokenConfig, + }, }, - }); + { + logViolation, + getMultiplier: db.getMultiplier, + findBalanceByUser: db.findBalanceByUser, + createAutoRefillTransaction: db.createAutoRefillTransaction, + }, + ); } const { completion, metadata } = await this.sendCompletion(payload, opts); @@ -764,12 +573,7 @@ class BaseClient { responseMessage.text = completion.join(''); } - if ( - tokenCountMap && - this.recordTokenUsage && - this.getTokenCountForResponse && - this.getTokenCount - ) { + if (tokenCountMap && this.recordTokenUsage && this.getTokenCountForResponse) { let completionTokens; /** @@ -782,13 +586,6 @@ class BaseClient { if (usage != null && Number(usage[this.outputTokensKey]) > 0) { responseMessage.tokenCount = usage[this.outputTokensKey]; completionTokens = responseMessage.tokenCount; - await this.updateUserMessageTokenCount({ - usage, - tokenCountMap, - userMessage, - userMessagePromise, - opts, - }); } else { responseMessage.tokenCount = this.getTokenCountForResponse(responseMessage); completionTokens = responseMessage.tokenCount; @@ -815,6 +612,27 @@ class BaseClient { await userMessagePromise; } + if ( + this.contextMeta?.calibrationRatio > 0 && + this.contextMeta.calibrationRatio !== 1 && + userMessage.tokenCount > 0 + ) { + const calibrated = Math.round(userMessage.tokenCount * this.contextMeta.calibrationRatio); + if (calibrated !== userMessage.tokenCount) { + logger.debug('[BaseClient] Calibrated user message tokenCount', { + messageId: userMessage.messageId, + raw: userMessage.tokenCount, + calibrated, + ratio: this.contextMeta.calibrationRatio, + }); + userMessage.tokenCount = calibrated; + await this.updateMessageInDatabase({ + messageId: userMessage.messageId, + tokenCount: calibrated, + }); + } + } + if (this.artifactPromises) { responseMessage.attachments = (await Promise.all(this.artifactPromises)).filter((a) => a); } @@ -827,6 +645,10 @@ class BaseClient { } } + if (this.contextMeta) { + responseMessage.contextMeta = this.contextMeta; + } + responseMessage.databasePromise = this.saveMessageToDatabase( responseMessage, saveOptions, @@ -837,79 +659,10 @@ class BaseClient { return responseMessage; } - /** - * Stream usage should only be used for user message token count re-calculation if: - * - The stream usage is available, with input tokens greater than 0, - * - the client provides a function to calculate the current token count, - * - files are being resent with every message (default behavior; or if `false`, with no attachments), - * - the `promptPrefix` (custom instructions) is not set. - * - * In these cases, the legacy token estimations would be more accurate. - * - * TODO: included system messages in the `orderedMessages` accounting, potentially as a - * separate message in the UI. ChatGPT does this through "hidden" system messages. - * @param {object} params - * @param {StreamUsage} params.usage - * @param {Record} params.tokenCountMap - * @param {TMessage} params.userMessage - * @param {Promise} params.userMessagePromise - * @param {object} params.opts - */ - async updateUserMessageTokenCount({ - usage, - tokenCountMap, - userMessage, - userMessagePromise, - opts, - }) { - /** @type {boolean} */ - const shouldUpdateCount = - this.calculateCurrentTokenCount != null && - Number(usage[this.inputTokensKey]) > 0 && - (this.options.resendFiles || - (!this.options.resendFiles && !this.options.attachments?.length)) && - !this.options.promptPrefix; - - if (!shouldUpdateCount) { - return; - } - - const userMessageTokenCount = this.calculateCurrentTokenCount({ - currentMessageId: userMessage.messageId, - tokenCountMap, - usage, - }); - - if (userMessageTokenCount === userMessage.tokenCount) { - return; - } - - userMessage.tokenCount = userMessageTokenCount; - /* - Note: `AgentController` saves the user message if not saved here - (noted by `savedMessageIds`), so we update the count of its `userMessage` reference - */ - if (typeof opts?.getReqData === 'function') { - opts.getReqData({ - userMessage, - }); - } - /* - Note: we update the user message to be sure it gets the calculated token count; - though `AgentController` saves the user message if not saved here - (noted by `savedMessageIds`), EditController does not - */ - await userMessagePromise; - await this.updateMessageInDatabase({ - messageId: userMessage.messageId, - tokenCount: userMessageTokenCount, - }); - } - async loadHistory(conversationId, parentMessageId = null) { logger.debug('[BaseClient] Loading history:', { conversationId, parentMessageId }); - const messages = (await getMessages({ conversationId })) ?? []; + const messages = (await db.getMessages({ conversationId })) ?? []; if (messages.length === 0) { return []; @@ -932,10 +685,24 @@ class BaseClient { return _messages; } - // Find the latest message with a 'summary' property for (let i = _messages.length - 1; i >= 0; i--) { - if (_messages[i]?.summary) { - this.previous_summary = _messages[i]; + const msg = _messages[i]; + if (!msg) { + continue; + } + + const summaryBlock = BaseClient.findSummaryContentBlock(msg); + if (summaryBlock) { + this.previous_summary = { + ...msg, + summary: BaseClient.getSummaryText(summaryBlock), + summaryTokenCount: summaryBlock.tokenCount, + }; + break; + } + + if (msg.summary) { + this.previous_summary = msg; break; } } @@ -965,8 +732,13 @@ class BaseClient { } const hasAddedConvo = this.options?.req?.body?.addedConvo != null; - const savedMessage = await saveMessage( - this.options?.req, + const reqCtx = { + userId: this.options?.req?.user?.id, + isTemporary: this.options?.req?.body?.isTemporary, + interfaceConfig: this.options?.req?.config?.interfaceConfig, + }; + const savedMessage = await db.saveMessage( + reqCtx, { ...message, endpoint: this.options.endpoint, @@ -991,7 +763,7 @@ class BaseClient { const existingConvo = this.fetchedConvo === true ? null - : await getConvo(this.options?.req?.user?.id, message.conversationId); + : await db.getConvo(this.options?.req?.user?.id, message.conversationId); const unsetFields = {}; const exceptions = new Set(['spec', 'iconURL']); @@ -1018,7 +790,7 @@ class BaseClient { } } - const conversation = await saveConvo(this.options?.req, fieldsToKeep, { + const conversation = await db.saveConvo(reqCtx, fieldsToKeep, { context: 'api/app/clients/BaseClient.js - saveMessageToDatabase #saveConvo', unsetFields, }); @@ -1031,7 +803,35 @@ class BaseClient { * @param {Partial} message */ async updateMessageInDatabase(message) { - await updateMessage(this.options.req, message); + await db.updateMessage(this.options?.req?.user?.id, message); + } + + /** Extracts text from a summary block (handles both legacy `text` field and new `content` array format). */ + static getSummaryText(summaryBlock) { + if (Array.isArray(summaryBlock.content)) { + return summaryBlock.content.map((b) => b.text ?? '').join(''); + } + if (typeof summaryBlock.content === 'string') { + return summaryBlock.content; + } + return summaryBlock.text ?? ''; + } + + /** Finds the last summary content block in a message's content array (last-summary-wins). */ + static findSummaryContentBlock(message) { + if (!Array.isArray(message?.content)) { + return null; + } + let lastSummary = null; + for (const part of message.content) { + if ( + part?.type === ContentTypes.SUMMARY && + BaseClient.getSummaryText(part).trim().length > 0 + ) { + lastSummary = part; + } + } + return lastSummary; } /** @@ -1088,20 +888,35 @@ class BaseClient { break; } - if (summary && message.summary) { - message.role = 'system'; - message.text = message.summary; + let resolved = message; + let hasSummary = false; + if (summary) { + const summaryBlock = BaseClient.findSummaryContentBlock(message); + if (summaryBlock) { + const summaryText = BaseClient.getSummaryText(summaryBlock); + resolved = { + ...message, + role: 'system', + content: [{ type: ContentTypes.TEXT, text: summaryText }], + tokenCount: summaryBlock.tokenCount, + }; + hasSummary = true; + } else if (message.summary) { + resolved = { + ...message, + role: 'system', + content: [{ type: ContentTypes.TEXT, text: message.summary }], + tokenCount: message.summaryTokenCount ?? message.tokenCount, + }; + hasSummary = true; + } } - if (summary && message.summaryTokenCount) { - message.tokenCount = message.summaryTokenCount; - } - - const shouldMap = mapMethod != null && (mapCondition != null ? mapCondition(message) : true); - const processedMessage = shouldMap ? mapMethod(message) : message; + const shouldMap = mapMethod != null && (mapCondition != null ? mapCondition(resolved) : true); + const processedMessage = shouldMap ? mapMethod(resolved) : resolved; orderedMessages.push(processedMessage); - if (summary && message.summary) { + if (hasSummary) { break; } @@ -1431,7 +1246,7 @@ class BaseClient { return message; } - const files = await getFiles( + const files = await db.getFiles( { file_id: { $in: fileIds }, }, diff --git a/api/app/clients/prompts/truncate.js b/api/app/clients/prompts/truncate.js index 564b39efeb..e744b40daa 100644 --- a/api/app/clients/prompts/truncate.js +++ b/api/app/clients/prompts/truncate.js @@ -37,79 +37,4 @@ function smartTruncateText(text, maxLength = MAX_CHAR) { return text; } -/** - * @param {TMessage[]} _messages - * @param {number} maxContextTokens - * @param {function({role: string, content: TMessageContent[]}): number} getTokenCountForMessage - * - * @returns {{ - * dbMessages: TMessage[], - * editedIndices: number[] - * }} - */ -function truncateToolCallOutputs(_messages, maxContextTokens, getTokenCountForMessage) { - const THRESHOLD_PERCENTAGE = 0.5; - const targetTokenLimit = maxContextTokens * THRESHOLD_PERCENTAGE; - - let currentTokenCount = 3; - const messages = [..._messages]; - const processedMessages = []; - let currentIndex = messages.length; - const editedIndices = new Set(); - while (messages.length > 0) { - currentIndex--; - const message = messages.pop(); - currentTokenCount += message.tokenCount; - if (currentTokenCount < targetTokenLimit) { - processedMessages.push(message); - continue; - } - - if (!message.content || !Array.isArray(message.content)) { - processedMessages.push(message); - continue; - } - - const toolCallIndices = message.content - .map((item, index) => (item.type === 'tool_call' ? index : -1)) - .filter((index) => index !== -1) - .reverse(); - - if (toolCallIndices.length === 0) { - processedMessages.push(message); - continue; - } - - const newContent = [...message.content]; - - // Truncate all tool outputs since we're over threshold - for (const index of toolCallIndices) { - const toolCall = newContent[index].tool_call; - if (!toolCall || !toolCall.output) { - continue; - } - - editedIndices.add(currentIndex); - - newContent[index] = { - ...newContent[index], - tool_call: { - ...toolCall, - output: '[OUTPUT_OMITTED_FOR_BREVITY]', - }, - }; - } - - const truncatedMessage = { - ...message, - content: newContent, - tokenCount: getTokenCountForMessage({ role: 'assistant', content: newContent }), - }; - - processedMessages.push(truncatedMessage); - } - - return { dbMessages: processedMessages.reverse(), editedIndices: Array.from(editedIndices) }; -} - -module.exports = { truncateText, smartTruncateText, truncateToolCallOutputs }; +module.exports = { truncateText, smartTruncateText }; diff --git a/api/app/clients/specs/BaseClient.test.js b/api/app/clients/specs/BaseClient.test.js index f13c9979ac..edbbcaa87b 100644 --- a/api/app/clients/specs/BaseClient.test.js +++ b/api/app/clients/specs/BaseClient.test.js @@ -355,7 +355,8 @@ describe('BaseClient', () => { id: '3', parentMessageId: '2', role: 'system', - text: 'Summary for Message 3', + text: 'Message 3', + content: [{ type: 'text', text: 'Summary for Message 3' }], summary: 'Summary for Message 3', }, { id: '4', parentMessageId: '3', text: 'Message 4' }, @@ -380,7 +381,8 @@ describe('BaseClient', () => { id: '4', parentMessageId: '3', role: 'system', - text: 'Summary for Message 4', + text: 'Message 4', + content: [{ type: 'text', text: 'Summary for Message 4' }], summary: 'Summary for Message 4', }, { id: '5', parentMessageId: '4', text: 'Message 5' }, @@ -405,12 +407,123 @@ describe('BaseClient', () => { id: '4', parentMessageId: '3', role: 'system', - text: 'Summary for Message 4', + text: 'Message 4', + content: [{ type: 'text', text: 'Summary for Message 4' }], summary: 'Summary for Message 4', }, { id: '5', parentMessageId: '4', text: 'Message 5' }, ]); }); + + it('should detect summary content block and use it over legacy fields (summary mode)', () => { + const messagesWithContentBlock = [ + { id: '3', parentMessageId: '2', text: 'Message 3' }, + { + id: '2', + parentMessageId: '1', + text: 'Message 2', + content: [ + { type: 'text', text: 'Original text' }, + { type: 'summary', text: 'Content block summary', tokenCount: 42 }, + ], + }, + { id: '1', parentMessageId: null, text: 'Message 1' }, + ]; + const result = TestClient.constructor.getMessagesForConversation({ + messages: messagesWithContentBlock, + parentMessageId: '3', + summary: true, + }); + expect(result).toHaveLength(2); + expect(result[0].role).toBe('system'); + expect(result[0].content).toEqual([{ type: 'text', text: 'Content block summary' }]); + expect(result[0].tokenCount).toBe(42); + }); + + it('should prefer content block summary over legacy summary field', () => { + const messagesWithBoth = [ + { id: '2', parentMessageId: '1', text: 'Message 2' }, + { + id: '1', + parentMessageId: null, + text: 'Message 1', + summary: 'Legacy summary', + summaryTokenCount: 10, + content: [{ type: 'summary', text: 'Content block summary', tokenCount: 20 }], + }, + ]; + const result = TestClient.constructor.getMessagesForConversation({ + messages: messagesWithBoth, + parentMessageId: '2', + summary: true, + }); + expect(result).toHaveLength(2); + expect(result[0].content).toEqual([{ type: 'text', text: 'Content block summary' }]); + expect(result[0].tokenCount).toBe(20); + }); + + it('should fallback to legacy summary when no content block exists', () => { + const messagesWithLegacy = [ + { id: '2', parentMessageId: '1', text: 'Message 2' }, + { + id: '1', + parentMessageId: null, + text: 'Message 1', + summary: 'Legacy summary only', + summaryTokenCount: 15, + }, + ]; + const result = TestClient.constructor.getMessagesForConversation({ + messages: messagesWithLegacy, + parentMessageId: '2', + summary: true, + }); + expect(result).toHaveLength(2); + expect(result[0].content).toEqual([{ type: 'text', text: 'Legacy summary only' }]); + expect(result[0].tokenCount).toBe(15); + }); + }); + + describe('findSummaryContentBlock', () => { + it('should find a summary block in the content array', () => { + const message = { + content: [ + { type: 'text', text: 'some text' }, + { type: 'summary', text: 'Summary of conversation', tokenCount: 50 }, + ], + }; + const result = TestClient.constructor.findSummaryContentBlock(message); + expect(result).toBeTruthy(); + expect(result.text).toBe('Summary of conversation'); + expect(result.tokenCount).toBe(50); + }); + + it('should return null when no summary block exists', () => { + const message = { + content: [ + { type: 'text', text: 'some text' }, + { type: 'tool_call', tool_call: {} }, + ], + }; + expect(TestClient.constructor.findSummaryContentBlock(message)).toBeNull(); + }); + + it('should return null for string content', () => { + const message = { content: 'just a string' }; + expect(TestClient.constructor.findSummaryContentBlock(message)).toBeNull(); + }); + + it('should return null for missing content', () => { + expect(TestClient.constructor.findSummaryContentBlock({})).toBeNull(); + expect(TestClient.constructor.findSummaryContentBlock(null)).toBeNull(); + }); + + it('should skip summary blocks with no text', () => { + const message = { + content: [{ type: 'summary', tokenCount: 10 }], + }; + expect(TestClient.constructor.findSummaryContentBlock(message)).toBeNull(); + }); }); describe('sendMessage', () => { diff --git a/api/app/clients/tools/structured/DALLE3.js b/api/app/clients/tools/structured/DALLE3.js index 26610f73ba..c48db1d764 100644 --- a/api/app/clients/tools/structured/DALLE3.js +++ b/api/app/clients/tools/structured/DALLE3.js @@ -51,6 +51,10 @@ class DALLE3 extends Tool { this.fileStrategy = fields.fileStrategy; /** @type {boolean} */ this.isAgent = fields.isAgent; + if (this.isAgent) { + /** Ensures LangChain maps [content, artifact] tuple to ToolMessage fields instead of serializing it into content. */ + this.responseFormat = 'content_and_artifact'; + } if (fields.processFileURL) { /** @type {processFileURL} Necessary for output to contain all image metadata. */ this.processFileURL = fields.processFileURL.bind(this); diff --git a/api/app/clients/tools/structured/FluxAPI.js b/api/app/clients/tools/structured/FluxAPI.js index 56f86a707d..f8341f7904 100644 --- a/api/app/clients/tools/structured/FluxAPI.js +++ b/api/app/clients/tools/structured/FluxAPI.js @@ -113,6 +113,10 @@ class FluxAPI extends Tool { /** @type {boolean} **/ this.isAgent = fields.isAgent; + if (this.isAgent) { + /** Ensures LangChain maps [content, artifact] tuple to ToolMessage fields instead of serializing it into content. */ + this.responseFormat = 'content_and_artifact'; + } this.returnMetadata = fields.returnMetadata ?? false; if (fields.processFileURL) { @@ -524,10 +528,40 @@ class FluxAPI extends Tool { return this.returnValue('No image data received from Flux API.'); } - // Try saving the image locally const imageUrl = resultData.sample; const imageName = `img-${uuidv4()}.png`; + if (this.isAgent) { + try { + const fetchOptions = {}; + if (process.env.PROXY) { + fetchOptions.agent = new HttpsProxyAgent(process.env.PROXY); + } + const imageResponse = await fetch(imageUrl, fetchOptions); + const arrayBuffer = await imageResponse.arrayBuffer(); + const base64 = Buffer.from(arrayBuffer).toString('base64'); + const content = [ + { + type: ContentTypes.IMAGE_URL, + image_url: { + url: `data:image/png;base64,${base64}`, + }, + }, + ]; + + const response = [ + { + type: ContentTypes.TEXT, + text: displayMessage, + }, + ]; + return [response, { content }]; + } catch (error) { + logger.error('[FluxAPI] Error processing finetuned image for agent:', error); + return this.returnValue(`Failed to process the finetuned image. ${error.message}`); + } + } + try { logger.debug('[FluxAPI] Saving finetuned image:', imageUrl); const result = await this.processFileURL({ @@ -541,12 +575,6 @@ class FluxAPI extends Tool { logger.debug('[FluxAPI] Finetuned image saved to path:', result.filepath); - // Calculate cost based on endpoint - const endpointKey = endpoint.includes('ultra') - ? 'FLUX_PRO_1_1_ULTRA_FINETUNED' - : 'FLUX_PRO_FINETUNED'; - const cost = FluxAPI.PRICING[endpointKey] || 0; - // Return the result based on returnMetadata flag this.result = this.returnMetadata ? result : this.wrapInMarkdown(result.filepath); return this.returnValue(this.result); } catch (error) { diff --git a/api/app/clients/tools/structured/GeminiImageGen.js b/api/app/clients/tools/structured/GeminiImageGen.js index 0bd1e302ed..f197f1d41b 100644 --- a/api/app/clients/tools/structured/GeminiImageGen.js +++ b/api/app/clients/tools/structured/GeminiImageGen.js @@ -13,8 +13,7 @@ const { getTransactionsConfig, } = require('@librechat/api'); const { getStrategyFunctions } = require('~/server/services/Files/strategies'); -const { spendTokens } = require('~/models/spendTokens'); -const { getFiles } = require('~/models/File'); +const { spendTokens, getFiles } = require('~/models'); /** * Configure proxy support for Google APIs diff --git a/api/app/clients/tools/structured/StableDiffusion.js b/api/app/clients/tools/structured/StableDiffusion.js index d7a7a4d96b..8cf4b141bb 100644 --- a/api/app/clients/tools/structured/StableDiffusion.js +++ b/api/app/clients/tools/structured/StableDiffusion.js @@ -43,6 +43,10 @@ class StableDiffusionAPI extends Tool { this.returnMetadata = fields.returnMetadata ?? false; /** @type {boolean} */ this.isAgent = fields.isAgent; + if (this.isAgent) { + /** Ensures LangChain maps [content, artifact] tuple to ToolMessage fields instead of serializing it into content. */ + this.responseFormat = 'content_and_artifact'; + } if (fields.uploadImageBuffer) { /** @type {uploadImageBuffer} Necessary for output to contain all image metadata. */ this.uploadImageBuffer = fields.uploadImageBuffer.bind(this); @@ -115,7 +119,7 @@ class StableDiffusionAPI extends Tool { generationResponse = await axios.post(`${url}/sdapi/v1/txt2img`, payload); } catch (error) { logger.error('[StableDiffusion] Error while generating image:', error); - return 'Error making API request.'; + return this.returnValue('Error making API request.'); } const image = generationResponse.data.images[0]; 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/structured/specs/imageTools-agent.spec.js b/api/app/clients/tools/structured/specs/imageTools-agent.spec.js new file mode 100644 index 0000000000..b82dd87b3f --- /dev/null +++ b/api/app/clients/tools/structured/specs/imageTools-agent.spec.js @@ -0,0 +1,294 @@ +/** + * Regression tests for image tool agent mode — verifies that invoke() returns + * a ToolMessage with base64 in artifact.content rather than serialized into content. + * + * Root cause: DALLE3/FluxAPI/StableDiffusion extend LangChain's Tool but did not + * set responseFormat = 'content_and_artifact'. LangChain's invoke() would then + * JSON.stringify the entire [content, artifact] tuple into ToolMessage.content, + * dumping base64 into token counting and causing context exhaustion. + */ + +const axios = require('axios'); +const OpenAI = require('openai'); +const undici = require('undici'); +const fetch = require('node-fetch'); +const { ToolMessage } = require('@langchain/core/messages'); +const { ContentTypes } = require('librechat-data-provider'); +const StableDiffusionAPI = require('../StableDiffusion'); +const FluxAPI = require('../FluxAPI'); +const DALLE3 = require('../DALLE3'); + +jest.mock('axios'); +jest.mock('openai'); +jest.mock('node-fetch'); +jest.mock('undici', () => ({ + ProxyAgent: jest.fn(), + fetch: jest.fn(), +})); +jest.mock('@librechat/data-schemas', () => ({ + logger: { info: jest.fn(), warn: jest.fn(), debug: jest.fn(), error: jest.fn() }, +})); +jest.mock('path', () => ({ + resolve: jest.fn(), + join: jest.fn().mockReturnValue('/mock/path'), + relative: jest.fn().mockReturnValue('relative/path'), + extname: jest.fn().mockReturnValue('.png'), +})); +jest.mock('fs', () => ({ + existsSync: jest.fn().mockReturnValue(true), + mkdirSync: jest.fn(), + promises: { writeFile: jest.fn(), readFile: jest.fn(), unlink: jest.fn() }, +})); + +const FAKE_BASE64 = 'aGVsbG8='; + +const makeToolCall = (name, args) => ({ + id: 'call_test_123', + name, + args, + type: 'tool_call', +}); + +describe('image tools - agent mode ToolMessage format', () => { + const ENV_KEYS = ['DALLE_API_KEY', 'FLUX_API_KEY', 'SD_WEBUI_URL', 'PROXY']; + let savedEnv = {}; + + beforeEach(() => { + jest.clearAllMocks(); + for (const key of ENV_KEYS) { + savedEnv[key] = process.env[key]; + } + process.env.DALLE_API_KEY = 'test-dalle-key'; + process.env.FLUX_API_KEY = 'test-flux-key'; + process.env.SD_WEBUI_URL = 'http://localhost:7860'; + delete process.env.PROXY; + }); + + afterEach(() => { + for (const key of ENV_KEYS) { + if (savedEnv[key] === undefined) { + delete process.env[key]; + } else { + process.env[key] = savedEnv[key]; + } + } + savedEnv = {}; + }); + + describe('DALLE3', () => { + beforeEach(() => { + OpenAI.mockImplementation(() => ({ + images: { + generate: jest.fn().mockResolvedValue({ + data: [{ url: 'https://example.com/image.png' }], + }), + }, + })); + undici.fetch.mockResolvedValue({ + arrayBuffer: () => Promise.resolve(Buffer.from(FAKE_BASE64, 'base64')), + }); + }); + + it('sets responseFormat to content_and_artifact when isAgent is true', () => { + const dalle = new DALLE3({ isAgent: true }); + expect(dalle.responseFormat).toBe('content_and_artifact'); + }); + + it('does not set responseFormat when isAgent is false', () => { + const dalle = new DALLE3({ isAgent: false, processFileURL: jest.fn() }); + expect(dalle.responseFormat).not.toBe('content_and_artifact'); + }); + + it('invoke() returns ToolMessage with base64 in artifact, not serialized in content', async () => { + const dalle = new DALLE3({ isAgent: true }); + const result = await dalle.invoke( + makeToolCall('dalle', { + prompt: 'a box', + quality: 'standard', + size: '1024x1024', + style: 'vivid', + }), + ); + + expect(result).toBeInstanceOf(ToolMessage); + + const contentStr = + typeof result.content === 'string' ? result.content : JSON.stringify(result.content); + expect(contentStr).not.toContain(FAKE_BASE64); + + expect(result.artifact).toBeDefined(); + const artifactContent = result.artifact?.content; + expect(Array.isArray(artifactContent)).toBe(true); + expect(artifactContent[0].type).toBe(ContentTypes.IMAGE_URL); + expect(artifactContent[0].image_url.url).toContain('base64'); + }); + + it('invoke() returns ToolMessage with error string in content when API fails', async () => { + OpenAI.mockImplementation(() => ({ + images: { generate: jest.fn().mockRejectedValue(new Error('API error')) }, + })); + + const dalle = new DALLE3({ isAgent: true }); + const result = await dalle.invoke( + makeToolCall('dalle', { + prompt: 'a box', + quality: 'standard', + size: '1024x1024', + style: 'vivid', + }), + ); + + expect(result).toBeInstanceOf(ToolMessage); + const contentStr = + typeof result.content === 'string' ? result.content : JSON.stringify(result.content); + expect(contentStr).toContain('Something went wrong'); + expect(result.artifact).toBeDefined(); + }); + }); + + describe('FluxAPI', () => { + beforeEach(() => { + jest.useFakeTimers(); + axios.post.mockResolvedValue({ data: { id: 'task-123' } }); + axios.get.mockResolvedValue({ + data: { status: 'Ready', result: { sample: 'https://example.com/image.png' } }, + }); + fetch.mockResolvedValue({ + arrayBuffer: () => Promise.resolve(Buffer.from(FAKE_BASE64, 'base64')), + }); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + it('sets responseFormat to content_and_artifact when isAgent is true', () => { + const flux = new FluxAPI({ isAgent: true }); + expect(flux.responseFormat).toBe('content_and_artifact'); + }); + + it('does not set responseFormat when isAgent is false', () => { + const flux = new FluxAPI({ isAgent: false, processFileURL: jest.fn() }); + expect(flux.responseFormat).not.toBe('content_and_artifact'); + }); + + it('invoke() returns ToolMessage with base64 in artifact, not serialized in content', async () => { + const flux = new FluxAPI({ isAgent: true }); + const invokePromise = flux.invoke( + makeToolCall('flux', { prompt: 'a box', endpoint: '/v1/flux-dev' }), + ); + await jest.runAllTimersAsync(); + const result = await invokePromise; + + expect(result).toBeInstanceOf(ToolMessage); + const contentStr = + typeof result.content === 'string' ? result.content : JSON.stringify(result.content); + expect(contentStr).not.toContain(FAKE_BASE64); + + expect(result.artifact).toBeDefined(); + const artifactContent = result.artifact?.content; + expect(Array.isArray(artifactContent)).toBe(true); + expect(artifactContent[0].type).toBe(ContentTypes.IMAGE_URL); + expect(artifactContent[0].image_url.url).toContain('base64'); + }); + + it('invoke() returns ToolMessage with base64 in artifact for generate_finetuned action', async () => { + const flux = new FluxAPI({ isAgent: true }); + const invokePromise = flux.invoke( + makeToolCall('flux', { + action: 'generate_finetuned', + prompt: 'a box', + finetune_id: 'ft-abc123', + endpoint: '/v1/flux-pro-finetuned', + }), + ); + await jest.runAllTimersAsync(); + const result = await invokePromise; + + expect(result).toBeInstanceOf(ToolMessage); + const contentStr = + typeof result.content === 'string' ? result.content : JSON.stringify(result.content); + expect(contentStr).not.toContain(FAKE_BASE64); + + expect(result.artifact).toBeDefined(); + const artifactContent = result.artifact?.content; + expect(Array.isArray(artifactContent)).toBe(true); + expect(artifactContent[0].type).toBe(ContentTypes.IMAGE_URL); + expect(artifactContent[0].image_url.url).toContain('base64'); + }); + + it('invoke() returns ToolMessage with error string in content when task submission fails', async () => { + axios.post.mockRejectedValue(new Error('Network error')); + + const flux = new FluxAPI({ isAgent: true }); + const invokePromise = flux.invoke( + makeToolCall('flux', { prompt: 'a box', endpoint: '/v1/flux-dev' }), + ); + await jest.runAllTimersAsync(); + const result = await invokePromise; + + expect(result).toBeInstanceOf(ToolMessage); + const contentStr = + typeof result.content === 'string' ? result.content : JSON.stringify(result.content); + expect(contentStr).toContain('Something went wrong'); + expect(result.artifact).toBeDefined(); + }); + }); + + describe('StableDiffusion', () => { + beforeEach(() => { + axios.post.mockResolvedValue({ + data: { + images: [FAKE_BASE64], + info: JSON.stringify({ height: 1024, width: 1024, seed: 42, infotexts: [] }), + }, + }); + }); + + it('sets responseFormat to content_and_artifact when isAgent is true', () => { + const sd = new StableDiffusionAPI({ isAgent: true, override: true }); + expect(sd.responseFormat).toBe('content_and_artifact'); + }); + + it('does not set responseFormat when isAgent is false', () => { + const sd = new StableDiffusionAPI({ + isAgent: false, + override: true, + uploadImageBuffer: jest.fn(), + }); + expect(sd.responseFormat).not.toBe('content_and_artifact'); + }); + + it('invoke() returns ToolMessage with base64 in artifact, not serialized in content', async () => { + const sd = new StableDiffusionAPI({ isAgent: true, override: true, userId: 'user-1' }); + const result = await sd.invoke( + makeToolCall('stable-diffusion', { prompt: 'a box', negative_prompt: '' }), + ); + + expect(result).toBeInstanceOf(ToolMessage); + const contentStr = + typeof result.content === 'string' ? result.content : JSON.stringify(result.content); + expect(contentStr).not.toContain(FAKE_BASE64); + + expect(result.artifact).toBeDefined(); + const artifactContent = result.artifact?.content; + expect(Array.isArray(artifactContent)).toBe(true); + expect(artifactContent[0].type).toBe(ContentTypes.IMAGE_URL); + expect(artifactContent[0].image_url.url).toContain('base64'); + }); + + it('invoke() returns ToolMessage with error string in content when API fails', async () => { + axios.post.mockRejectedValue(new Error('Connection refused')); + + const sd = new StableDiffusionAPI({ isAgent: true, override: true, userId: 'user-1' }); + const result = await sd.invoke( + makeToolCall('stable-diffusion', { prompt: 'a box', negative_prompt: '' }), + ); + + expect(result).toBeInstanceOf(ToolMessage); + const contentStr = + typeof result.content === 'string' ? result.content : JSON.stringify(result.content); + expect(contentStr).toContain('Error making API request'); + }); + }); +}); diff --git a/api/app/clients/tools/util/handleTools.js b/api/app/clients/tools/util/handleTools.js index d82a0d6930..4b86101425 100644 --- a/api/app/clients/tools/util/handleTools.js +++ b/api/app/clients/tools/util/handleTools.js @@ -45,7 +45,7 @@ const { getUserPluginAuthValue } = require('~/server/services/PluginService'); const { createMCPTool, createMCPTools } = require('~/server/services/MCP'); const { loadAuthValues } = require('~/server/services/Tools/credentials'); const { getMCPServerTools } = require('~/server/services/Config'); -const { getRoleByName } = require('~/models/Role'); +const { getRoleByName } = require('~/models'); /** * Validates the availability and authentication of tools for a user based on environment variables or user-specific plugin authentication values. diff --git a/api/cache/banViolation.js b/api/cache/banViolation.js index 4d321889c1..36945ca420 100644 --- a/api/cache/banViolation.js +++ b/api/cache/banViolation.js @@ -1,8 +1,7 @@ const { logger } = require('@librechat/data-schemas'); -const { isEnabled, math } = require('@librechat/api'); const { ViolationTypes } = require('librechat-data-provider'); +const { isEnabled, math, removePorts } = require('@librechat/api'); const { deleteAllUserSessions } = require('~/models'); -const { removePorts } = require('~/server/utils'); const getLogStores = require('./getLogStores'); const { BAN_VIOLATIONS, BAN_INTERVAL } = process.env ?? {}; 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 3b752403c1..47f8b7287b 100644 --- a/api/jest.config.js +++ b/api/jest.config.js @@ -9,7 +9,7 @@ module.exports = { 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 deleted file mode 100644 index 20aa20a7e4..0000000000 --- a/api/models/Action.js +++ /dev/null @@ -1,77 +0,0 @@ -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 {Object} updateData - An object containing the properties to update. - * @returns {Promise} The updated or newly created action document as a plain object. - */ -const updateAction = async (searchParams, updateData) => { - const options = { new: true, upsert: true }; - return await Action.findOneAndUpdate(searchParams, updateData, options).lean(); -}; - -/** - * Retrieves all actions that match the given search parameters. - * - * @param {Object} searchParams - The search parameters to find matching actions. - * @param {boolean} includeSensitive - Flag to include sensitive data in the metadata. - * @returns {Promise>} A promise that resolves to an array of action documents as plain objects. - */ -const getActions = async (searchParams, includeSensitive = false) => { - const actions = await Action.find(searchParams).lean(); - - if (!includeSensitive) { - for (let i = 0; i < actions.length; i++) { - const metadata = actions[i].metadata; - if (!metadata) { - continue; - } - - const sensitiveFields = ['api_key', 'oauth_client_id', 'oauth_client_secret']; - for (let field of sensitiveFields) { - if (metadata[field]) { - delete metadata[field]; - } - } - } - } - - return actions; -}; - -/** - * 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. - */ -const deleteAction = async (searchParams) => { - return await Action.findOneAndDelete(searchParams).lean(); -}; - -/** - * Deletes actions by params. - * - * @param {Object} searchParams - The search parameters to find the actions to delete. - * @param {string} searchParams.action_id - The ID of the action(s) to delete. - * @param {string} searchParams.user - The user ID of the action's author. - * @returns {Promise} A promise that resolves to the number of deleted action documents. - */ -const deleteActions = async (searchParams) => { - const result = await Action.deleteMany(searchParams); - return result.deletedCount; -}; - -module.exports = { - getActions, - updateAction, - deleteAction, - deleteActions, -}; diff --git a/api/models/Agent.js b/api/models/Agent.js deleted file mode 100644 index 663285183a..0000000000 --- a/api/models/Agent.js +++ /dev/null @@ -1,931 +0,0 @@ -const mongoose = require('mongoose'); -const crypto = require('node:crypto'); -const { logger } = require('@librechat/data-schemas'); -const { getCustomEndpointConfig } = require('@librechat/api'); -const { - Tools, - SystemRoles, - ResourceType, - actionDelimiter, - isAgentsEndpoint, - isEphemeralAgentId, - encodeEphemeralAgentId, -} = require('librechat-data-provider'); -const { mcp_all, mcp_delimiter } = require('librechat-data-provider').Constants; -const { - removeAgentFromAllProjects, - removeAgentIdsFromProject, - addAgentIdsToProject, -} = require('./Project'); -const { removeAllPermissions } = require('~/server/services/PermissionService'); -const { getMCPServerTools } = require('~/server/services/Config'); -const { Agent, AclEntry, User } = require('~/db/models'); -const { getActions } = require('./Action'); - -/** - * Extracts unique MCP server names from tools array - * Tools format: "toolName_mcp_serverName" or "sys__server__sys_mcp_serverName" - * @param {string[]} tools - Array of tool identifiers - * @returns {string[]} Array of unique MCP server names - */ -const extractMCPServerNames = (tools) => { - if (!tools || !Array.isArray(tools)) { - return []; - } - const serverNames = new Set(); - for (const tool of tools) { - if (!tool || !tool.includes(mcp_delimiter)) { - continue; - } - const parts = tool.split(mcp_delimiter); - if (parts.length >= 2) { - serverNames.add(parts[parts.length - 1]); - } - } - return Array.from(serverNames); -}; - -/** - * Create an agent with the provided data. - * @param {Object} agentData - The agent data to create. - * @returns {Promise} The created agent document as a plain object. - * @throws {Error} If the agent creation fails. - */ -const createAgent = async (agentData) => { - const { author: _author, ...versionData } = agentData; - const timestamp = new Date(); - const initialAgentData = { - ...agentData, - versions: [ - { - ...versionData, - createdAt: timestamp, - updatedAt: timestamp, - }, - ], - category: agentData.category || 'general', - mcpServerNames: extractMCPServerNames(agentData.tools), - }; - - return (await Agent.create(initialAgentData)).toObject(); -}; - -/** - * Get an agent document based on the provided ID. - * - * @param {Object} searchParameter - The search parameters to find the agent to update. - * @param {string} searchParameter.id - The ID of the agent to update. - * @param {string} searchParameter.author - The user ID of the agent's author. - * @returns {Promise} The agent document as a plain object, or null if not found. - */ -const getAgent = async (searchParameter) => await Agent.findOne(searchParameter).lean(); - -/** - * Get multiple agent documents based on the provided search parameters. - * - * @param {Object} searchParameter - The search parameters to find agents. - * @returns {Promise} Array of agent documents as plain objects. - */ -const getAgents = async (searchParameter) => await Agent.find(searchParameter).lean(); - -/** - * Load an agent based on the provided ID - * - * @param {Object} params - * @param {ServerRequest} params.req - * @param {string} params.spec - * @param {string} params.agent_id - * @param {string} params.endpoint - * @param {import('@librechat/agents').ClientOptions} [params.model_parameters] - * @returns {Promise} The agent document as a plain object, or null if not found. - */ -const loadEphemeralAgent = async ({ req, spec, endpoint, model_parameters: _m }) => { - const { model, ...model_parameters } = _m; - const modelSpecs = req.config?.modelSpecs?.list; - /** @type {TModelSpec | null} */ - let modelSpec = null; - if (spec != null && spec !== '') { - modelSpec = modelSpecs?.find((s) => s.name === spec) || null; - } - /** @type {TEphemeralAgent | null} */ - const ephemeralAgent = req.body.ephemeralAgent; - const mcpServers = new Set(ephemeralAgent?.mcp); - const userId = req.user?.id; // note: userId cannot be undefined at runtime - if (modelSpec?.mcpServers) { - for (const mcpServer of modelSpec.mcpServers) { - mcpServers.add(mcpServer); - } - } - /** @type {string[]} */ - const tools = []; - if (ephemeralAgent?.execute_code === true || modelSpec?.executeCode === true) { - tools.push(Tools.execute_code); - } - if (ephemeralAgent?.file_search === true || modelSpec?.fileSearch === true) { - tools.push(Tools.file_search); - } - if (ephemeralAgent?.web_search === true || modelSpec?.webSearch === true) { - tools.push(Tools.web_search); - } - - const addedServers = new Set(); - if (mcpServers.size > 0) { - for (const mcpServer of mcpServers) { - if (addedServers.has(mcpServer)) { - continue; - } - const serverTools = await getMCPServerTools(userId, mcpServer); - if (!serverTools) { - tools.push(`${mcp_all}${mcp_delimiter}${mcpServer}`); - addedServers.add(mcpServer); - continue; - } - tools.push(...Object.keys(serverTools)); - addedServers.add(mcpServer); - } - } - - const instructions = req.body.promptPrefix; - - // Get endpoint config for modelDisplayLabel fallback - const appConfig = req.config; - let endpointConfig = appConfig?.endpoints?.[endpoint]; - if (!isAgentsEndpoint(endpoint) && !endpointConfig) { - try { - endpointConfig = getCustomEndpointConfig({ endpoint, appConfig }); - } catch (err) { - logger.error('[loadEphemeralAgent] Error getting custom endpoint config', err); - } - } - - // For ephemeral agents, use modelLabel if provided, then model spec's label, - // then modelDisplayLabel from endpoint config, otherwise empty string to show model name - const sender = - model_parameters?.modelLabel ?? modelSpec?.label ?? endpointConfig?.modelDisplayLabel ?? ''; - - // Encode ephemeral agent ID with endpoint, model, and computed sender for display - const ephemeralId = encodeEphemeralAgentId({ endpoint, model, sender }); - - const result = { - id: ephemeralId, - instructions, - provider: endpoint, - model_parameters, - model, - tools, - }; - - if (ephemeralAgent?.artifacts != null && ephemeralAgent.artifacts) { - result.artifacts = ephemeralAgent.artifacts; - } - return result; -}; - -/** - * Load an agent based on the provided ID - * - * @param {Object} params - * @param {ServerRequest} params.req - * @param {string} params.spec - * @param {string} params.agent_id - * @param {string} params.endpoint - * @param {import('@librechat/agents').ClientOptions} [params.model_parameters] - * @returns {Promise} The agent document as a plain object, or null if not found. - */ -const loadAgent = async ({ req, spec, agent_id, endpoint, model_parameters }) => { - if (!agent_id) { - return null; - } - if (isEphemeralAgentId(agent_id)) { - return await loadEphemeralAgent({ req, spec, endpoint, model_parameters }); - } - const agent = await getAgent({ - id: agent_id, - }); - - if (!agent) { - return null; - } - - agent.version = agent.versions ? agent.versions.length : 0; - return agent; -}; - -/** - * Check if a version already exists in the versions array, excluding timestamp and author fields - * @param {Object} updateData - The update data to compare - * @param {Object} currentData - The current agent data - * @param {Array} versions - The existing versions array - * @param {string} [actionsHash] - Hash of current action metadata - * @returns {Object|null} - The matching version if found, null otherwise - */ -const isDuplicateVersion = (updateData, currentData, versions, actionsHash = null) => { - if (!versions || versions.length === 0) { - return null; - } - - const excludeFields = [ - '_id', - 'id', - 'createdAt', - 'updatedAt', - 'author', - 'updatedBy', - 'created_at', - 'updated_at', - '__v', - 'versions', - 'actionsHash', // Exclude actionsHash from direct comparison - ]; - - const { $push: _$push, $pull: _$pull, $addToSet: _$addToSet, ...directUpdates } = updateData; - - if (Object.keys(directUpdates).length === 0 && !actionsHash) { - return null; - } - - const wouldBeVersion = { ...currentData, ...directUpdates }; - const lastVersion = versions[versions.length - 1]; - - if (actionsHash && lastVersion.actionsHash !== actionsHash) { - return null; - } - - const allFields = new Set([...Object.keys(wouldBeVersion), ...Object.keys(lastVersion)]); - - const importantFields = Array.from(allFields).filter((field) => !excludeFields.includes(field)); - - let isMatch = true; - for (const field of importantFields) { - const wouldBeValue = wouldBeVersion[field]; - const lastVersionValue = lastVersion[field]; - - // Skip if both are undefined/null - if (!wouldBeValue && !lastVersionValue) { - continue; - } - - // Handle arrays - if (Array.isArray(wouldBeValue) || Array.isArray(lastVersionValue)) { - // Normalize: treat undefined/null as empty array for comparison - let wouldBeArr; - if (Array.isArray(wouldBeValue)) { - wouldBeArr = wouldBeValue; - } else if (wouldBeValue == null) { - wouldBeArr = []; - } else { - wouldBeArr = [wouldBeValue]; - } - - let lastVersionArr; - if (Array.isArray(lastVersionValue)) { - lastVersionArr = lastVersionValue; - } else if (lastVersionValue == null) { - lastVersionArr = []; - } else { - lastVersionArr = [lastVersionValue]; - } - - if (wouldBeArr.length !== lastVersionArr.length) { - isMatch = false; - break; - } - - // Special handling for projectIds (MongoDB ObjectIds) - if (field === 'projectIds') { - const wouldBeIds = wouldBeArr.map((id) => id.toString()).sort(); - const versionIds = lastVersionArr.map((id) => id.toString()).sort(); - - if (!wouldBeIds.every((id, i) => id === versionIds[i])) { - isMatch = false; - break; - } - } - // Handle arrays of objects - else if ( - wouldBeArr.length > 0 && - typeof wouldBeArr[0] === 'object' && - wouldBeArr[0] !== null - ) { - const sortedWouldBe = [...wouldBeArr].map((item) => JSON.stringify(item)).sort(); - const sortedVersion = [...lastVersionArr].map((item) => JSON.stringify(item)).sort(); - - if (!sortedWouldBe.every((item, i) => item === sortedVersion[i])) { - isMatch = false; - break; - } - } else { - const sortedWouldBe = [...wouldBeArr].sort(); - const sortedVersion = [...lastVersionArr].sort(); - - if (!sortedWouldBe.every((item, i) => item === sortedVersion[i])) { - isMatch = false; - break; - } - } - } - // Handle objects - else if (typeof wouldBeValue === 'object' && wouldBeValue !== null) { - const lastVersionObj = - typeof lastVersionValue === 'object' && lastVersionValue !== null ? lastVersionValue : {}; - - // For empty objects, normalize the comparison - const wouldBeKeys = Object.keys(wouldBeValue); - const lastVersionKeys = Object.keys(lastVersionObj); - - // If both are empty objects, they're equal - if (wouldBeKeys.length === 0 && lastVersionKeys.length === 0) { - continue; - } - - // Otherwise do a deep comparison - if (JSON.stringify(wouldBeValue) !== JSON.stringify(lastVersionObj)) { - isMatch = false; - break; - } - } - // Handle primitive values - else { - // For primitives, handle the case where one is undefined and the other is a default value - if (wouldBeValue !== lastVersionValue) { - // Special handling for boolean false vs undefined - if ( - typeof wouldBeValue === 'boolean' && - wouldBeValue === false && - lastVersionValue === undefined - ) { - continue; - } - // Special handling for empty string vs undefined - if ( - typeof wouldBeValue === 'string' && - wouldBeValue === '' && - lastVersionValue === undefined - ) { - continue; - } - isMatch = false; - break; - } - } - } - - return isMatch ? lastVersion : null; -}; - -/** - * Update an agent with new data without overwriting existing - * properties, or create a new agent if it doesn't exist. - * When an agent is updated, a copy of the current state will be saved to the versions array. - * - * @param {Object} searchParameter - The search parameters to find the agent to update. - * @param {string} searchParameter.id - The ID of the agent to update. - * @param {string} [searchParameter.author] - The user ID of the agent's author. - * @param {Object} updateData - An object containing the properties to update. - * @param {Object} [options] - Optional configuration object. - * @param {string} [options.updatingUserId] - The ID of the user performing the update (used for tracking non-author updates). - * @param {boolean} [options.forceVersion] - Force creation of a new version even if no fields changed. - * @param {boolean} [options.skipVersioning] - Skip version creation entirely (useful for isolated operations like sharing). - * @returns {Promise} The updated or newly created agent document as a plain object. - * @throws {Error} If the update would create a duplicate version - */ -const updateAgent = async (searchParameter, updateData, options = {}) => { - const { updatingUserId = null, forceVersion = false, skipVersioning = false } = options; - const mongoOptions = { new: true, upsert: false }; - - const currentAgent = await Agent.findOne(searchParameter); - if (currentAgent) { - const { - __v, - _id, - id: __id, - versions, - author: _author, - ...versionData - } = currentAgent.toObject(); - const { $push, $pull, $addToSet, ...directUpdates } = updateData; - - // Sync mcpServerNames when tools are updated - if (directUpdates.tools !== undefined) { - const mcpServerNames = extractMCPServerNames(directUpdates.tools); - directUpdates.mcpServerNames = mcpServerNames; - updateData.mcpServerNames = mcpServerNames; // Also update the original updateData - } - - let actionsHash = null; - - // Generate actions hash if agent has actions - if (currentAgent.actions && currentAgent.actions.length > 0) { - // Extract action IDs from the format "domain_action_id" - const actionIds = currentAgent.actions - .map((action) => { - const parts = action.split(actionDelimiter); - return parts[1]; // Get just the action ID part - }) - .filter(Boolean); - - if (actionIds.length > 0) { - try { - const actions = await getActions( - { - action_id: { $in: actionIds }, - }, - true, - ); // Include sensitive data for hash - - actionsHash = await generateActionMetadataHash(currentAgent.actions, actions); - } catch (error) { - logger.error('Error fetching actions for hash generation:', error); - } - } - } - - const shouldCreateVersion = - !skipVersioning && - (forceVersion || Object.keys(directUpdates).length > 0 || $push || $pull || $addToSet); - - if (shouldCreateVersion) { - const duplicateVersion = isDuplicateVersion(updateData, versionData, versions, actionsHash); - if (duplicateVersion && !forceVersion) { - // No changes detected, return the current agent without creating a new version - const agentObj = currentAgent.toObject(); - agentObj.version = versions.length; - return agentObj; - } - } - - const versionEntry = { - ...versionData, - ...directUpdates, - updatedAt: new Date(), - }; - - // Include actions hash in version if available - if (actionsHash) { - versionEntry.actionsHash = actionsHash; - } - - // Always store updatedBy field to track who made the change - if (updatingUserId) { - versionEntry.updatedBy = new mongoose.Types.ObjectId(updatingUserId); - } - - if (shouldCreateVersion) { - updateData.$push = { - ...($push || {}), - versions: versionEntry, - }; - } - } - - return Agent.findOneAndUpdate(searchParameter, updateData, mongoOptions).lean(); -}; - -/** - * Modifies an agent with the resource file id. - * @param {object} params - * @param {ServerRequest} params.req - * @param {string} params.agent_id - * @param {string} params.tool_resource - * @param {string} params.file_id - * @returns {Promise} The updated agent. - */ -const addAgentResourceFile = async ({ req, agent_id, tool_resource, file_id }) => { - const searchParameter = { id: agent_id }; - let agent = await getAgent(searchParameter); - if (!agent) { - throw new Error('Agent not found for adding resource file'); - } - const fileIdsPath = `tool_resources.${tool_resource}.file_ids`; - await Agent.updateOne( - { - id: agent_id, - [`${fileIdsPath}`]: { $exists: false }, - }, - { - $set: { - [`${fileIdsPath}`]: [], - }, - }, - ); - - const updateData = { - $addToSet: { - tools: tool_resource, - [fileIdsPath]: file_id, - }, - }; - - const updatedAgent = await updateAgent(searchParameter, updateData, { - updatingUserId: req?.user?.id, - }); - if (updatedAgent) { - return updatedAgent; - } else { - throw new Error('Agent not found for adding resource file'); - } -}; - -/** - * Removes multiple resource files from an agent using atomic operations. - * @param {object} params - * @param {string} params.agent_id - * @param {Array<{tool_resource: string, file_id: string}>} params.files - * @returns {Promise} The updated agent. - * @throws {Error} If the agent is not found or update fails. - */ -const removeAgentResourceFiles = async ({ agent_id, files }) => { - const searchParameter = { id: agent_id }; - - // Group files to remove by resource - const filesByResource = files.reduce((acc, { tool_resource, file_id }) => { - if (!acc[tool_resource]) { - acc[tool_resource] = []; - } - acc[tool_resource].push(file_id); - return acc; - }, {}); - - // Step 1: Atomically remove file IDs using $pull - const pullOps = {}; - const resourcesToCheck = new Set(); - for (const [resource, fileIds] of Object.entries(filesByResource)) { - const fileIdsPath = `tool_resources.${resource}.file_ids`; - pullOps[fileIdsPath] = { $in: fileIds }; - resourcesToCheck.add(resource); - } - - const updatePullData = { $pull: pullOps }; - const agentAfterPull = await Agent.findOneAndUpdate(searchParameter, updatePullData, { - new: true, - }).lean(); - - if (!agentAfterPull) { - // Agent might have been deleted concurrently, or never existed. - // Check if it existed before trying to throw. - const agentExists = await getAgent(searchParameter); - if (!agentExists) { - throw new Error('Agent not found for removing resource files'); - } - // If it existed but findOneAndUpdate returned null, something else went wrong. - throw new Error('Failed to update agent during file removal (pull step)'); - } - - // Return the agent state directly after the $pull operation. - // Skipping the $unset step for now to simplify and test core $pull atomicity. - // Empty arrays might remain, but the removal itself should be correct. - return agentAfterPull; -}; - -/** - * Deletes an agent based on the provided ID. - * - * @param {Object} searchParameter - The search parameters to find the agent to delete. - * @param {string} searchParameter.id - The ID of the agent to delete. - * @param {string} [searchParameter.author] - The user ID of the agent's author. - * @returns {Promise} Resolves when the agent has been successfully deleted. - */ -const deleteAgent = async (searchParameter) => { - const agent = await Agent.findOneAndDelete(searchParameter); - if (agent) { - await removeAgentFromAllProjects(agent.id); - await Promise.all([ - removeAllPermissions({ - resourceType: ResourceType.AGENT, - resourceId: agent._id, - }), - removeAllPermissions({ - resourceType: ResourceType.REMOTE_AGENT, - resourceId: agent._id, - }), - ]); - try { - await Agent.updateMany({ 'edges.to': agent.id }, { $pull: { edges: { to: agent.id } } }); - } catch (error) { - logger.error('[deleteAgent] Error removing agent from handoff edges', error); - } - try { - await User.updateMany( - { 'favorites.agentId': agent.id }, - { $pull: { favorites: { agentId: agent.id } } }, - ); - } catch (error) { - logger.error('[deleteAgent] Error removing agent from user favorites', error); - } - } - return agent; -}; - -/** - * Deletes all agents created by a specific user. - * @param {string} userId - The ID of the user whose agents should be deleted. - * @returns {Promise} A promise that resolves when all user agents have been deleted. - */ -const deleteUserAgents = async (userId) => { - try { - const userAgents = await getAgents({ author: userId }); - - if (userAgents.length === 0) { - return; - } - - const agentIds = userAgents.map((agent) => agent.id); - const agentObjectIds = userAgents.map((agent) => agent._id); - - for (const agentId of agentIds) { - await removeAgentFromAllProjects(agentId); - } - - await AclEntry.deleteMany({ - resourceType: { $in: [ResourceType.AGENT, ResourceType.REMOTE_AGENT] }, - resourceId: { $in: agentObjectIds }, - }); - - try { - await User.updateMany( - { 'favorites.agentId': { $in: agentIds } }, - { $pull: { favorites: { agentId: { $in: agentIds } } } }, - ); - } catch (error) { - logger.error('[deleteUserAgents] Error removing agents from user favorites', error); - } - - await Agent.deleteMany({ author: userId }); - } catch (error) { - logger.error('[deleteUserAgents] General error:', error); - } -}; - -/** - * Get agents by accessible IDs with optional cursor-based pagination. - * @param {Object} params - The parameters for getting accessible agents. - * @param {Array} [params.accessibleIds] - Array of agent ObjectIds the user has ACL access to. - * @param {Object} [params.otherParams] - Additional query parameters (including author filter). - * @param {number} [params.limit] - Number of agents to return (max 100). If not provided, returns all agents. - * @param {string} [params.after] - Cursor for pagination - get agents after this cursor. // base64 encoded JSON string with updatedAt and _id. - * @returns {Promise} A promise that resolves to an object containing the agents data and pagination info. - */ -const getListAgentsByAccess = async ({ - accessibleIds = [], - otherParams = {}, - limit = null, - after = null, -}) => { - const isPaginated = limit !== null && limit !== undefined; - const normalizedLimit = isPaginated ? Math.min(Math.max(1, parseInt(limit) || 20), 100) : null; - - // Build base query combining ACL accessible agents with other filters - const baseQuery = { ...otherParams, _id: { $in: accessibleIds } }; - - // Add cursor condition - if (after) { - try { - const cursor = JSON.parse(Buffer.from(after, 'base64').toString('utf8')); - const { updatedAt, _id } = cursor; - - const cursorCondition = { - $or: [ - { updatedAt: { $lt: new Date(updatedAt) } }, - { updatedAt: new Date(updatedAt), _id: { $gt: new mongoose.Types.ObjectId(_id) } }, - ], - }; - - // Merge cursor condition with base query - if (Object.keys(baseQuery).length > 0) { - baseQuery.$and = [{ ...baseQuery }, cursorCondition]; - // Remove the original conditions from baseQuery to avoid duplication - Object.keys(baseQuery).forEach((key) => { - if (key !== '$and') delete baseQuery[key]; - }); - } else { - Object.assign(baseQuery, cursorCondition); - } - } catch (error) { - logger.warn('Invalid cursor:', error.message); - } - } - - let query = Agent.find(baseQuery, { - id: 1, - _id: 1, - name: 1, - avatar: 1, - author: 1, - projectIds: 1, - description: 1, - updatedAt: 1, - category: 1, - support_contact: 1, - is_promoted: 1, - }).sort({ updatedAt: -1, _id: 1 }); - - // Only apply limit if pagination is requested - if (isPaginated) { - query = query.limit(normalizedLimit + 1); - } - - const agents = await query.lean(); - - const hasMore = isPaginated ? agents.length > normalizedLimit : false; - const data = (isPaginated ? agents.slice(0, normalizedLimit) : agents).map((agent) => { - if (agent.author) { - agent.author = agent.author.toString(); - } - return agent; - }); - - // Generate next cursor only if paginated - let nextCursor = null; - if (isPaginated && hasMore && data.length > 0) { - const lastAgent = agents[normalizedLimit - 1]; - nextCursor = Buffer.from( - JSON.stringify({ - updatedAt: lastAgent.updatedAt.toISOString(), - _id: lastAgent._id.toString(), - }), - ).toString('base64'); - } - - return { - object: 'list', - data, - first_id: data.length > 0 ? data[0].id : null, - last_id: data.length > 0 ? data[data.length - 1].id : null, - has_more: hasMore, - after: nextCursor, - }; -}; - -/** - * Updates the projects associated with an agent, adding and removing project IDs as specified. - * This function also updates the corresponding projects to include or exclude the agent ID. - * - * @param {Object} params - Parameters for updating the agent's projects. - * @param {IUser} params.user - Parameters for updating the agent's projects. - * @param {string} params.agentId - The ID of the agent to update. - * @param {string[]} [params.projectIds] - Array of project IDs to add to the agent. - * @param {string[]} [params.removeProjectIds] - Array of project IDs to remove from the agent. - * @returns {Promise} The updated agent document. - * @throws {Error} If there's an error updating the agent or projects. - */ -const updateAgentProjects = async ({ user, agentId, projectIds, removeProjectIds }) => { - const updateOps = {}; - - if (removeProjectIds && removeProjectIds.length > 0) { - for (const projectId of removeProjectIds) { - await removeAgentIdsFromProject(projectId, [agentId]); - } - updateOps.$pull = { projectIds: { $in: removeProjectIds } }; - } - - if (projectIds && projectIds.length > 0) { - for (const projectId of projectIds) { - await addAgentIdsToProject(projectId, [agentId]); - } - updateOps.$addToSet = { projectIds: { $each: projectIds } }; - } - - if (Object.keys(updateOps).length === 0) { - return await getAgent({ id: agentId }); - } - - const updateQuery = { id: agentId, author: user.id }; - if (user.role === SystemRoles.ADMIN) { - delete updateQuery.author; - } - - const updatedAgent = await updateAgent(updateQuery, updateOps, { - updatingUserId: user.id, - skipVersioning: true, - }); - if (updatedAgent) { - return updatedAgent; - } - if (updateOps.$addToSet) { - for (const projectId of projectIds) { - await removeAgentIdsFromProject(projectId, [agentId]); - } - } else if (updateOps.$pull) { - for (const projectId of removeProjectIds) { - await addAgentIdsToProject(projectId, [agentId]); - } - } - - return await getAgent({ id: agentId }); -}; - -/** - * Reverts an agent to a specific version in its version history. - * @param {Object} searchParameter - The search parameters to find the agent to revert. - * @param {string} searchParameter.id - The ID of the agent to revert. - * @param {string} [searchParameter.author] - The user ID of the agent's author. - * @param {number} versionIndex - The index of the version to revert to in the versions array. - * @returns {Promise} The updated agent document after reverting. - * @throws {Error} If the agent is not found or the specified version does not exist. - */ -const revertAgentVersion = async (searchParameter, versionIndex) => { - const agent = await Agent.findOne(searchParameter); - if (!agent) { - throw new Error('Agent not found'); - } - - if (!agent.versions || !agent.versions[versionIndex]) { - throw new Error(`Version ${versionIndex} not found`); - } - - const revertToVersion = agent.versions[versionIndex]; - - const updateData = { - ...revertToVersion, - }; - - delete updateData._id; - delete updateData.id; - delete updateData.versions; - delete updateData.author; - delete updateData.updatedBy; - - return Agent.findOneAndUpdate(searchParameter, updateData, { new: true }).lean(); -}; - -/** - * Generates a hash of action metadata for version comparison - * @param {string[]} actionIds - Array of action IDs in format "domain_action_id" - * @param {Action[]} actions - Array of action documents - * @returns {Promise} - SHA256 hash of the action metadata - */ -const generateActionMetadataHash = async (actionIds, actions) => { - if (!actionIds || actionIds.length === 0) { - return ''; - } - - // Create a map of action_id to metadata for quick lookup - const actionMap = new Map(); - actions.forEach((action) => { - actionMap.set(action.action_id, action.metadata); - }); - - // Sort action IDs for consistent hashing - const sortedActionIds = [...actionIds].sort(); - - // Build a deterministic string representation of all action metadata - const metadataString = sortedActionIds - .map((actionFullId) => { - // Extract just the action_id part (after the delimiter) - const parts = actionFullId.split(actionDelimiter); - const actionId = parts[1]; - - const metadata = actionMap.get(actionId); - if (!metadata) { - return `${actionId}:null`; - } - - // Sort metadata keys for deterministic output - const sortedKeys = Object.keys(metadata).sort(); - const metadataStr = sortedKeys - .map((key) => `${key}:${JSON.stringify(metadata[key])}`) - .join(','); - return `${actionId}:{${metadataStr}}`; - }) - .join(';'); - - // Use Web Crypto API to generate hash - const encoder = new TextEncoder(); - const data = encoder.encode(metadataString); - const hashBuffer = await crypto.webcrypto.subtle.digest('SHA-256', data); - const hashArray = Array.from(new Uint8Array(hashBuffer)); - const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join(''); - - return hashHex; -}; -/** - * Counts the number of promoted agents. - * @returns {Promise} - The count of promoted agents - */ -const countPromotedAgents = async () => { - const count = await Agent.countDocuments({ is_promoted: true }); - return count; -}; - -/** - * Load a default agent based on the endpoint - * @param {string} endpoint - * @returns {Agent | null} - */ - -module.exports = { - getAgent, - getAgents, - loadAgent, - createAgent, - updateAgent, - deleteAgent, - deleteUserAgents, - revertAgentVersion, - updateAgentProjects, - countPromotedAgents, - addAgentResourceFile, - getListAgentsByAccess, - removeAgentResourceFiles, - generateActionMetadataHash, -}; diff --git a/api/models/Assistant.js b/api/models/Assistant.js deleted file mode 100644 index be94d35d7d..0000000000 --- a/api/models/Assistant.js +++ /dev/null @@ -1,62 +0,0 @@ -const { Assistant } = require('~/db/models'); - -/** - * Update an assistant with new data without overwriting existing properties, - * or create a new assistant if it doesn't exist. - * - * @param {Object} searchParams - The search parameters to find the assistant to update. - * @param {string} searchParams.assistant_id - The ID of the assistant to update. - * @param {string} searchParams.user - The user ID of the assistant's author. - * @param {Object} updateData - An object containing the properties to update. - * @returns {Promise} The updated or newly created assistant document as a plain object. - */ -const updateAssistantDoc = async (searchParams, updateData) => { - const options = { new: true, upsert: true }; - return await Assistant.findOneAndUpdate(searchParams, updateData, options).lean(); -}; - -/** - * Retrieves an assistant document based on the provided ID. - * - * @param {Object} searchParams - The search parameters to find the assistant to update. - * @param {string} searchParams.assistant_id - The ID of the assistant to update. - * @param {string} searchParams.user - The user ID of the assistant's author. - * @returns {Promise} The assistant document as a plain object, or null if not found. - */ -const getAssistant = async (searchParams) => await Assistant.findOne(searchParams).lean(); - -/** - * Retrieves all assistants that match the given search parameters. - * - * @param {Object} searchParams - The search parameters to find matching assistants. - * @param {Object} [select] - Optional. Specifies which document fields to include or exclude. - * @returns {Promise>} A promise that resolves to an array of assistant documents as plain objects. - */ -const getAssistants = async (searchParams, select = null) => { - let query = Assistant.find(searchParams); - - if (select) { - query = query.select(select); - } - - return await query.lean(); -}; - -/** - * Deletes an assistant based on the provided ID. - * - * @param {Object} searchParams - The search parameters to find the assistant to delete. - * @param {string} searchParams.assistant_id - The ID of the assistant to delete. - * @param {string} searchParams.user - The user ID of the assistant's author. - * @returns {Promise} Resolves when the assistant has been successfully deleted. - */ -const deleteAssistant = async (searchParams) => { - return await Assistant.findOneAndDelete(searchParams); -}; - -module.exports = { - updateAssistantDoc, - deleteAssistant, - getAssistants, - getAssistant, -}; diff --git a/api/models/Banner.js b/api/models/Banner.js deleted file mode 100644 index 42ad1599ed..0000000000 --- a/api/models/Banner.js +++ /dev/null @@ -1,28 +0,0 @@ -const { logger } = require('@librechat/data-schemas'); -const { Banner } = require('~/db/models'); - -/** - * Retrieves the current active banner. - * @returns {Promise} The active banner object or null if no active banner is found. - */ -const getBanner = async (user) => { - try { - const now = new Date(); - const banner = await Banner.findOne({ - displayFrom: { $lte: now }, - $or: [{ displayTo: { $gte: now } }, { displayTo: null }], - type: 'banner', - }).lean(); - - if (!banner || banner.isPublic || user) { - return banner; - } - - return null; - } catch (error) { - logger.error('[getBanners] Error getting banners', error); - throw new Error('Error getting banners'); - } -}; - -module.exports = { getBanner }; diff --git a/api/models/Categories.js b/api/models/Categories.js deleted file mode 100644 index 34bd2d8ed2..0000000000 --- a/api/models/Categories.js +++ /dev/null @@ -1,57 +0,0 @@ -const { logger } = require('@librechat/data-schemas'); - -const options = [ - { - label: 'com_ui_idea', - value: 'idea', - }, - { - label: 'com_ui_travel', - value: 'travel', - }, - { - label: 'com_ui_teach_or_explain', - value: 'teach_or_explain', - }, - { - label: 'com_ui_write', - value: 'write', - }, - { - label: 'com_ui_shop', - value: 'shop', - }, - { - label: 'com_ui_code', - value: 'code', - }, - { - label: 'com_ui_misc', - value: 'misc', - }, - { - label: 'com_ui_roleplay', - value: 'roleplay', - }, - { - label: 'com_ui_finance', - value: 'finance', - }, -]; - -module.exports = { - /** - * Retrieves the categories asynchronously. - * @returns {Promise} An array of category objects. - * @throws {Error} If there is an error retrieving the categories. - */ - getCategories: async () => { - try { - // const categories = await Categories.find(); - return options; - } catch (error) { - logger.error('Error getting categories', error); - return []; - } - }, -}; diff --git a/api/models/Conversation.js b/api/models/Conversation.js deleted file mode 100644 index 32eac1a764..0000000000 --- a/api/models/Conversation.js +++ /dev/null @@ -1,372 +0,0 @@ -const { logger } = require('@librechat/data-schemas'); -const { createTempChatExpirationDate } = require('@librechat/api'); -const { getMessages, deleteMessages } = require('./Message'); -const { Conversation } = require('~/db/models'); - -/** - * Searches for a conversation by conversationId and returns a lean document with only conversationId and user. - * @param {string} conversationId - The conversation's ID. - * @returns {Promise<{conversationId: string, user: string} | null>} The conversation object with selected fields or null if not found. - */ -const searchConversation = async (conversationId) => { - try { - return await Conversation.findOne({ conversationId }, 'conversationId user').lean(); - } catch (error) { - logger.error('[searchConversation] Error searching conversation', error); - throw new Error('Error searching conversation'); - } -}; - -/** - * Retrieves a single conversation for a given user and conversation ID. - * @param {string} user - The user's ID. - * @param {string} conversationId - The conversation's ID. - * @returns {Promise} The conversation object. - */ -const getConvo = async (user, conversationId) => { - try { - return await Conversation.findOne({ user, conversationId }).lean(); - } catch (error) { - logger.error('[getConvo] Error getting single conversation', error); - throw new Error('Error getting single conversation'); - } -}; - -const deleteNullOrEmptyConversations = async () => { - try { - const filter = { - $or: [ - { conversationId: null }, - { conversationId: '' }, - { conversationId: { $exists: false } }, - ], - }; - - const result = await Conversation.deleteMany(filter); - - // Delete associated messages - const messageDeleteResult = await deleteMessages(filter); - - logger.info( - `[deleteNullOrEmptyConversations] Deleted ${result.deletedCount} conversations and ${messageDeleteResult.deletedCount} messages`, - ); - - return { - conversations: result, - messages: messageDeleteResult, - }; - } catch (error) { - logger.error('[deleteNullOrEmptyConversations] Error deleting conversations', error); - throw new Error('Error deleting conversations with null or empty conversationId'); - } -}; - -/** - * Searches for a conversation by conversationId and returns associated file ids. - * @param {string} conversationId - The conversation's ID. - * @returns {Promise} - */ -const getConvoFiles = async (conversationId) => { - try { - return (await Conversation.findOne({ conversationId }, 'files').lean())?.files ?? []; - } catch (error) { - logger.error('[getConvoFiles] Error getting conversation files', error); - throw new Error('Error getting conversation files'); - } -}; - -module.exports = { - getConvoFiles, - searchConversation, - deleteNullOrEmptyConversations, - /** - * Saves a conversation to the database. - * @param {Object} req - The request object. - * @param {string} conversationId - The conversation's ID. - * @param {Object} metadata - Additional metadata to log for operation. - * @returns {Promise} The conversation object. - */ - saveConvo: async (req, { conversationId, newConversationId, ...convo }, metadata) => { - try { - if (metadata?.context) { - logger.debug(`[saveConvo] ${metadata.context}`); - } - - const messages = await getMessages({ conversationId }, '_id'); - const update = { ...convo, messages, user: req.user.id }; - - if (newConversationId) { - update.conversationId = newConversationId; - } - - if (req?.body?.isTemporary) { - try { - const appConfig = req.config; - update.expiredAt = createTempChatExpirationDate(appConfig?.interfaceConfig); - } catch (err) { - logger.error('Error creating temporary chat expiration date:', err); - logger.info(`---\`saveConvo\` context: ${metadata?.context}`); - update.expiredAt = null; - } - } else { - update.expiredAt = null; - } - - /** @type {{ $set: Partial; $unset?: Record }} */ - const updateOperation = { $set: update }; - if (metadata && metadata.unsetFields && Object.keys(metadata.unsetFields).length > 0) { - updateOperation.$unset = metadata.unsetFields; - } - - /** Note: the resulting Model object is necessary for Meilisearch operations */ - const conversation = await Conversation.findOneAndUpdate( - { conversationId, user: req.user.id }, - updateOperation, - { - new: true, - upsert: metadata?.noUpsert !== true, - }, - ); - - if (!conversation) { - logger.debug('[saveConvo] Conversation not found, skipping update'); - return null; - } - - return conversation.toObject(); - } catch (error) { - logger.error('[saveConvo] Error saving conversation', error); - if (metadata && metadata?.context) { - logger.info(`[saveConvo] ${metadata.context}`); - } - return { message: 'Error saving conversation' }; - } - }, - bulkSaveConvos: async (conversations) => { - try { - const bulkOps = conversations.map((convo) => ({ - updateOne: { - filter: { conversationId: convo.conversationId, user: convo.user }, - update: convo, - upsert: true, - timestamps: false, - }, - })); - - const result = await Conversation.bulkWrite(bulkOps); - return result; - } catch (error) { - logger.error('[bulkSaveConvos] Error saving conversations in bulk', error); - throw new Error('Failed to save conversations in bulk.'); - } - }, - getConvosByCursor: async ( - user, - { - cursor, - limit = 25, - isArchived = false, - tags, - search, - sortBy = 'updatedAt', - sortDirection = 'desc', - } = {}, - ) => { - const filters = [{ user }]; - if (isArchived) { - filters.push({ isArchived: true }); - } else { - filters.push({ $or: [{ isArchived: false }, { isArchived: { $exists: false } }] }); - } - - if (Array.isArray(tags) && tags.length > 0) { - filters.push({ tags: { $in: tags } }); - } - - filters.push({ $or: [{ expiredAt: null }, { expiredAt: { $exists: false } }] }); - - if (search) { - try { - const meiliResults = await Conversation.meiliSearch(search, { filter: `user = "${user}"` }); - const matchingIds = Array.isArray(meiliResults.hits) - ? meiliResults.hits.map((result) => result.conversationId) - : []; - if (!matchingIds.length) { - return { conversations: [], nextCursor: null }; - } - filters.push({ conversationId: { $in: matchingIds } }); - } catch (error) { - logger.error('[getConvosByCursor] Error during meiliSearch', error); - throw new Error('Error during meiliSearch'); - } - } - - const validSortFields = ['title', 'createdAt', 'updatedAt']; - if (!validSortFields.includes(sortBy)) { - throw new Error( - `Invalid sortBy field: ${sortBy}. Must be one of ${validSortFields.join(', ')}`, - ); - } - const finalSortBy = sortBy; - const finalSortDirection = sortDirection === 'asc' ? 'asc' : 'desc'; - - let cursorFilter = null; - if (cursor) { - try { - const decoded = JSON.parse(Buffer.from(cursor, 'base64').toString()); - const { primary, secondary } = decoded; - const primaryValue = finalSortBy === 'title' ? primary : new Date(primary); - const secondaryValue = new Date(secondary); - const op = finalSortDirection === 'asc' ? '$gt' : '$lt'; - - cursorFilter = { - $or: [ - { [finalSortBy]: { [op]: primaryValue } }, - { - [finalSortBy]: primaryValue, - updatedAt: { [op]: secondaryValue }, - }, - ], - }; - } catch (err) { - logger.warn('[getConvosByCursor] Invalid cursor format, starting from beginning'); - } - if (cursorFilter) { - filters.push(cursorFilter); - } - } - - const query = filters.length === 1 ? filters[0] : { $and: filters }; - - try { - const sortOrder = finalSortDirection === 'asc' ? 1 : -1; - const sortObj = { [finalSortBy]: sortOrder }; - - if (finalSortBy !== 'updatedAt') { - sortObj.updatedAt = sortOrder; - } - - const convos = await Conversation.find(query) - .select( - 'conversationId endpoint title createdAt updatedAt user model agent_id assistant_id spec iconURL', - ) - .sort(sortObj) - .limit(limit + 1) - .lean(); - - let nextCursor = null; - if (convos.length > limit) { - convos.pop(); // Remove extra item used to detect next page - // Create cursor from the last RETURNED item (not the popped one) - const lastReturned = convos[convos.length - 1]; - const primaryValue = lastReturned[finalSortBy]; - const primaryStr = finalSortBy === 'title' ? primaryValue : primaryValue.toISOString(); - const secondaryStr = lastReturned.updatedAt.toISOString(); - const composite = { primary: primaryStr, secondary: secondaryStr }; - nextCursor = Buffer.from(JSON.stringify(composite)).toString('base64'); - } - - return { conversations: convos, nextCursor }; - } catch (error) { - logger.error('[getConvosByCursor] Error getting conversations', error); - throw new Error('Error getting conversations'); - } - }, - getConvosQueried: async (user, convoIds, cursor = null, limit = 25) => { - try { - if (!convoIds?.length) { - return { conversations: [], nextCursor: null, convoMap: {} }; - } - - const conversationIds = convoIds.map((convo) => convo.conversationId); - - const results = await Conversation.find({ - user, - conversationId: { $in: conversationIds }, - $or: [{ expiredAt: { $exists: false } }, { expiredAt: null }], - }).lean(); - - results.sort((a, b) => new Date(b.updatedAt) - new Date(a.updatedAt)); - - let filtered = results; - if (cursor && cursor !== 'start') { - const cursorDate = new Date(cursor); - filtered = results.filter((convo) => new Date(convo.updatedAt) < cursorDate); - } - - const limited = filtered.slice(0, limit + 1); - let nextCursor = null; - if (limited.length > limit) { - limited.pop(); // Remove extra item used to detect next page - // Create cursor from the last RETURNED item (not the popped one) - nextCursor = limited[limited.length - 1].updatedAt.toISOString(); - } - - const convoMap = {}; - limited.forEach((convo) => { - convoMap[convo.conversationId] = convo; - }); - - return { conversations: limited, nextCursor, convoMap }; - } catch (error) { - logger.error('[getConvosQueried] Error getting conversations', error); - throw new Error('Error fetching conversations'); - } - }, - getConvo, - /* chore: this method is not properly error handled */ - getConvoTitle: async (user, conversationId) => { - try { - const convo = await getConvo(user, conversationId); - /* ChatGPT Browser was triggering error here due to convo being saved later */ - if (convo && !convo.title) { - return null; - } else { - // TypeError: Cannot read properties of null (reading 'title') - return convo?.title || 'New Chat'; - } - } catch (error) { - logger.error('[getConvoTitle] Error getting conversation title', error); - throw new Error('Error getting conversation title'); - } - }, - /** - * Asynchronously deletes conversations and associated messages for a given user and filter. - * - * @async - * @function - * @param {string|ObjectId} user - The user's ID. - * @param {Object} filter - Additional filter criteria for the conversations to be deleted. - * @returns {Promise<{ n: number, ok: number, deletedCount: number, messages: { n: number, ok: number, deletedCount: number } }>} - * An object containing the count of deleted conversations and associated messages. - * @throws {Error} Throws an error if there's an issue with the database operations. - * - * @example - * const user = 'someUserId'; - * const filter = { someField: 'someValue' }; - * const result = await deleteConvos(user, filter); - * logger.error(result); // { n: 5, ok: 1, deletedCount: 5, messages: { n: 10, ok: 1, deletedCount: 10 } } - */ - deleteConvos: async (user, filter) => { - try { - const userFilter = { ...filter, user }; - const conversations = await Conversation.find(userFilter).select('conversationId'); - const conversationIds = conversations.map((c) => c.conversationId); - - if (!conversationIds.length) { - throw new Error('Conversation not found or already deleted.'); - } - - const deleteConvoResult = await Conversation.deleteMany(userFilter); - - const deleteMessagesResult = await deleteMessages({ - conversationId: { $in: conversationIds }, - }); - - return { ...deleteConvoResult, messages: deleteMessagesResult }; - } catch (error) { - logger.error('[deleteConvos] Error deleting conversations and messages', error); - throw error; - } - }, -}; diff --git a/api/models/ConversationTag.js b/api/models/ConversationTag.js deleted file mode 100644 index 47a6c2bbf5..0000000000 --- a/api/models/ConversationTag.js +++ /dev/null @@ -1,284 +0,0 @@ -const { logger } = require('@librechat/data-schemas'); -const { ConversationTag, Conversation } = require('~/db/models'); - -/** - * Retrieves all conversation tags for a user. - * @param {string} user - The user ID. - * @returns {Promise} An array of conversation tags. - */ -const getConversationTags = async (user) => { - try { - return await ConversationTag.find({ user }).sort({ position: 1 }).lean(); - } catch (error) { - logger.error('[getConversationTags] Error getting conversation tags', error); - throw new Error('Error getting conversation tags'); - } -}; - -/** - * Creates a new conversation tag. - * @param {string} user - The user ID. - * @param {Object} data - The tag data. - * @param {string} data.tag - The tag name. - * @param {string} [data.description] - The tag description. - * @param {boolean} [data.addToConversation] - Whether to add the tag to a conversation. - * @param {string} [data.conversationId] - The conversation ID to add the tag to. - * @returns {Promise} The created tag. - */ -const createConversationTag = async (user, data) => { - try { - const { tag, description, addToConversation, conversationId } = data; - - const existingTag = await ConversationTag.findOne({ user, tag }).lean(); - if (existingTag) { - return existingTag; - } - - const maxPosition = await ConversationTag.findOne({ user }).sort('-position').lean(); - const position = (maxPosition?.position || 0) + 1; - - const newTag = await ConversationTag.findOneAndUpdate( - { tag, user }, - { - tag, - user, - count: addToConversation ? 1 : 0, - position, - description, - $setOnInsert: { createdAt: new Date() }, - }, - { - new: true, - upsert: true, - lean: true, - }, - ); - - if (addToConversation && conversationId) { - await Conversation.findOneAndUpdate( - { user, conversationId }, - { $addToSet: { tags: tag } }, - { new: true }, - ); - } - - return newTag; - } catch (error) { - logger.error('[createConversationTag] Error creating conversation tag', error); - throw new Error('Error creating conversation tag'); - } -}; - -/** - * Updates an existing conversation tag. - * @param {string} user - The user ID. - * @param {string} oldTag - The current tag name. - * @param {Object} data - The updated tag data. - * @param {string} [data.tag] - The new tag name. - * @param {string} [data.description] - The updated description. - * @param {number} [data.position] - The new position. - * @returns {Promise} The updated tag. - */ -const updateConversationTag = async (user, oldTag, data) => { - try { - const { tag: newTag, description, position } = data; - - const existingTag = await ConversationTag.findOne({ user, tag: oldTag }).lean(); - if (!existingTag) { - return null; - } - - if (newTag && newTag !== oldTag) { - const tagAlreadyExists = await ConversationTag.findOne({ user, tag: newTag }).lean(); - if (tagAlreadyExists) { - throw new Error('Tag already exists'); - } - - await Conversation.updateMany({ user, tags: oldTag }, { $set: { 'tags.$': newTag } }); - } - - const updateData = {}; - if (newTag) { - updateData.tag = newTag; - } - if (description !== undefined) { - updateData.description = description; - } - if (position !== undefined) { - await adjustPositions(user, existingTag.position, position); - updateData.position = position; - } - - return await ConversationTag.findOneAndUpdate({ user, tag: oldTag }, updateData, { - new: true, - lean: true, - }); - } catch (error) { - logger.error('[updateConversationTag] Error updating conversation tag', error); - throw new Error('Error updating conversation tag'); - } -}; - -/** - * Adjusts positions of tags when a tag's position is changed. - * @param {string} user - The user ID. - * @param {number} oldPosition - The old position of the tag. - * @param {number} newPosition - The new position of the tag. - * @returns {Promise} - */ -const adjustPositions = async (user, oldPosition, newPosition) => { - if (oldPosition === newPosition) { - return; - } - - const update = oldPosition < newPosition ? { $inc: { position: -1 } } : { $inc: { position: 1 } }; - const position = - oldPosition < newPosition - ? { - $gt: Math.min(oldPosition, newPosition), - $lte: Math.max(oldPosition, newPosition), - } - : { - $gte: Math.min(oldPosition, newPosition), - $lt: Math.max(oldPosition, newPosition), - }; - - await ConversationTag.updateMany( - { - user, - position, - }, - update, - ); -}; - -/** - * Deletes a conversation tag. - * @param {string} user - The user ID. - * @param {string} tag - The tag to delete. - * @returns {Promise} The deleted tag. - */ -const deleteConversationTag = async (user, tag) => { - try { - const deletedTag = await ConversationTag.findOneAndDelete({ user, tag }).lean(); - if (!deletedTag) { - return null; - } - - await Conversation.updateMany({ user, tags: tag }, { $pull: { tags: tag } }); - - await ConversationTag.updateMany( - { user, position: { $gt: deletedTag.position } }, - { $inc: { position: -1 } }, - ); - - return deletedTag; - } catch (error) { - logger.error('[deleteConversationTag] Error deleting conversation tag', error); - throw new Error('Error deleting conversation tag'); - } -}; - -/** - * Updates tags for a specific conversation. - * @param {string} user - The user ID. - * @param {string} conversationId - The conversation ID. - * @param {string[]} tags - The new set of tags for the conversation. - * @returns {Promise} The updated list of tags for the conversation. - */ -const updateTagsForConversation = async (user, conversationId, tags) => { - try { - const conversation = await Conversation.findOne({ user, conversationId }).lean(); - if (!conversation) { - throw new Error('Conversation not found'); - } - - const oldTags = new Set(conversation.tags); - const newTags = new Set(tags); - - const addedTags = [...newTags].filter((tag) => !oldTags.has(tag)); - const removedTags = [...oldTags].filter((tag) => !newTags.has(tag)); - - const bulkOps = []; - - for (const tag of addedTags) { - bulkOps.push({ - updateOne: { - filter: { user, tag }, - update: { $inc: { count: 1 } }, - upsert: true, - }, - }); - } - - for (const tag of removedTags) { - bulkOps.push({ - updateOne: { - filter: { user, tag }, - update: { $inc: { count: -1 } }, - }, - }); - } - - if (bulkOps.length > 0) { - await ConversationTag.bulkWrite(bulkOps); - } - - const updatedConversation = ( - await Conversation.findOneAndUpdate( - { user, conversationId }, - { $set: { tags: [...newTags] } }, - { new: true }, - ) - ).toObject(); - - return updatedConversation.tags; - } catch (error) { - logger.error('[updateTagsForConversation] Error updating tags', error); - throw new Error('Error updating tags for conversation'); - } -}; - -/** - * Increments tag counts for existing tags only. - * @param {string} user - The user ID. - * @param {string[]} tags - Array of tag names to increment - * @returns {Promise} - */ -const bulkIncrementTagCounts = async (user, tags) => { - if (!tags || tags.length === 0) { - return; - } - - try { - const uniqueTags = [...new Set(tags.filter(Boolean))]; - if (uniqueTags.length === 0) { - return; - } - - const bulkOps = uniqueTags.map((tag) => ({ - updateOne: { - filter: { user, tag }, - update: { $inc: { count: 1 } }, - }, - })); - - const result = await ConversationTag.bulkWrite(bulkOps); - if (result && result.modifiedCount > 0) { - logger.debug( - `user: ${user} | Incremented tag counts - modified ${result.modifiedCount} tags`, - ); - } - } catch (error) { - logger.error('[bulkIncrementTagCounts] Error incrementing tag counts', error); - } -}; - -module.exports = { - getConversationTags, - createConversationTag, - updateConversationTag, - deleteConversationTag, - bulkIncrementTagCounts, - updateTagsForConversation, -}; diff --git a/api/models/File.js b/api/models/File.js deleted file mode 100644 index 1a01ef12f9..0000000000 --- a/api/models/File.js +++ /dev/null @@ -1,250 +0,0 @@ -const { logger } = require('@librechat/data-schemas'); -const { EToolResources, FileContext } = require('librechat-data-provider'); -const { File } = require('~/db/models'); - -/** - * Finds a file by its file_id with additional query options. - * @param {string} file_id - The unique identifier of the file. - * @param {object} options - Query options for filtering, projection, etc. - * @returns {Promise} A promise that resolves to the file document or null. - */ -const findFileById = async (file_id, options = {}) => { - return await File.findOne({ file_id, ...options }).lean(); -}; - -/** - * Retrieves files matching a given filter, sorted by the most recently updated. - * @param {Object} filter - The filter criteria to apply. - * @param {Object} [_sortOptions] - Optional sort parameters. - * @param {Object|String} [selectFields={ text: 0 }] - Fields to include/exclude in the query results. - * Default excludes the 'text' field. - * @returns {Promise>} A promise that resolves to an array of file documents. - */ -const getFiles = async (filter, _sortOptions, selectFields = { text: 0 }) => { - const sortOptions = { updatedAt: -1, ..._sortOptions }; - return await File.find(filter).select(selectFields).sort(sortOptions).lean(); -}; - -/** - * Retrieves tool files (files that are embedded or have a fileIdentifier) from an array of file IDs. - * Note: execute_code files are handled separately by getCodeGeneratedFiles. - * @param {string[]} fileIds - Array of file_id strings to search for - * @param {Set} toolResourceSet - Optional filter for tool resources - * @returns {Promise>} Files that match the criteria - */ -const getToolFilesByIds = async (fileIds, toolResourceSet) => { - if (!fileIds || !fileIds.length || !toolResourceSet?.size) { - return []; - } - - try { - const orConditions = []; - - if (toolResourceSet.has(EToolResources.context)) { - orConditions.push({ text: { $exists: true, $ne: null }, context: FileContext.agents }); - } - if (toolResourceSet.has(EToolResources.file_search)) { - orConditions.push({ embedded: true }); - } - - if (orConditions.length === 0) { - return []; - } - - const filter = { - file_id: { $in: fileIds }, - context: { $ne: FileContext.execute_code }, // Exclude code-generated files - $or: orConditions, - }; - - const selectFields = { text: 0 }; - const sortOptions = { updatedAt: -1 }; - - return await getFiles(filter, sortOptions, selectFields); - } catch (error) { - logger.error('[getToolFilesByIds] Error retrieving tool files:', error); - throw new Error('Error retrieving tool files'); - } -}; - -/** - * Retrieves files generated by code execution for a given conversation. - * These files are stored locally with fileIdentifier metadata for code env re-upload. - * @param {string} conversationId - The conversation ID to search for - * @param {string[]} [messageIds] - Optional array of messageIds to filter by (for linear thread filtering) - * @returns {Promise>} Files generated by code execution in the conversation - */ -const getCodeGeneratedFiles = async (conversationId, messageIds) => { - if (!conversationId) { - return []; - } - - /** messageIds are required for proper thread filtering of code-generated files */ - if (!messageIds || messageIds.length === 0) { - return []; - } - - try { - const filter = { - conversationId, - context: FileContext.execute_code, - messageId: { $exists: true, $in: messageIds }, - 'metadata.fileIdentifier': { $exists: true }, - }; - - const selectFields = { text: 0 }; - const sortOptions = { createdAt: 1 }; - - return await getFiles(filter, sortOptions, selectFields); - } catch (error) { - logger.error('[getCodeGeneratedFiles] Error retrieving code generated files:', error); - return []; - } -}; - -/** - * Retrieves user-uploaded execute_code files (not code-generated) by their file IDs. - * These are files with fileIdentifier metadata but context is NOT execute_code (e.g., agents or message_attachment). - * File IDs should be collected from message.files arrays in the current thread. - * @param {string[]} fileIds - Array of file IDs to fetch (from message.files in the thread) - * @returns {Promise>} User-uploaded execute_code files - */ -const getUserCodeFiles = async (fileIds) => { - if (!fileIds || fileIds.length === 0) { - return []; - } - - try { - const filter = { - file_id: { $in: fileIds }, - context: { $ne: FileContext.execute_code }, - 'metadata.fileIdentifier': { $exists: true }, - }; - - const selectFields = { text: 0 }; - const sortOptions = { createdAt: 1 }; - - return await getFiles(filter, sortOptions, selectFields); - } catch (error) { - logger.error('[getUserCodeFiles] Error retrieving user code files:', error); - return []; - } -}; - -/** - * Creates a new file with a TTL of 1 hour. - * @param {MongoFile} data - The file data to be created, must contain file_id. - * @param {boolean} disableTTL - Whether to disable the TTL. - * @returns {Promise} A promise that resolves to the created file document. - */ -const createFile = async (data, disableTTL) => { - const fileData = { - ...data, - expiresAt: new Date(Date.now() + 3600 * 1000), - }; - - if (disableTTL) { - delete fileData.expiresAt; - } - - return await File.findOneAndUpdate({ file_id: data.file_id }, fileData, { - new: true, - upsert: true, - }).lean(); -}; - -/** - * Updates a file identified by file_id with new data and removes the TTL. - * @param {MongoFile} data - The data to update, must contain file_id. - * @returns {Promise} A promise that resolves to the updated file document. - */ -const updateFile = async (data) => { - const { file_id, ...update } = data; - const updateOperation = { - $set: update, - $unset: { expiresAt: '' }, // Remove the expiresAt field to prevent TTL - }; - return await File.findOneAndUpdate({ file_id }, updateOperation, { new: true }).lean(); -}; - -/** - * Increments the usage of a file identified by file_id. - * @param {MongoFile} data - The data to update, must contain file_id and the increment value for usage. - * @returns {Promise} A promise that resolves to the updated file document. - */ -const updateFileUsage = async (data) => { - const { file_id, inc = 1 } = data; - const updateOperation = { - $inc: { usage: inc }, - $unset: { expiresAt: '', temp_file_id: '' }, - }; - return await File.findOneAndUpdate({ file_id }, updateOperation, { new: true }).lean(); -}; - -/** - * Deletes a file identified by file_id. - * @param {string} file_id - The unique identifier of the file to delete. - * @returns {Promise} A promise that resolves to the deleted file document or null. - */ -const deleteFile = async (file_id) => { - return await File.findOneAndDelete({ file_id }).lean(); -}; - -/** - * Deletes a file identified by a filter. - * @param {object} filter - The filter criteria to apply. - * @returns {Promise} A promise that resolves to the deleted file document or null. - */ -const deleteFileByFilter = async (filter) => { - return await File.findOneAndDelete(filter).lean(); -}; - -/** - * Deletes multiple files identified by an array of file_ids. - * @param {Array} file_ids - The unique identifiers of the files to delete. - * @returns {Promise} A promise that resolves to the result of the deletion operation. - */ -const deleteFiles = async (file_ids, user) => { - let deleteQuery = { file_id: { $in: file_ids } }; - if (user) { - deleteQuery = { user: user }; - } - return await File.deleteMany(deleteQuery); -}; - -/** - * Batch updates files with new signed URLs in MongoDB - * - * @param {MongoFile[]} updates - Array of updates in the format { file_id, filepath } - * @returns {Promise} - */ -async function batchUpdateFiles(updates) { - if (!updates || updates.length === 0) { - return; - } - - const bulkOperations = updates.map((update) => ({ - updateOne: { - filter: { file_id: update.file_id }, - update: { $set: { filepath: update.filepath } }, - }, - })); - - const result = await File.bulkWrite(bulkOperations); - logger.info(`Updated ${result.modifiedCount} files with new S3 URLs`); -} - -module.exports = { - findFileById, - getFiles, - getToolFilesByIds, - getCodeGeneratedFiles, - getUserCodeFiles, - createFile, - updateFile, - updateFileUsage, - deleteFile, - deleteFiles, - deleteFileByFilter, - batchUpdateFiles, -}; diff --git a/api/models/File.spec.js b/api/models/File.spec.js deleted file mode 100644 index 2d4282cff7..0000000000 --- a/api/models/File.spec.js +++ /dev/null @@ -1,629 +0,0 @@ -const mongoose = require('mongoose'); -const { v4: uuidv4 } = require('uuid'); -const { MongoMemoryServer } = require('mongodb-memory-server'); -const { createModels, createMethods } = require('@librechat/data-schemas'); -const { - SystemRoles, - ResourceType, - AccessRoleIds, - PrincipalType, -} = require('librechat-data-provider'); -const { grantPermission } = require('~/server/services/PermissionService'); -const { createAgent } = require('./Agent'); - -let File; -let Agent; -let AclEntry; -let User; -let modelsToCleanup = []; -let methods; -let getFiles; -let createFile; -let seedDefaultRoles; - -describe('File Access Control', () => { - let mongoServer; - - beforeAll(async () => { - mongoServer = await MongoMemoryServer.create(); - const mongoUri = mongoServer.getUri(); - await mongoose.connect(mongoUri); - - // Initialize all models - const models = createModels(mongoose); - - // Track which models we're adding - modelsToCleanup = Object.keys(models); - - // Register models on mongoose.models so methods can access them - const dbModels = require('~/db/models'); - Object.assign(mongoose.models, dbModels); - - File = dbModels.File; - Agent = dbModels.Agent; - AclEntry = dbModels.AclEntry; - User = dbModels.User; - - // Create methods from data-schemas (includes file methods) - methods = createMethods(mongoose); - getFiles = methods.getFiles; - createFile = methods.createFile; - seedDefaultRoles = methods.seedDefaultRoles; - - // Seed default roles - await seedDefaultRoles(); - }); - - afterAll(async () => { - // Clean up all collections before disconnecting - const collections = mongoose.connection.collections; - for (const key in collections) { - await collections[key].deleteMany({}); - } - - // Clear only the models we added - for (const modelName of modelsToCleanup) { - if (mongoose.models[modelName]) { - delete mongoose.models[modelName]; - } - } - - await mongoose.disconnect(); - await mongoServer.stop(); - }); - - beforeEach(async () => { - await File.deleteMany({}); - await Agent.deleteMany({}); - await AclEntry.deleteMany({}); - await User.deleteMany({}); - // Don't delete AccessRole as they are seeded defaults needed for tests - }); - - describe('hasAccessToFilesViaAgent', () => { - it('should efficiently check access for multiple files at once', async () => { - const userId = new mongoose.Types.ObjectId(); - const authorId = new mongoose.Types.ObjectId(); - const agentId = uuidv4(); - const fileIds = [uuidv4(), uuidv4(), uuidv4(), uuidv4()]; - - // Create users - await User.create({ - _id: userId, - email: 'user@example.com', - emailVerified: true, - provider: 'local', - }); - - await User.create({ - _id: authorId, - email: 'author@example.com', - emailVerified: true, - provider: 'local', - }); - - // Create files - for (const fileId of fileIds) { - await createFile({ - user: authorId, - file_id: fileId, - filename: `file-${fileId}.txt`, - filepath: `/uploads/${fileId}`, - }); - } - - // Create agent with only first two files attached - const agent = await createAgent({ - id: agentId, - name: 'Test Agent', - author: authorId, - model: 'gpt-4', - provider: 'openai', - tool_resources: { - file_search: { - file_ids: [fileIds[0], fileIds[1]], - }, - }, - }); - - // Grant EDIT permission to user on the agent - await grantPermission({ - principalType: PrincipalType.USER, - principalId: userId, - resourceType: ResourceType.AGENT, - resourceId: agent._id, - accessRoleId: AccessRoleIds.AGENT_EDITOR, - grantedBy: authorId, - }); - - // Check access for all files - const { hasAccessToFilesViaAgent } = require('~/server/services/Files/permissions'); - const accessMap = await hasAccessToFilesViaAgent({ - userId: userId, - role: SystemRoles.USER, - fileIds, - agentId: agent.id, // Use agent.id which is the custom UUID - }); - - // Should have access only to the first two files - expect(accessMap.get(fileIds[0])).toBe(true); - expect(accessMap.get(fileIds[1])).toBe(true); - expect(accessMap.get(fileIds[2])).toBe(false); - expect(accessMap.get(fileIds[3])).toBe(false); - }); - - it('should grant access to all files when user is the agent author', 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', - emailVerified: true, - provider: 'local', - }); - - // Create agent - await createAgent({ - id: agentId, - name: 'Test Agent', - author: authorId, - model: 'gpt-4', - provider: 'openai', - tool_resources: { - file_search: { - file_ids: [fileIds[0]], // Only one file attached - }, - }, - }); - - // Check access as the author - const { hasAccessToFilesViaAgent } = require('~/server/services/Files/permissions'); - const accessMap = await hasAccessToFilesViaAgent({ - userId: authorId, - role: SystemRoles.USER, - fileIds, - 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); - }); - - it('should handle non-existent agent gracefully', async () => { - const userId = new mongoose.Types.ObjectId(); - const fileIds = [uuidv4(), uuidv4()]; - - // Create user - await User.create({ - _id: userId, - email: 'user@example.com', - emailVerified: true, - provider: 'local', - }); - - const { hasAccessToFilesViaAgent } = require('~/server/services/Files/permissions'); - const accessMap = await hasAccessToFilesViaAgent({ - userId: userId, - role: SystemRoles.USER, - fileIds, - agentId: 'non-existent-agent', - }); - - // Should have no access to any files - expect(accessMap.get(fileIds[0])).toBe(false); - expect(accessMap.get(fileIds[1])).toBe(false); - }); - - it('should deny access when user only has VIEW permission and needs access for deletion', async () => { - const userId = new mongoose.Types.ObjectId(); - const authorId = new mongoose.Types.ObjectId(); - const agentId = uuidv4(); - const fileIds = [uuidv4(), uuidv4()]; - - // Create users - await User.create({ - _id: userId, - email: 'user@example.com', - emailVerified: true, - provider: 'local', - }); - - await User.create({ - _id: authorId, - email: 'author@example.com', - emailVerified: true, - provider: 'local', - }); - - // Create agent with files - const agent = await createAgent({ - id: agentId, - name: 'View-Only Agent', - author: authorId, - model: 'gpt-4', - provider: 'openai', - tool_resources: { - file_search: { - file_ids: fileIds, - }, - }, - }); - - // Grant only VIEW permission to user on the agent - await grantPermission({ - principalType: PrincipalType.USER, - principalId: userId, - resourceType: ResourceType.AGENT, - resourceId: agent._id, - accessRoleId: AccessRoleIds.AGENT_VIEWER, - grantedBy: authorId, - }); - - // Check access for files - const { hasAccessToFilesViaAgent } = require('~/server/services/Files/permissions'); - const accessMap = await hasAccessToFilesViaAgent({ - userId: userId, - role: SystemRoles.USER, - fileIds, - agentId, - isDelete: true, - }); - - // Should have no access to any files when only VIEW permission - expect(accessMap.get(fileIds[0])).toBe(false); - expect(accessMap.get(fileIds[1])).toBe(false); - }); - - it('should grant access when user has VIEW permission', async () => { - const userId = new mongoose.Types.ObjectId(); - const authorId = new mongoose.Types.ObjectId(); - const agentId = uuidv4(); - const fileIds = [uuidv4(), uuidv4()]; - - // Create users - await User.create({ - _id: userId, - email: 'user@example.com', - emailVerified: true, - provider: 'local', - }); - - await User.create({ - _id: authorId, - email: 'author@example.com', - emailVerified: true, - provider: 'local', - }); - - // Create agent with files - const agent = await createAgent({ - id: agentId, - name: 'View-Only Agent', - author: authorId, - model: 'gpt-4', - provider: 'openai', - tool_resources: { - file_search: { - file_ids: fileIds, - }, - }, - }); - - // Grant only VIEW permission to user on the agent - await grantPermission({ - principalType: PrincipalType.USER, - principalId: userId, - resourceType: ResourceType.AGENT, - resourceId: agent._id, - accessRoleId: AccessRoleIds.AGENT_VIEWER, - grantedBy: authorId, - }); - - // Check access for files - const { hasAccessToFilesViaAgent } = require('~/server/services/Files/permissions'); - const accessMap = await hasAccessToFilesViaAgent({ - userId: userId, - role: SystemRoles.USER, - fileIds, - agentId, - }); - - expect(accessMap.get(fileIds[0])).toBe(true); - expect(accessMap.get(fileIds[1])).toBe(true); - }); - }); - - describe('getFiles with agent access control', () => { - test('should return files owned by user and files accessible through agent', async () => { - const authorId = new mongoose.Types.ObjectId(); - const userId = new mongoose.Types.ObjectId(); - const agentId = `agent_${uuidv4()}`; - const ownedFileId = `file_${uuidv4()}`; - const sharedFileId = `file_${uuidv4()}`; - const inaccessibleFileId = `file_${uuidv4()}`; - - // Create users - await User.create({ - _id: userId, - email: 'user@example.com', - emailVerified: true, - provider: 'local', - }); - - await User.create({ - _id: authorId, - email: 'author@example.com', - emailVerified: true, - provider: 'local', - }); - - // Create agent with shared file - const agent = await createAgent({ - id: agentId, - name: 'Shared Agent', - provider: 'test', - model: 'test-model', - author: authorId, - tool_resources: { - file_search: { - file_ids: [sharedFileId], - }, - }, - }); - - // Grant EDIT permission to user on the agent - await grantPermission({ - principalType: PrincipalType.USER, - principalId: userId, - resourceType: ResourceType.AGENT, - resourceId: agent._id, - accessRoleId: AccessRoleIds.AGENT_EDITOR, - grantedBy: authorId, - }); - - // Create files - await createFile({ - file_id: ownedFileId, - user: userId, - filename: 'owned.txt', - filepath: '/uploads/owned.txt', - type: 'text/plain', - bytes: 100, - }); - - await createFile({ - file_id: sharedFileId, - user: authorId, - filename: 'shared.txt', - filepath: '/uploads/shared.txt', - type: 'text/plain', - bytes: 200, - embedded: true, - }); - - await createFile({ - file_id: inaccessibleFileId, - user: authorId, - filename: 'inaccessible.txt', - filepath: '/uploads/inaccessible.txt', - type: 'text/plain', - bytes: 300, - }); - - // Get all files first - const allFiles = await getFiles( - { file_id: { $in: [ownedFileId, sharedFileId, inaccessibleFileId] } }, - null, - { text: 0 }, - ); - - // Then filter by access control - const { filterFilesByAgentAccess } = require('~/server/services/Files/permissions'); - const files = await filterFilesByAgentAccess({ - files: allFiles, - userId: userId, - role: SystemRoles.USER, - agentId, - }); - - expect(files).toHaveLength(2); - expect(files.map((f) => f.file_id)).toContain(ownedFileId); - expect(files.map((f) => f.file_id)).toContain(sharedFileId); - expect(files.map((f) => f.file_id)).not.toContain(inaccessibleFileId); - }); - - test('should return all files when no userId/agentId provided', async () => { - const userId = new mongoose.Types.ObjectId(); - const fileId1 = `file_${uuidv4()}`; - const fileId2 = `file_${uuidv4()}`; - - await createFile({ - file_id: fileId1, - user: userId, - filename: 'file1.txt', - filepath: '/uploads/file1.txt', - type: 'text/plain', - bytes: 100, - }); - - await createFile({ - file_id: fileId2, - user: new mongoose.Types.ObjectId(), - filename: 'file2.txt', - filepath: '/uploads/file2.txt', - type: 'text/plain', - bytes: 200, - }); - - const files = await getFiles({ file_id: { $in: [fileId1, fileId2] } }); - expect(files).toHaveLength(2); - }); - }); - - describe('Role-based file permissions', () => { - it('should optimize permission checks when role is provided', async () => { - const userId = new mongoose.Types.ObjectId(); - const authorId = new mongoose.Types.ObjectId(); - const agentId = uuidv4(); - const fileIds = [uuidv4(), uuidv4()]; - - // Create users - await User.create({ - _id: userId, - email: 'user@example.com', - emailVerified: true, - provider: 'local', - role: 'ADMIN', // User has ADMIN role - }); - - await User.create({ - _id: authorId, - email: 'author@example.com', - emailVerified: true, - provider: 'local', - }); - - // Create files - for (const fileId of fileIds) { - await createFile({ - file_id: fileId, - user: authorId, - filename: `${fileId}.txt`, - filepath: `/uploads/${fileId}.txt`, - type: 'text/plain', - bytes: 100, - }); - } - - // Create agent with files - const agent = await createAgent({ - id: agentId, - name: 'Test Agent', - author: authorId, - model: 'gpt-4', - provider: 'openai', - tool_resources: { - file_search: { - file_ids: fileIds, - }, - }, - }); - - // Grant permission to ADMIN role - await grantPermission({ - principalType: PrincipalType.ROLE, - principalId: 'ADMIN', - resourceType: ResourceType.AGENT, - resourceId: agent._id, - accessRoleId: AccessRoleIds.AGENT_EDITOR, - grantedBy: authorId, - }); - - // Check access with role provided (should avoid DB query) - const { hasAccessToFilesViaAgent } = require('~/server/services/Files/permissions'); - const accessMapWithRole = await hasAccessToFilesViaAgent({ - userId: userId, - role: 'ADMIN', - fileIds, - agentId: agent.id, - }); - - // User should have access through their ADMIN role - expect(accessMapWithRole.get(fileIds[0])).toBe(true); - expect(accessMapWithRole.get(fileIds[1])).toBe(true); - - // Check access without role (will query DB to get user's role) - const accessMapWithoutRole = await hasAccessToFilesViaAgent({ - userId: userId, - fileIds, - agentId: agent.id, - }); - - // Should have same result - expect(accessMapWithoutRole.get(fileIds[0])).toBe(true); - expect(accessMapWithoutRole.get(fileIds[1])).toBe(true); - }); - - it('should deny access when user role changes', async () => { - const userId = new mongoose.Types.ObjectId(); - const authorId = new mongoose.Types.ObjectId(); - const agentId = uuidv4(); - const fileId = uuidv4(); - - // Create users - await User.create({ - _id: userId, - email: 'user@example.com', - emailVerified: true, - provider: 'local', - role: 'EDITOR', - }); - - await User.create({ - _id: authorId, - email: 'author@example.com', - emailVerified: true, - provider: 'local', - }); - - // Create file - await createFile({ - file_id: fileId, - user: authorId, - filename: 'test.txt', - filepath: '/uploads/test.txt', - type: 'text/plain', - bytes: 100, - }); - - // Create agent - const agent = await createAgent({ - id: agentId, - name: 'Test Agent', - author: authorId, - model: 'gpt-4', - provider: 'openai', - tool_resources: { - file_search: { - file_ids: [fileId], - }, - }, - }); - - // Grant permission to EDITOR role only - await grantPermission({ - principalType: PrincipalType.ROLE, - principalId: 'EDITOR', - resourceType: ResourceType.AGENT, - resourceId: agent._id, - accessRoleId: AccessRoleIds.AGENT_EDITOR, - grantedBy: authorId, - }); - - const { hasAccessToFilesViaAgent } = require('~/server/services/Files/permissions'); - - // Check with EDITOR role - should have access - const accessAsEditor = await hasAccessToFilesViaAgent({ - userId: userId, - role: 'EDITOR', - fileIds: [fileId], - agentId: agent.id, - }); - expect(accessAsEditor.get(fileId)).toBe(true); - - // Simulate role change to USER - should lose access - const accessAsUser = await hasAccessToFilesViaAgent({ - userId: userId, - role: SystemRoles.USER, - fileIds: [fileId], - agentId: agent.id, - }); - expect(accessAsUser.get(fileId)).toBe(false); - }); - }); -}); diff --git a/api/models/Message.js b/api/models/Message.js deleted file mode 100644 index 8fe04f6f54..0000000000 --- a/api/models/Message.js +++ /dev/null @@ -1,372 +0,0 @@ -const { z } = require('zod'); -const { logger } = require('@librechat/data-schemas'); -const { createTempChatExpirationDate } = require('@librechat/api'); -const { Message } = require('~/db/models'); - -const idSchema = z.string().uuid(); - -/** - * Saves a message in the database. - * - * @async - * @function saveMessage - * @param {ServerRequest} req - The request object containing user information. - * @param {Object} params - The message data object. - * @param {string} params.endpoint - The endpoint where the message originated. - * @param {string} params.iconURL - The URL of the sender's icon. - * @param {string} params.messageId - The unique identifier for the message. - * @param {string} params.newMessageId - The new unique identifier for the message (if applicable). - * @param {string} params.conversationId - The identifier of the conversation. - * @param {string} [params.parentMessageId] - The identifier of the parent message, if any. - * @param {string} params.sender - The identifier of the sender. - * @param {string} params.text - The text content of the message. - * @param {boolean} params.isCreatedByUser - Indicates if the message was created by the user. - * @param {string} [params.error] - Any error associated with the message. - * @param {boolean} [params.unfinished] - Indicates if the message is unfinished. - * @param {Object[]} [params.files] - An array of files associated with the message. - * @param {string} [params.finish_reason] - Reason for finishing the message. - * @param {number} [params.tokenCount] - The number of tokens in the message. - * @param {string} [params.plugin] - Plugin associated with the message. - * @param {string[]} [params.plugins] - An array of plugins associated with the message. - * @param {string} [params.model] - The model used to generate the message. - * @param {Object} [metadata] - Additional metadata for this operation - * @param {string} [metadata.context] - The context of the operation - * @returns {Promise} The updated or newly inserted message document. - * @throws {Error} If there is an error in saving the message. - */ -async function saveMessage(req, params, metadata) { - if (!req?.user?.id) { - throw new Error('User not authenticated'); - } - - const validConvoId = idSchema.safeParse(params.conversationId); - if (!validConvoId.success) { - logger.warn(`Invalid conversation ID: ${params.conversationId}`); - logger.info(`---\`saveMessage\` context: ${metadata?.context}`); - logger.info(`---Invalid conversation ID Params: ${JSON.stringify(params, null, 2)}`); - return; - } - - try { - const update = { - ...params, - user: req.user.id, - messageId: params.newMessageId || params.messageId, - }; - - if (req?.body?.isTemporary) { - try { - const appConfig = req.config; - update.expiredAt = createTempChatExpirationDate(appConfig?.interfaceConfig); - } catch (err) { - logger.error('Error creating temporary chat expiration date:', err); - logger.info(`---\`saveMessage\` context: ${metadata?.context}`); - update.expiredAt = null; - } - } else { - update.expiredAt = null; - } - - if (update.tokenCount != null && isNaN(update.tokenCount)) { - logger.warn( - `Resetting invalid \`tokenCount\` for message \`${params.messageId}\`: ${update.tokenCount}`, - ); - logger.info(`---\`saveMessage\` context: ${metadata?.context}`); - update.tokenCount = 0; - } - const message = await Message.findOneAndUpdate( - { messageId: params.messageId, user: req.user.id }, - update, - { upsert: true, new: true }, - ); - - return message.toObject(); - } catch (err) { - logger.error('Error saving message:', err); - logger.info(`---\`saveMessage\` context: ${metadata?.context}`); - - // Check if this is a duplicate key error (MongoDB error code 11000) - if (err.code === 11000 && err.message.includes('duplicate key error')) { - // Log the duplicate key error but don't crash the application - logger.warn(`Duplicate messageId detected: ${params.messageId}. Continuing execution.`); - - try { - // Try to find the existing message with this ID - const existingMessage = await Message.findOne({ - messageId: params.messageId, - user: req.user.id, - }); - - // If we found it, return it - if (existingMessage) { - return existingMessage.toObject(); - } - - // If we can't find it (unlikely but possible in race conditions) - return { - ...params, - messageId: params.messageId, - user: req.user.id, - }; - } catch (findError) { - // If the findOne also fails, log it but don't crash - logger.warn( - `Could not retrieve existing message with ID ${params.messageId}: ${findError.message}`, - ); - return { - ...params, - messageId: params.messageId, - user: req.user.id, - }; - } - } - - throw err; // Re-throw other errors - } -} - -/** - * Saves multiple messages in the database in bulk. - * - * @async - * @function bulkSaveMessages - * @param {Object[]} messages - An array of message objects to save. - * @param {boolean} [overrideTimestamp=false] - Indicates whether to override the timestamps of the messages. Defaults to false. - * @returns {Promise} The result of the bulk write operation. - * @throws {Error} If there is an error in saving messages in bulk. - */ -async function bulkSaveMessages(messages, overrideTimestamp = false) { - try { - const bulkOps = messages.map((message) => ({ - updateOne: { - filter: { messageId: message.messageId }, - update: message, - timestamps: !overrideTimestamp, - upsert: true, - }, - })); - const result = await Message.bulkWrite(bulkOps); - return result; - } catch (err) { - logger.error('Error saving messages in bulk:', err); - throw err; - } -} - -/** - * Records a message in the database. - * - * @async - * @function recordMessage - * @param {Object} params - The message data object. - * @param {string} params.user - The identifier of the user. - * @param {string} params.endpoint - The endpoint where the message originated. - * @param {string} params.messageId - The unique identifier for the message. - * @param {string} params.conversationId - The identifier of the conversation. - * @param {string} [params.parentMessageId] - The identifier of the parent message, if any. - * @param {Partial} rest - Any additional properties from the TMessage typedef not explicitly listed. - * @returns {Promise} The updated or newly inserted message document. - * @throws {Error} If there is an error in saving the message. - */ -async function recordMessage({ - user, - endpoint, - messageId, - conversationId, - parentMessageId, - ...rest -}) { - try { - // No parsing of convoId as may use threadId - const message = { - user, - endpoint, - messageId, - conversationId, - parentMessageId, - ...rest, - }; - - return await Message.findOneAndUpdate({ user, messageId }, message, { - upsert: true, - new: true, - }); - } catch (err) { - logger.error('Error recording message:', err); - throw err; - } -} - -/** - * Updates the text of a message. - * - * @async - * @function updateMessageText - * @param {Object} params - The update data object. - * @param {Object} req - The request object. - * @param {string} params.messageId - The unique identifier for the message. - * @param {string} params.text - The new text content of the message. - * @returns {Promise} - * @throws {Error} If there is an error in updating the message text. - */ -async function updateMessageText(req, { messageId, text }) { - try { - await Message.updateOne({ messageId, user: req.user.id }, { text }); - } catch (err) { - logger.error('Error updating message text:', err); - throw err; - } -} - -/** - * Updates a message. - * - * @async - * @function updateMessage - * @param {Object} req - The request object. - * @param {Object} message - The message object containing update data. - * @param {string} message.messageId - The unique identifier for the message. - * @param {string} [message.text] - The new text content of the message. - * @param {Object[]} [message.files] - The files associated with the message. - * @param {boolean} [message.isCreatedByUser] - Indicates if the message was created by the user. - * @param {string} [message.sender] - The identifier of the sender. - * @param {number} [message.tokenCount] - The number of tokens in the message. - * @param {Object} [metadata] - The operation metadata - * @param {string} [metadata.context] - The operation metadata - * @returns {Promise} The updated message document. - * @throws {Error} If there is an error in updating the message or if the message is not found. - */ -async function updateMessage(req, message, metadata) { - try { - const { messageId, ...update } = message; - const updatedMessage = await Message.findOneAndUpdate( - { messageId, user: req.user.id }, - update, - { - new: true, - }, - ); - - if (!updatedMessage) { - throw new Error('Message not found or user not authorized.'); - } - - return { - messageId: updatedMessage.messageId, - conversationId: updatedMessage.conversationId, - parentMessageId: updatedMessage.parentMessageId, - sender: updatedMessage.sender, - text: updatedMessage.text, - isCreatedByUser: updatedMessage.isCreatedByUser, - tokenCount: updatedMessage.tokenCount, - feedback: updatedMessage.feedback, - }; - } catch (err) { - logger.error('Error updating message:', err); - if (metadata && metadata?.context) { - logger.info(`---\`updateMessage\` context: ${metadata.context}`); - } - throw err; - } -} - -/** - * Deletes messages in a conversation since a specific message. - * - * @async - * @function deleteMessagesSince - * @param {Object} params - The parameters object. - * @param {Object} req - The request object. - * @param {string} params.messageId - The unique identifier for the message. - * @param {string} params.conversationId - The identifier of the conversation. - * @returns {Promise} The number of deleted messages. - * @throws {Error} If there is an error in deleting messages. - */ -async function deleteMessagesSince(req, { messageId, conversationId }) { - try { - const message = await Message.findOne({ messageId, user: req.user.id }).lean(); - - if (message) { - const query = Message.find({ conversationId, user: req.user.id }); - return await query.deleteMany({ - createdAt: { $gt: message.createdAt }, - }); - } - return undefined; - } catch (err) { - logger.error('Error deleting messages:', err); - throw err; - } -} - -/** - * Retrieves messages from the database. - * @async - * @function getMessages - * @param {Record} filter - The filter criteria. - * @param {string | undefined} [select] - The fields to select. - * @returns {Promise} The messages that match the filter criteria. - * @throws {Error} If there is an error in retrieving messages. - */ -async function getMessages(filter, select) { - try { - if (select) { - return await Message.find(filter).select(select).sort({ createdAt: 1 }).lean(); - } - - return await Message.find(filter).sort({ createdAt: 1 }).lean(); - } catch (err) { - logger.error('Error getting messages:', err); - throw err; - } -} - -/** - * Retrieves a single message from the database. - * @async - * @function getMessage - * @param {{ user: string, messageId: string }} params - The search parameters - * @returns {Promise} The message that matches the criteria or null if not found - * @throws {Error} If there is an error in retrieving the message - */ -async function getMessage({ user, messageId }) { - try { - return await Message.findOne({ - user, - messageId, - }).lean(); - } catch (err) { - logger.error('Error getting message:', err); - throw err; - } -} - -/** - * Deletes messages from the database. - * - * @async - * @function deleteMessages - * @param {import('mongoose').FilterQuery} filter - The filter criteria to find messages to delete. - * @returns {Promise} The metadata with count of deleted messages. - * @throws {Error} If there is an error in deleting messages. - */ -async function deleteMessages(filter) { - try { - return await Message.deleteMany(filter); - } catch (err) { - logger.error('Error deleting messages:', err); - throw err; - } -} - -module.exports = { - saveMessage, - bulkSaveMessages, - recordMessage, - updateMessageText, - updateMessage, - deleteMessagesSince, - getMessages, - getMessage, - deleteMessages, -}; diff --git a/api/models/Preset.js b/api/models/Preset.js deleted file mode 100644 index 4db3d59066..0000000000 --- a/api/models/Preset.js +++ /dev/null @@ -1,82 +0,0 @@ -const { logger } = require('@librechat/data-schemas'); -const { Preset } = require('~/db/models'); - -const getPreset = async (user, presetId) => { - try { - return await Preset.findOne({ user, presetId }).lean(); - } catch (error) { - logger.error('[getPreset] Error getting single preset', error); - return { message: 'Error getting single preset' }; - } -}; - -module.exports = { - getPreset, - getPresets: async (user, filter) => { - try { - const presets = await Preset.find({ ...filter, user }).lean(); - const defaultValue = 10000; - - presets.sort((a, b) => { - let orderA = a.order !== undefined ? a.order : defaultValue; - let orderB = b.order !== undefined ? b.order : defaultValue; - - if (orderA !== orderB) { - return orderA - orderB; - } - - return b.updatedAt - a.updatedAt; - }); - - return presets; - } catch (error) { - logger.error('[getPresets] Error getting presets', error); - return { message: 'Error retrieving presets' }; - } - }, - savePreset: async (user, { presetId, newPresetId, defaultPreset, ...preset }) => { - try { - const setter = { $set: {} }; - const { user: _, ...cleanPreset } = preset; - const update = { presetId, ...cleanPreset }; - if (preset.tools && Array.isArray(preset.tools)) { - update.tools = - preset.tools - .map((tool) => tool?.pluginKey ?? tool) - .filter((toolName) => typeof toolName === 'string') ?? []; - } - if (newPresetId) { - update.presetId = newPresetId; - } - - if (defaultPreset) { - update.defaultPreset = defaultPreset; - update.order = 0; - - const currentDefault = await Preset.findOne({ defaultPreset: true, user }); - - if (currentDefault && currentDefault.presetId !== presetId) { - await Preset.findByIdAndUpdate(currentDefault._id, { - $unset: { defaultPreset: '', order: '' }, - }); - } - } else if (defaultPreset === false) { - update.defaultPreset = undefined; - update.order = undefined; - setter['$unset'] = { defaultPreset: '', order: '' }; - } - - setter.$set = update; - return await Preset.findOneAndUpdate({ presetId, user }, setter, { new: true, upsert: true }); - } catch (error) { - logger.error('[savePreset] Error saving preset', error); - return { message: 'Error saving preset' }; - } - }, - deletePresets: async (user, filter) => { - // let toRemove = await Preset.find({ ...filter, user }).select('presetId'); - // const ids = toRemove.map((instance) => instance.presetId); - let deleteCount = await Preset.deleteMany({ ...filter, user }); - return deleteCount; - }, -}; diff --git a/api/models/Project.js b/api/models/Project.js deleted file mode 100644 index 8fd1e556f9..0000000000 --- a/api/models/Project.js +++ /dev/null @@ -1,133 +0,0 @@ -const { GLOBAL_PROJECT_NAME } = require('librechat-data-provider').Constants; -const { Project } = require('~/db/models'); - -/** - * Retrieve a project by ID and convert the found project document to a plain object. - * - * @param {string} projectId - The ID of the project to find and return as a plain object. - * @param {string|string[]} [fieldsToSelect] - The fields to include or exclude in the returned document. - * @returns {Promise} A plain object representing the project document, or `null` if no project is found. - */ -const getProjectById = async function (projectId, fieldsToSelect = null) { - const query = Project.findById(projectId); - - if (fieldsToSelect) { - query.select(fieldsToSelect); - } - - return await query.lean(); -}; - -/** - * Retrieve a project by name and convert the found project document to a plain object. - * If the project with the given name doesn't exist and the name is "instance", create it and return the lean version. - * - * @param {string} projectName - The name of the project to find or create. - * @param {string|string[]} [fieldsToSelect] - The fields to include or exclude in the returned document. - * @returns {Promise} A plain object representing the project document. - */ -const getProjectByName = async function (projectName, fieldsToSelect = null) { - const query = { name: projectName }; - const update = { $setOnInsert: { name: projectName } }; - const options = { - new: true, - upsert: projectName === GLOBAL_PROJECT_NAME, - lean: true, - select: fieldsToSelect, - }; - - return await Project.findOneAndUpdate(query, update, options); -}; - -/** - * Add an array of prompt group IDs to a project's promptGroupIds array, ensuring uniqueness. - * - * @param {string} projectId - The ID of the project to update. - * @param {string[]} promptGroupIds - The array of prompt group IDs to add to the project. - * @returns {Promise} The updated project document. - */ -const addGroupIdsToProject = async function (projectId, promptGroupIds) { - return await Project.findByIdAndUpdate( - projectId, - { $addToSet: { promptGroupIds: { $each: promptGroupIds } } }, - { new: true }, - ); -}; - -/** - * Remove an array of prompt group IDs from a project's promptGroupIds array. - * - * @param {string} projectId - The ID of the project to update. - * @param {string[]} promptGroupIds - The array of prompt group IDs to remove from the project. - * @returns {Promise} The updated project document. - */ -const removeGroupIdsFromProject = async function (projectId, promptGroupIds) { - return await Project.findByIdAndUpdate( - projectId, - { $pull: { promptGroupIds: { $in: promptGroupIds } } }, - { new: true }, - ); -}; - -/** - * Remove a prompt group ID from all projects. - * - * @param {string} promptGroupId - The ID of the prompt group to remove from projects. - * @returns {Promise} - */ -const removeGroupFromAllProjects = async (promptGroupId) => { - await Project.updateMany({}, { $pull: { promptGroupIds: promptGroupId } }); -}; - -/** - * Add an array of agent IDs to a project's agentIds array, ensuring uniqueness. - * - * @param {string} projectId - The ID of the project to update. - * @param {string[]} agentIds - The array of agent IDs to add to the project. - * @returns {Promise} The updated project document. - */ -const addAgentIdsToProject = async function (projectId, agentIds) { - return await Project.findByIdAndUpdate( - projectId, - { $addToSet: { agentIds: { $each: agentIds } } }, - { new: true }, - ); -}; - -/** - * Remove an array of agent IDs from a project's agentIds array. - * - * @param {string} projectId - The ID of the project to update. - * @param {string[]} agentIds - The array of agent IDs to remove from the project. - * @returns {Promise} The updated project document. - */ -const removeAgentIdsFromProject = async function (projectId, agentIds) { - return await Project.findByIdAndUpdate( - projectId, - { $pull: { agentIds: { $in: agentIds } } }, - { new: true }, - ); -}; - -/** - * Remove an agent ID from all projects. - * - * @param {string} agentId - The ID of the agent to remove from projects. - * @returns {Promise} - */ -const removeAgentFromAllProjects = async (agentId) => { - await Project.updateMany({}, { $pull: { agentIds: agentId } }); -}; - -module.exports = { - getProjectById, - getProjectByName, - /* prompts */ - addGroupIdsToProject, - removeGroupIdsFromProject, - removeGroupFromAllProjects, - /* agents */ - addAgentIdsToProject, - removeAgentIdsFromProject, - removeAgentFromAllProjects, -}; diff --git a/api/models/Prompt.js b/api/models/Prompt.js deleted file mode 100644 index bde911b23a..0000000000 --- a/api/models/Prompt.js +++ /dev/null @@ -1,708 +0,0 @@ -const { ObjectId } = require('mongodb'); -const { escapeRegExp } = require('@librechat/api'); -const { logger } = require('@librechat/data-schemas'); -const { - Constants, - SystemRoles, - ResourceType, - SystemCategories, -} = require('librechat-data-provider'); -const { - removeGroupFromAllProjects, - removeGroupIdsFromProject, - addGroupIdsToProject, - getProjectByName, -} = require('./Project'); -const { removeAllPermissions } = require('~/server/services/PermissionService'); -const { PromptGroup, Prompt, AclEntry } = require('~/db/models'); - -/** - * Create a pipeline for the aggregation to get prompt groups - * @param {Object} query - * @param {number} skip - * @param {number} limit - * @returns {[Object]} - The pipeline for the aggregation - */ -const createGroupPipeline = (query, skip, limit) => { - return [ - { $match: query }, - { $sort: { createdAt: -1 } }, - { $skip: skip }, - { $limit: limit }, - { - $lookup: { - from: 'prompts', - localField: 'productionId', - foreignField: '_id', - as: 'productionPrompt', - }, - }, - { $unwind: { path: '$productionPrompt', preserveNullAndEmptyArrays: true } }, - { - $project: { - name: 1, - numberOfGenerations: 1, - oneliner: 1, - category: 1, - projectIds: 1, - productionId: 1, - author: 1, - authorName: 1, - createdAt: 1, - updatedAt: 1, - 'productionPrompt.prompt': 1, - // 'productionPrompt._id': 1, - // 'productionPrompt.type': 1, - }, - }, - ]; -}; - -/** - * Create a pipeline for the aggregation to get all prompt groups - * @param {Object} query - * @param {Partial} $project - * @returns {[Object]} - The pipeline for the aggregation - */ -const createAllGroupsPipeline = ( - query, - $project = { - name: 1, - oneliner: 1, - category: 1, - author: 1, - authorName: 1, - createdAt: 1, - updatedAt: 1, - command: 1, - 'productionPrompt.prompt': 1, - }, -) => { - return [ - { $match: query }, - { $sort: { createdAt: -1 } }, - { - $lookup: { - from: 'prompts', - localField: 'productionId', - foreignField: '_id', - as: 'productionPrompt', - }, - }, - { $unwind: { path: '$productionPrompt', preserveNullAndEmptyArrays: true } }, - { - $project, - }, - ]; -}; - -/** - * Get all prompt groups with filters - * @param {ServerRequest} req - * @param {TPromptGroupsWithFilterRequest} filter - * @returns {Promise} - */ -const getAllPromptGroups = async (req, filter) => { - try { - const { name, ...query } = filter; - - let searchShared = true; - let searchSharedOnly = false; - if (name) { - query.name = new RegExp(escapeRegExp(name), 'i'); - } - if (!query.category) { - delete query.category; - } else if (query.category === SystemCategories.MY_PROMPTS) { - searchShared = false; - delete query.category; - } else if (query.category === SystemCategories.NO_CATEGORY) { - query.category = ''; - } else if (query.category === SystemCategories.SHARED_PROMPTS) { - searchSharedOnly = true; - delete query.category; - } - - let combinedQuery = query; - - if (searchShared) { - const project = await getProjectByName(Constants.GLOBAL_PROJECT_NAME, 'promptGroupIds'); - if (project && project.promptGroupIds && project.promptGroupIds.length > 0) { - const projectQuery = { _id: { $in: project.promptGroupIds }, ...query }; - delete projectQuery.author; - combinedQuery = searchSharedOnly ? projectQuery : { $or: [projectQuery, query] }; - } - } - - const promptGroupsPipeline = createAllGroupsPipeline(combinedQuery); - return await PromptGroup.aggregate(promptGroupsPipeline).exec(); - } catch (error) { - console.error('Error getting all prompt groups', error); - return { message: 'Error getting all prompt groups' }; - } -}; - -/** - * Get prompt groups with filters - * @param {ServerRequest} req - * @param {TPromptGroupsWithFilterRequest} filter - * @returns {Promise} - */ -const getPromptGroups = async (req, filter) => { - try { - const { pageNumber = 1, pageSize = 10, name, ...query } = filter; - - const validatedPageNumber = Math.max(parseInt(pageNumber, 10), 1); - const validatedPageSize = Math.max(parseInt(pageSize, 10), 1); - - let searchShared = true; - let searchSharedOnly = false; - if (name) { - query.name = new RegExp(escapeRegExp(name), 'i'); - } - if (!query.category) { - delete query.category; - } else if (query.category === SystemCategories.MY_PROMPTS) { - searchShared = false; - delete query.category; - } else if (query.category === SystemCategories.NO_CATEGORY) { - query.category = ''; - } else if (query.category === SystemCategories.SHARED_PROMPTS) { - searchSharedOnly = true; - delete query.category; - } - - let combinedQuery = query; - - if (searchShared) { - // const projects = req.user.projects || []; // TODO: handle multiple projects - const project = await getProjectByName(Constants.GLOBAL_PROJECT_NAME, 'promptGroupIds'); - if (project && project.promptGroupIds && project.promptGroupIds.length > 0) { - const projectQuery = { _id: { $in: project.promptGroupIds }, ...query }; - delete projectQuery.author; - combinedQuery = searchSharedOnly ? projectQuery : { $or: [projectQuery, query] }; - } - } - - const skip = (validatedPageNumber - 1) * validatedPageSize; - const limit = validatedPageSize; - - const promptGroupsPipeline = createGroupPipeline(combinedQuery, skip, limit); - const totalPromptGroupsPipeline = [{ $match: combinedQuery }, { $count: 'total' }]; - - const [promptGroupsResults, totalPromptGroupsResults] = await Promise.all([ - PromptGroup.aggregate(promptGroupsPipeline).exec(), - PromptGroup.aggregate(totalPromptGroupsPipeline).exec(), - ]); - - const promptGroups = promptGroupsResults; - const totalPromptGroups = - totalPromptGroupsResults.length > 0 ? totalPromptGroupsResults[0].total : 0; - - return { - promptGroups, - pageNumber: validatedPageNumber.toString(), - pageSize: validatedPageSize.toString(), - pages: Math.ceil(totalPromptGroups / validatedPageSize).toString(), - }; - } catch (error) { - console.error('Error getting prompt groups', error); - return { message: 'Error getting prompt groups' }; - } -}; - -/** - * @param {Object} fields - * @param {string} fields._id - * @param {string} fields.author - * @param {string} fields.role - * @returns {Promise} - */ -const deletePromptGroup = async ({ _id, author, role }) => { - // Build query - with ACL, author is optional - const query = { _id }; - const groupQuery = { groupId: new ObjectId(_id) }; - - // Legacy: Add author filter if provided (backward compatibility) - if (author && role !== SystemRoles.ADMIN) { - query.author = author; - groupQuery.author = author; - } - - const response = await PromptGroup.deleteOne(query); - - if (!response || response.deletedCount === 0) { - throw new Error('Prompt group not found'); - } - - await Prompt.deleteMany(groupQuery); - await removeGroupFromAllProjects(_id); - - try { - await removeAllPermissions({ resourceType: ResourceType.PROMPTGROUP, resourceId: _id }); - } catch (error) { - logger.error('Error removing promptGroup permissions:', error); - } - - return { message: 'Prompt group deleted successfully' }; -}; - -/** - * Get prompt groups by accessible IDs with optional cursor-based pagination. - * @param {Object} params - The parameters for getting accessible prompt groups. - * @param {Array} [params.accessibleIds] - Array of prompt group ObjectIds the user has ACL access to. - * @param {Object} [params.otherParams] - Additional query parameters (including author filter). - * @param {number} [params.limit] - Number of prompt groups to return (max 100). If not provided, returns all prompt groups. - * @param {string} [params.after] - Cursor for pagination - get prompt groups after this cursor. // base64 encoded JSON string with updatedAt and _id. - * @returns {Promise} A promise that resolves to an object containing the prompt groups data and pagination info. - */ -async function getListPromptGroupsByAccess({ - accessibleIds = [], - otherParams = {}, - limit = null, - after = null, -}) { - const isPaginated = limit !== null && limit !== undefined; - const normalizedLimit = isPaginated ? Math.min(Math.max(1, parseInt(limit) || 20), 100) : null; - - // Build base query combining ACL accessible prompt groups with other filters - const baseQuery = { ...otherParams, _id: { $in: accessibleIds } }; - - // Add cursor condition - if (after && typeof after === 'string' && after !== 'undefined' && after !== 'null') { - try { - const cursor = JSON.parse(Buffer.from(after, 'base64').toString('utf8')); - const { updatedAt, _id } = cursor; - - const cursorCondition = { - $or: [ - { updatedAt: { $lt: new Date(updatedAt) } }, - { updatedAt: new Date(updatedAt), _id: { $gt: new ObjectId(_id) } }, - ], - }; - - // Merge cursor condition with base query - if (Object.keys(baseQuery).length > 0) { - baseQuery.$and = [{ ...baseQuery }, cursorCondition]; - // Remove the original conditions from baseQuery to avoid duplication - Object.keys(baseQuery).forEach((key) => { - if (key !== '$and') delete baseQuery[key]; - }); - } else { - Object.assign(baseQuery, cursorCondition); - } - } catch (error) { - logger.warn('Invalid cursor:', error.message); - } - } - - // Build aggregation pipeline - const pipeline = [{ $match: baseQuery }, { $sort: { updatedAt: -1, _id: 1 } }]; - - // Only apply limit if pagination is requested - if (isPaginated) { - pipeline.push({ $limit: normalizedLimit + 1 }); - } - - // Add lookup for production prompt - pipeline.push( - { - $lookup: { - from: 'prompts', - localField: 'productionId', - foreignField: '_id', - as: 'productionPrompt', - }, - }, - { $unwind: { path: '$productionPrompt', preserveNullAndEmptyArrays: true } }, - { - $project: { - name: 1, - numberOfGenerations: 1, - oneliner: 1, - category: 1, - projectIds: 1, - productionId: 1, - author: 1, - authorName: 1, - createdAt: 1, - updatedAt: 1, - 'productionPrompt.prompt': 1, - }, - }, - ); - - const promptGroups = await PromptGroup.aggregate(pipeline).exec(); - - const hasMore = isPaginated ? promptGroups.length > normalizedLimit : false; - const data = (isPaginated ? promptGroups.slice(0, normalizedLimit) : promptGroups).map( - (group) => { - if (group.author) { - group.author = group.author.toString(); - } - return group; - }, - ); - - // Generate next cursor only if paginated - let nextCursor = null; - if (isPaginated && hasMore && data.length > 0) { - const lastGroup = promptGroups[normalizedLimit - 1]; - nextCursor = Buffer.from( - JSON.stringify({ - updatedAt: lastGroup.updatedAt.toISOString(), - _id: lastGroup._id.toString(), - }), - ).toString('base64'); - } - - return { - object: 'list', - data, - first_id: data.length > 0 ? data[0]._id.toString() : null, - last_id: data.length > 0 ? data[data.length - 1]._id.toString() : null, - has_more: hasMore, - after: nextCursor, - }; -} - -module.exports = { - getPromptGroups, - deletePromptGroup, - getAllPromptGroups, - getListPromptGroupsByAccess, - /** - * Create a prompt and its respective group - * @param {TCreatePromptRecord} saveData - * @returns {Promise} - */ - createPromptGroup: async (saveData) => { - try { - const { prompt, group, author, authorName } = saveData; - - let newPromptGroup = await PromptGroup.findOneAndUpdate( - { ...group, author, authorName, productionId: null }, - { $setOnInsert: { ...group, author, authorName, productionId: null } }, - { new: true, upsert: true }, - ) - .lean() - .select('-__v') - .exec(); - - const newPrompt = await Prompt.findOneAndUpdate( - { ...prompt, author, groupId: newPromptGroup._id }, - { $setOnInsert: { ...prompt, author, groupId: newPromptGroup._id } }, - { new: true, upsert: true }, - ) - .lean() - .select('-__v') - .exec(); - - newPromptGroup = await PromptGroup.findByIdAndUpdate( - newPromptGroup._id, - { productionId: newPrompt._id }, - { new: true }, - ) - .lean() - .select('-__v') - .exec(); - - return { - prompt: newPrompt, - group: { - ...newPromptGroup, - productionPrompt: { prompt: newPrompt.prompt }, - }, - }; - } catch (error) { - logger.error('Error saving prompt group', error); - throw new Error('Error saving prompt group'); - } - }, - /** - * Save a prompt - * @param {TCreatePromptRecord} saveData - * @returns {Promise} - */ - savePrompt: async (saveData) => { - try { - const { prompt, author } = saveData; - const newPromptData = { - ...prompt, - author, - }; - - /** @type {TPrompt} */ - let newPrompt; - try { - newPrompt = await Prompt.create(newPromptData); - } catch (error) { - if (error?.message?.includes('groupId_1_version_1')) { - await Prompt.db.collection('prompts').dropIndex('groupId_1_version_1'); - } else { - throw error; - } - newPrompt = await Prompt.create(newPromptData); - } - - return { prompt: newPrompt }; - } catch (error) { - logger.error('Error saving prompt', error); - return { message: 'Error saving prompt' }; - } - }, - getPrompts: async (filter) => { - try { - return await Prompt.find(filter).sort({ createdAt: -1 }).lean(); - } catch (error) { - logger.error('Error getting prompts', error); - return { message: 'Error getting prompts' }; - } - }, - getPrompt: async (filter) => { - try { - if (filter.groupId) { - filter.groupId = new ObjectId(filter.groupId); - } - return await Prompt.findOne(filter).lean(); - } catch (error) { - logger.error('Error getting prompt', error); - return { message: 'Error getting prompt' }; - } - }, - /** - * Get prompt groups with filters - * @param {TGetRandomPromptsRequest} filter - * @returns {Promise} - */ - getRandomPromptGroups: async (filter) => { - try { - const result = await PromptGroup.aggregate([ - { - $match: { - category: { $ne: '' }, - }, - }, - { - $group: { - _id: '$category', - promptGroup: { $first: '$$ROOT' }, - }, - }, - { - $replaceRoot: { newRoot: '$promptGroup' }, - }, - { - $sample: { size: +filter.limit + +filter.skip }, - }, - { - $skip: +filter.skip, - }, - { - $limit: +filter.limit, - }, - ]); - return { prompts: result }; - } catch (error) { - logger.error('Error getting prompt groups', error); - return { message: 'Error getting prompt groups' }; - } - }, - getPromptGroupsWithPrompts: async (filter) => { - try { - return await PromptGroup.findOne(filter) - .populate({ - path: 'prompts', - select: '-_id -__v -user', - }) - .select('-_id -__v -user') - .lean(); - } catch (error) { - logger.error('Error getting prompt groups', error); - return { message: 'Error getting prompt groups' }; - } - }, - getPromptGroup: async (filter) => { - try { - return await PromptGroup.findOne(filter).lean(); - } catch (error) { - logger.error('Error getting prompt group', error); - return { message: 'Error getting prompt group' }; - } - }, - /** - * Deletes a prompt and its corresponding prompt group if it is the last prompt in the group. - * - * @param {Object} options - The options for deleting the prompt. - * @param {ObjectId|string} options.promptId - The ID of the prompt to delete. - * @param {ObjectId|string} options.groupId - The ID of the prompt's group. - * @param {ObjectId|string} options.author - The ID of the prompt's author. - * @param {string} options.role - The role of the prompt's author. - * @return {Promise} An object containing the result of the deletion. - * If the prompt was deleted successfully, the object will have a property 'prompt' with the value 'Prompt deleted successfully'. - * If the prompt group was deleted successfully, the object will have a property 'promptGroup' with the message 'Prompt group deleted successfully' and id of the deleted group. - * If there was an error deleting the prompt, the object will have a property 'message' with the value 'Error deleting prompt'. - */ - deletePrompt: async ({ promptId, groupId, author, role }) => { - const query = { _id: promptId, groupId, author }; - if (role === SystemRoles.ADMIN) { - delete query.author; - } - const { deletedCount } = await Prompt.deleteOne(query); - if (deletedCount === 0) { - throw new Error('Failed to delete the prompt'); - } - - const remainingPrompts = await Prompt.find({ groupId }) - .select('_id') - .sort({ createdAt: 1 }) - .lean(); - - if (remainingPrompts.length === 0) { - // Remove all ACL entries for the promptGroup when deleting the last prompt - try { - await removeAllPermissions({ - resourceType: ResourceType.PROMPTGROUP, - resourceId: groupId, - }); - } catch (error) { - logger.error('Error removing promptGroup permissions:', error); - } - - await PromptGroup.deleteOne({ _id: groupId }); - await removeGroupFromAllProjects(groupId); - - return { - prompt: 'Prompt deleted successfully', - promptGroup: { - message: 'Prompt group deleted successfully', - id: groupId, - }, - }; - } else { - const promptGroup = await PromptGroup.findById(groupId).lean(); - if (promptGroup.productionId.toString() === promptId.toString()) { - await PromptGroup.updateOne( - { _id: groupId }, - { productionId: remainingPrompts[remainingPrompts.length - 1]._id }, - ); - } - - return { prompt: 'Prompt deleted successfully' }; - } - }, - /** - * Delete all prompts and prompt groups created by a specific user. - * @param {ServerRequest} req - The server request object. - * @param {string} userId - The ID of the user whose prompts and prompt groups are to be deleted. - */ - deleteUserPrompts: async (req, userId) => { - try { - const promptGroups = await getAllPromptGroups(req, { author: new ObjectId(userId) }); - - if (promptGroups.length === 0) { - return; - } - - const groupIds = promptGroups.map((group) => group._id); - - for (const groupId of groupIds) { - await removeGroupFromAllProjects(groupId); - } - - await AclEntry.deleteMany({ - resourceType: ResourceType.PROMPTGROUP, - resourceId: { $in: groupIds }, - }); - - await PromptGroup.deleteMany({ author: new ObjectId(userId) }); - await Prompt.deleteMany({ author: new ObjectId(userId) }); - } catch (error) { - logger.error('[deleteUserPrompts] General error:', error); - } - }, - /** - * Update prompt group - * @param {Partial} filter - Filter to find prompt group - * @param {Partial} data - Data to update - * @returns {Promise} - */ - updatePromptGroup: async (filter, data) => { - try { - const updateOps = {}; - if (data.removeProjectIds) { - for (const projectId of data.removeProjectIds) { - await removeGroupIdsFromProject(projectId, [filter._id]); - } - - updateOps.$pull = { projectIds: { $in: data.removeProjectIds } }; - delete data.removeProjectIds; - } - - if (data.projectIds) { - for (const projectId of data.projectIds) { - await addGroupIdsToProject(projectId, [filter._id]); - } - - updateOps.$addToSet = { projectIds: { $each: data.projectIds } }; - delete data.projectIds; - } - - const updateData = { ...data, ...updateOps }; - const updatedDoc = await PromptGroup.findOneAndUpdate(filter, updateData, { - new: true, - upsert: false, - }); - - if (!updatedDoc) { - throw new Error('Prompt group not found'); - } - - return updatedDoc; - } catch (error) { - logger.error('Error updating prompt group', error); - return { message: 'Error updating prompt group' }; - } - }, - /** - * Function to make a prompt production based on its ID. - * @param {String} promptId - The ID of the prompt to make production. - * @returns {Object} The result of the production operation. - */ - makePromptProduction: async (promptId) => { - try { - const prompt = await Prompt.findById(promptId).lean(); - - if (!prompt) { - throw new Error('Prompt not found'); - } - - await PromptGroup.findByIdAndUpdate( - prompt.groupId, - { productionId: prompt._id }, - { new: true }, - ) - .lean() - .exec(); - - return { - message: 'Prompt production made successfully', - }; - } catch (error) { - logger.error('Error making prompt production', error); - return { message: 'Error making prompt production' }; - } - }, - updatePromptLabels: async (_id, labels) => { - try { - const response = await Prompt.updateOne({ _id }, { $set: { labels } }); - if (response.matchedCount === 0) { - return { message: 'Prompt not found' }; - } - return { message: 'Prompt labels updated successfully' }; - } catch (error) { - logger.error('Error updating prompt labels', error); - return { message: 'Error updating prompt labels' }; - } - }, -}; diff --git a/api/models/Prompt.spec.js b/api/models/Prompt.spec.js deleted file mode 100644 index e00a1a518c..0000000000 --- a/api/models/Prompt.spec.js +++ /dev/null @@ -1,564 +0,0 @@ -const mongoose = require('mongoose'); -const { ObjectId } = require('mongodb'); -const { logger } = require('@librechat/data-schemas'); -const { MongoMemoryServer } = require('mongodb-memory-server'); -const { - SystemRoles, - ResourceType, - AccessRoleIds, - PrincipalType, - PermissionBits, -} = require('librechat-data-provider'); - -// Mock the config/connect module to prevent connection attempts during tests -jest.mock('../../config/connect', () => jest.fn().mockResolvedValue(true)); - -const dbModels = require('~/db/models'); - -// Disable console for tests -logger.silent = true; - -let mongoServer; -let Prompt, PromptGroup, AclEntry, AccessRole, User, Group, Project; -let promptFns, permissionService; -let testUsers, testGroups, testRoles; - -beforeAll(async () => { - // Set up MongoDB memory server - mongoServer = await MongoMemoryServer.create(); - const mongoUri = mongoServer.getUri(); - await mongoose.connect(mongoUri); - - // Initialize models - Prompt = dbModels.Prompt; - PromptGroup = dbModels.PromptGroup; - AclEntry = dbModels.AclEntry; - AccessRole = dbModels.AccessRole; - User = dbModels.User; - Group = dbModels.Group; - Project = dbModels.Project; - - promptFns = require('~/models/Prompt'); - permissionService = require('~/server/services/PermissionService'); - - // Create test data - await setupTestData(); -}); - -afterAll(async () => { - await mongoose.disconnect(); - await mongoServer.stop(); - jest.clearAllMocks(); -}); - -async function setupTestData() { - // Create access roles for promptGroups - testRoles = { - viewer: await AccessRole.create({ - accessRoleId: AccessRoleIds.PROMPTGROUP_VIEWER, - name: 'Viewer', - description: 'Can view promptGroups', - resourceType: ResourceType.PROMPTGROUP, - permBits: PermissionBits.VIEW, - }), - editor: await AccessRole.create({ - accessRoleId: AccessRoleIds.PROMPTGROUP_EDITOR, - name: 'Editor', - description: 'Can view and edit promptGroups', - resourceType: ResourceType.PROMPTGROUP, - permBits: PermissionBits.VIEW | PermissionBits.EDIT, - }), - owner: await AccessRole.create({ - accessRoleId: AccessRoleIds.PROMPTGROUP_OWNER, - name: 'Owner', - description: 'Full control over promptGroups', - resourceType: ResourceType.PROMPTGROUP, - permBits: - PermissionBits.VIEW | PermissionBits.EDIT | PermissionBits.DELETE | PermissionBits.SHARE, - }), - }; - - // Create test users - testUsers = { - owner: await User.create({ - name: 'Prompt Owner', - email: 'owner@example.com', - role: SystemRoles.USER, - }), - editor: await User.create({ - name: 'Prompt Editor', - email: 'editor@example.com', - role: SystemRoles.USER, - }), - viewer: await User.create({ - name: 'Prompt Viewer', - email: 'viewer@example.com', - role: SystemRoles.USER, - }), - admin: await User.create({ - name: 'Admin User', - email: 'admin@example.com', - role: SystemRoles.ADMIN, - }), - noAccess: await User.create({ - name: 'No Access User', - email: 'noaccess@example.com', - role: SystemRoles.USER, - }), - }; - - // Create test groups - testGroups = { - editors: await Group.create({ - name: 'Prompt Editors', - description: 'Group with editor access', - }), - viewers: await Group.create({ - name: 'Prompt Viewers', - description: 'Group with viewer access', - }), - }; - - await Project.create({ - name: 'Global', - description: 'Global project', - promptGroupIds: [], - }); -} - -describe('Prompt ACL Permissions', () => { - describe('Creating Prompts with Permissions', () => { - it('should grant owner permissions when creating a prompt', async () => { - // First create a group - const testGroup = await PromptGroup.create({ - name: 'Test Group', - category: 'testing', - author: testUsers.owner._id, - authorName: testUsers.owner.name, - productionId: new mongoose.Types.ObjectId(), - }); - - const promptData = { - prompt: { - prompt: 'Test prompt content', - name: 'Test Prompt', - type: 'text', - groupId: testGroup._id, - }, - author: testUsers.owner._id, - }; - - await promptFns.savePrompt(promptData); - - // Manually grant permissions as would happen in the route - await permissionService.grantPermission({ - principalType: PrincipalType.USER, - principalId: testUsers.owner._id, - resourceType: ResourceType.PROMPTGROUP, - resourceId: testGroup._id, - accessRoleId: AccessRoleIds.PROMPTGROUP_OWNER, - grantedBy: testUsers.owner._id, - }); - - // Check ACL entry - const aclEntry = await AclEntry.findOne({ - resourceType: ResourceType.PROMPTGROUP, - resourceId: testGroup._id, - principalType: PrincipalType.USER, - principalId: testUsers.owner._id, - }); - - expect(aclEntry).toBeTruthy(); - expect(aclEntry.permBits).toBe(testRoles.owner.permBits); - }); - }); - - describe('Accessing Prompts', () => { - let testPromptGroup; - - beforeEach(async () => { - // Create a prompt group - testPromptGroup = await PromptGroup.create({ - name: 'Test Group', - author: testUsers.owner._id, - authorName: testUsers.owner.name, - productionId: new ObjectId(), - }); - - // Create a prompt - await Prompt.create({ - prompt: 'Test prompt for access control', - name: 'Access Test Prompt', - author: testUsers.owner._id, - groupId: testPromptGroup._id, - type: 'text', - }); - - // Grant owner permissions - await permissionService.grantPermission({ - principalType: PrincipalType.USER, - principalId: testUsers.owner._id, - resourceType: ResourceType.PROMPTGROUP, - resourceId: testPromptGroup._id, - accessRoleId: AccessRoleIds.PROMPTGROUP_OWNER, - grantedBy: testUsers.owner._id, - }); - }); - - afterEach(async () => { - await Prompt.deleteMany({}); - await PromptGroup.deleteMany({}); - await AclEntry.deleteMany({}); - }); - - it('owner should have full access to their prompt', async () => { - const hasAccess = await permissionService.checkPermission({ - userId: testUsers.owner._id, - resourceType: ResourceType.PROMPTGROUP, - resourceId: testPromptGroup._id, - requiredPermission: PermissionBits.VIEW, - }); - - expect(hasAccess).toBe(true); - - const canEdit = await permissionService.checkPermission({ - userId: testUsers.owner._id, - resourceType: ResourceType.PROMPTGROUP, - resourceId: testPromptGroup._id, - requiredPermission: PermissionBits.EDIT, - }); - - expect(canEdit).toBe(true); - }); - - it('user with viewer role should only have view access', async () => { - // Grant viewer permissions - await permissionService.grantPermission({ - principalType: PrincipalType.USER, - principalId: testUsers.viewer._id, - resourceType: ResourceType.PROMPTGROUP, - resourceId: testPromptGroup._id, - accessRoleId: AccessRoleIds.PROMPTGROUP_VIEWER, - grantedBy: testUsers.owner._id, - }); - - const canView = await permissionService.checkPermission({ - userId: testUsers.viewer._id, - resourceType: ResourceType.PROMPTGROUP, - resourceId: testPromptGroup._id, - requiredPermission: PermissionBits.VIEW, - }); - - const canEdit = await permissionService.checkPermission({ - userId: testUsers.viewer._id, - resourceType: ResourceType.PROMPTGROUP, - resourceId: testPromptGroup._id, - requiredPermission: PermissionBits.EDIT, - }); - - expect(canView).toBe(true); - expect(canEdit).toBe(false); - }); - - it('user without permissions should have no access', async () => { - const hasAccess = await permissionService.checkPermission({ - userId: testUsers.noAccess._id, - resourceType: ResourceType.PROMPTGROUP, - resourceId: testPromptGroup._id, - requiredPermission: PermissionBits.VIEW, - }); - - expect(hasAccess).toBe(false); - }); - - it('admin should have access regardless of permissions', async () => { - // Admin users should work through normal permission system - // The middleware layer handles admin bypass, not the permission service - const hasAccess = await permissionService.checkPermission({ - userId: testUsers.admin._id, - resourceType: ResourceType.PROMPTGROUP, - resourceId: testPromptGroup._id, - requiredPermission: PermissionBits.VIEW, - }); - - // Without explicit permissions, even admin won't have access at this layer - expect(hasAccess).toBe(false); - - // The actual admin bypass happens in the middleware layer (`canAccessPromptViaGroup`/`canAccessPromptGroupResource`) - // which checks req.user.role === SystemRoles.ADMIN - }); - }); - - describe('Group-based Access', () => { - let testPromptGroup; - - beforeEach(async () => { - // Create a prompt group first - testPromptGroup = await PromptGroup.create({ - name: 'Group Access Test Group', - author: testUsers.owner._id, - authorName: testUsers.owner.name, - productionId: new ObjectId(), - }); - - await Prompt.create({ - prompt: 'Group access test prompt', - name: 'Group Test', - author: testUsers.owner._id, - groupId: testPromptGroup._id, - type: 'text', - }); - - // Add users to groups - await User.findByIdAndUpdate(testUsers.editor._id, { - $push: { groups: testGroups.editors._id }, - }); - - await User.findByIdAndUpdate(testUsers.viewer._id, { - $push: { groups: testGroups.viewers._id }, - }); - }); - - afterEach(async () => { - await Prompt.deleteMany({}); - await AclEntry.deleteMany({}); - await User.updateMany({}, { $set: { groups: [] } }); - }); - - it('group members should inherit group permissions', async () => { - // Create a prompt group - const testPromptGroup = await PromptGroup.create({ - name: 'Group Test Group', - author: testUsers.owner._id, - authorName: testUsers.owner.name, - productionId: new ObjectId(), - }); - - const { addUserToGroup } = require('~/models'); - await addUserToGroup(testUsers.editor._id, testGroups.editors._id); - - const prompt = await promptFns.savePrompt({ - author: testUsers.owner._id, - prompt: { - prompt: 'Group test prompt', - name: 'Group Test', - groupId: testPromptGroup._id, - type: 'text', - }, - }); - - // Check if savePrompt returned an error - if (!prompt || !prompt.prompt) { - throw new Error(`Failed to save prompt: ${prompt?.message || 'Unknown error'}`); - } - - // Grant edit permissions to the group - await permissionService.grantPermission({ - principalType: PrincipalType.GROUP, - principalId: testGroups.editors._id, - resourceType: ResourceType.PROMPTGROUP, - resourceId: testPromptGroup._id, - accessRoleId: AccessRoleIds.PROMPTGROUP_EDITOR, - grantedBy: testUsers.owner._id, - }); - - // Check if group member has access - const hasAccess = await permissionService.checkPermission({ - userId: testUsers.editor._id, - resourceType: ResourceType.PROMPTGROUP, - resourceId: testPromptGroup._id, - requiredPermission: PermissionBits.EDIT, - }); - - expect(hasAccess).toBe(true); - - // Check that non-member doesn't have access - const nonMemberAccess = await permissionService.checkPermission({ - userId: testUsers.viewer._id, - resourceType: ResourceType.PROMPTGROUP, - resourceId: testPromptGroup._id, - requiredPermission: PermissionBits.EDIT, - }); - - expect(nonMemberAccess).toBe(false); - }); - }); - - describe('Public Access', () => { - let publicPromptGroup, privatePromptGroup; - - beforeEach(async () => { - // Create separate prompt groups for public and private access - publicPromptGroup = await PromptGroup.create({ - name: 'Public Access Test Group', - author: testUsers.owner._id, - authorName: testUsers.owner.name, - productionId: new ObjectId(), - }); - - privatePromptGroup = await PromptGroup.create({ - name: 'Private Access Test Group', - author: testUsers.owner._id, - authorName: testUsers.owner.name, - productionId: new ObjectId(), - }); - - // Create prompts in their respective groups - await Prompt.create({ - prompt: 'Public prompt', - name: 'Public', - author: testUsers.owner._id, - groupId: publicPromptGroup._id, - type: 'text', - }); - - await Prompt.create({ - prompt: 'Private prompt', - name: 'Private', - author: testUsers.owner._id, - groupId: privatePromptGroup._id, - type: 'text', - }); - - // Grant public view access to publicPromptGroup - await permissionService.grantPermission({ - principalType: PrincipalType.PUBLIC, - principalId: null, - resourceType: ResourceType.PROMPTGROUP, - resourceId: publicPromptGroup._id, - accessRoleId: AccessRoleIds.PROMPTGROUP_VIEWER, - grantedBy: testUsers.owner._id, - }); - - // Grant only owner access to privatePromptGroup - await permissionService.grantPermission({ - principalType: PrincipalType.USER, - principalId: testUsers.owner._id, - resourceType: ResourceType.PROMPTGROUP, - resourceId: privatePromptGroup._id, - accessRoleId: AccessRoleIds.PROMPTGROUP_OWNER, - grantedBy: testUsers.owner._id, - }); - }); - - afterEach(async () => { - await Prompt.deleteMany({}); - await PromptGroup.deleteMany({}); - await AclEntry.deleteMany({}); - }); - - it('public prompt should be accessible to any user', async () => { - const hasAccess = await permissionService.checkPermission({ - userId: testUsers.noAccess._id, - resourceType: ResourceType.PROMPTGROUP, - resourceId: publicPromptGroup._id, - requiredPermission: PermissionBits.VIEW, - includePublic: true, - }); - - expect(hasAccess).toBe(true); - }); - - it('private prompt should not be accessible to unauthorized users', async () => { - const hasAccess = await permissionService.checkPermission({ - userId: testUsers.noAccess._id, - resourceType: ResourceType.PROMPTGROUP, - resourceId: privatePromptGroup._id, - requiredPermission: PermissionBits.VIEW, - includePublic: true, - }); - - expect(hasAccess).toBe(false); - }); - }); - - describe('Prompt Deletion', () => { - let testPromptGroup; - - it('should remove ACL entries when prompt is deleted', async () => { - testPromptGroup = await PromptGroup.create({ - name: 'Deletion Test Group', - author: testUsers.owner._id, - authorName: testUsers.owner.name, - productionId: new ObjectId(), - }); - - const prompt = await promptFns.savePrompt({ - author: testUsers.owner._id, - prompt: { - prompt: 'To be deleted', - name: 'Delete Test', - groupId: testPromptGroup._id, - type: 'text', - }, - }); - - // Check if savePrompt returned an error - if (!prompt || !prompt.prompt) { - throw new Error(`Failed to save prompt: ${prompt?.message || 'Unknown error'}`); - } - - const testPromptId = prompt.prompt._id; - const promptGroupId = testPromptGroup._id; - - // Grant permission - await permissionService.grantPermission({ - principalType: PrincipalType.USER, - principalId: testUsers.owner._id, - resourceType: ResourceType.PROMPTGROUP, - resourceId: testPromptGroup._id, - accessRoleId: AccessRoleIds.PROMPTGROUP_OWNER, - grantedBy: testUsers.owner._id, - }); - - // Verify ACL entry exists - const beforeDelete = await AclEntry.find({ - resourceType: ResourceType.PROMPTGROUP, - resourceId: testPromptGroup._id, - }); - expect(beforeDelete).toHaveLength(1); - - // Delete the prompt - await promptFns.deletePrompt({ - promptId: testPromptId, - groupId: promptGroupId, - author: testUsers.owner._id, - role: SystemRoles.USER, - }); - - // Verify ACL entries are removed - const aclEntries = await AclEntry.find({ - resourceType: ResourceType.PROMPTGROUP, - resourceId: testPromptGroup._id, - }); - - expect(aclEntries).toHaveLength(0); - }); - }); - - describe('Backwards Compatibility', () => { - it('should handle prompts without ACL entries gracefully', async () => { - // Create a prompt group first - const promptGroup = await PromptGroup.create({ - name: 'Legacy Test Group', - author: testUsers.owner._id, - authorName: testUsers.owner.name, - productionId: new ObjectId(), - }); - - // Create a prompt without ACL entries (legacy prompt) - const legacyPrompt = await Prompt.create({ - prompt: 'Legacy prompt without ACL', - name: 'Legacy', - author: testUsers.owner._id, - groupId: promptGroup._id, - type: 'text', - }); - - // The system should handle this gracefully - const prompt = await promptFns.getPrompt({ _id: legacyPrompt._id }); - expect(prompt).toBeTruthy(); - expect(prompt._id.toString()).toBe(legacyPrompt._id.toString()); - }); - }); -}); diff --git a/api/models/Role.js b/api/models/Role.js deleted file mode 100644 index b7f806f3b6..0000000000 --- a/api/models/Role.js +++ /dev/null @@ -1,304 +0,0 @@ -const { - CacheKeys, - SystemRoles, - roleDefaults, - permissionsSchema, - removeNullishValues, -} = require('librechat-data-provider'); -const { logger } = require('@librechat/data-schemas'); -const getLogStores = require('~/cache/getLogStores'); -const { Role } = require('~/db/models'); - -/** - * Retrieve a role by name and convert the found role document to a plain object. - * If the role with the given name doesn't exist and the name is a system defined role, - * create it and return the lean version. - * - * @param {string} roleName - The name of the role to find or create. - * @param {string|string[]} [fieldsToSelect] - The fields to include or exclude in the returned document. - * @returns {Promise} Role document. - */ -const getRoleByName = async function (roleName, fieldsToSelect = null) { - const cache = getLogStores(CacheKeys.ROLES); - try { - const cachedRole = await cache.get(roleName); - if (cachedRole) { - return cachedRole; - } - let query = Role.findOne({ name: roleName }); - if (fieldsToSelect) { - query = query.select(fieldsToSelect); - } - let role = await query.lean().exec(); - - if (!role && SystemRoles[roleName]) { - role = await new Role(roleDefaults[roleName]).save(); - await cache.set(roleName, role); - return role.toObject(); - } - await cache.set(roleName, role); - return role; - } catch (error) { - throw new Error(`Failed to retrieve or create role: ${error.message}`); - } -}; - -/** - * Update role values by name. - * - * @param {string} roleName - The name of the role to update. - * @param {Partial} updates - The fields to update. - * @returns {Promise} Updated role document. - */ -const updateRoleByName = async function (roleName, updates) { - const cache = getLogStores(CacheKeys.ROLES); - try { - const role = await Role.findOneAndUpdate( - { name: roleName }, - { $set: updates }, - { new: true, lean: true }, - ) - .select('-__v') - .lean() - .exec(); - await cache.set(roleName, role); - return role; - } catch (error) { - throw new Error(`Failed to update role: ${error.message}`); - } -}; - -/** - * Updates access permissions for a specific role and multiple permission types. - * @param {string} roleName - The role to update. - * @param {Object.>} permissionsUpdate - Permissions to update and their values. - * @param {IRole} [roleData] - Optional role data to use instead of fetching from the database. - */ -async function updateAccessPermissions(roleName, permissionsUpdate, roleData) { - // Filter and clean the permission updates based on our schema definition. - const updates = {}; - for (const [permissionType, permissions] of Object.entries(permissionsUpdate)) { - if (permissionsSchema.shape && permissionsSchema.shape[permissionType]) { - updates[permissionType] = removeNullishValues(permissions); - } - } - if (!Object.keys(updates).length) { - return; - } - - try { - const role = roleData ?? (await getRoleByName(roleName)); - if (!role) { - return; - } - - const currentPermissions = role.permissions || {}; - const updatedPermissions = { ...currentPermissions }; - let hasChanges = false; - - const unsetFields = {}; - const permissionTypes = Object.keys(permissionsSchema.shape || {}); - for (const permType of permissionTypes) { - if (role[permType] && typeof role[permType] === 'object') { - logger.info( - `Migrating '${roleName}' role from old schema: found '${permType}' at top level`, - ); - - updatedPermissions[permType] = { - ...updatedPermissions[permType], - ...role[permType], - }; - - unsetFields[permType] = 1; - hasChanges = true; - } - } - - // Migrate legacy SHARED_GLOBAL → SHARE for PROMPTS and AGENTS. - // SHARED_GLOBAL was removed in favour of SHARE in PR #11283. If the DB still has - // SHARED_GLOBAL but not SHARE, inherit the value so sharing intent is preserved. - const legacySharedGlobalTypes = ['PROMPTS', 'AGENTS']; - for (const legacyPermType of legacySharedGlobalTypes) { - const existingTypePerms = currentPermissions[legacyPermType]; - if ( - existingTypePerms && - 'SHARED_GLOBAL' in existingTypePerms && - !('SHARE' in existingTypePerms) && - updates[legacyPermType] && - // Don't override an explicit SHARE value the caller already provided - !('SHARE' in updates[legacyPermType]) - ) { - const inheritedValue = existingTypePerms['SHARED_GLOBAL']; - updates[legacyPermType]['SHARE'] = inheritedValue; - logger.info( - `Migrating '${roleName}' role ${legacyPermType}.SHARED_GLOBAL=${inheritedValue} → SHARE`, - ); - } - } - - for (const [permissionType, permissions] of Object.entries(updates)) { - const currentTypePermissions = currentPermissions[permissionType] || {}; - updatedPermissions[permissionType] = { ...currentTypePermissions }; - - for (const [permission, value] of Object.entries(permissions)) { - if (currentTypePermissions[permission] !== value) { - updatedPermissions[permissionType][permission] = value; - hasChanges = true; - logger.info( - `Updating '${roleName}' role permission '${permissionType}' '${permission}' from ${currentTypePermissions[permission]} to: ${value}`, - ); - } - } - } - - // Clean up orphaned SHARED_GLOBAL fields left in DB after the schema rename. - // Since we $set the full permissions object, deleting from updatedPermissions - // is sufficient to remove the field from MongoDB. - for (const legacyPermType of legacySharedGlobalTypes) { - const existingTypePerms = currentPermissions[legacyPermType]; - if (existingTypePerms && 'SHARED_GLOBAL' in existingTypePerms) { - if (!updates[legacyPermType]) { - // permType wasn't in the update payload so the migration block above didn't run. - // Create a writable copy and handle the SHARED_GLOBAL → SHARE inheritance here - // to avoid removing SHARED_GLOBAL without writing SHARE (data loss). - updatedPermissions[legacyPermType] = { ...existingTypePerms }; - if (!('SHARE' in existingTypePerms)) { - updatedPermissions[legacyPermType]['SHARE'] = existingTypePerms['SHARED_GLOBAL']; - logger.info( - `Migrating '${roleName}' role ${legacyPermType}.SHARED_GLOBAL=${existingTypePerms['SHARED_GLOBAL']} → SHARE`, - ); - } - } - delete updatedPermissions[legacyPermType]['SHARED_GLOBAL']; - hasChanges = true; - logger.info( - `Removed legacy SHARED_GLOBAL field from '${roleName}' role ${legacyPermType} permissions`, - ); - } - } - - if (hasChanges) { - const updateObj = { permissions: updatedPermissions }; - - if (Object.keys(unsetFields).length > 0) { - logger.info( - `Unsetting old schema fields for '${roleName}' role: ${Object.keys(unsetFields).join(', ')}`, - ); - - try { - await Role.updateOne( - { name: roleName }, - { - $set: updateObj, - $unset: unsetFields, - }, - ); - - const cache = getLogStores(CacheKeys.ROLES); - const updatedRole = await Role.findOne({ name: roleName }).select('-__v').lean().exec(); - await cache.set(roleName, updatedRole); - - logger.info(`Updated role '${roleName}' and removed old schema fields`); - } catch (updateError) { - logger.error(`Error during role migration update: ${updateError.message}`); - throw updateError; - } - } else { - // Standard update if no migration needed - await updateRoleByName(roleName, updateObj); - } - - logger.info(`Updated '${roleName}' role permissions`); - } else { - logger.info(`No changes needed for '${roleName}' role permissions`); - } - } catch (error) { - logger.error(`Failed to update ${roleName} role permissions:`, error); - } -} - -/** - * Migrates roles from old schema to new schema structure. - * This can be called directly to fix existing roles. - * - * @param {string} [roleName] - Optional specific role to migrate. If not provided, migrates all roles. - * @returns {Promise} Number of roles migrated. - */ -const migrateRoleSchema = async function (roleName) { - try { - // Get roles to migrate - let roles; - if (roleName) { - const role = await Role.findOne({ name: roleName }); - roles = role ? [role] : []; - } else { - roles = await Role.find({}); - } - - logger.info(`Migrating ${roles.length} roles to new schema structure`); - let migratedCount = 0; - - for (const role of roles) { - const permissionTypes = Object.keys(permissionsSchema.shape || {}); - const unsetFields = {}; - let hasOldSchema = false; - - // Check for old schema fields - for (const permType of permissionTypes) { - if (role[permType] && typeof role[permType] === 'object') { - hasOldSchema = true; - - // Ensure permissions object exists - role.permissions = role.permissions || {}; - - // Migrate permissions from old location to new - role.permissions[permType] = { - ...role.permissions[permType], - ...role[permType], - }; - - // Mark field for removal - unsetFields[permType] = 1; - } - } - - if (hasOldSchema) { - try { - logger.info(`Migrating role '${role.name}' from old schema structure`); - - // Simple update operation - await Role.updateOne( - { _id: role._id }, - { - $set: { permissions: role.permissions }, - $unset: unsetFields, - }, - ); - - // Refresh cache - const cache = getLogStores(CacheKeys.ROLES); - const updatedRole = await Role.findById(role._id).lean().exec(); - await cache.set(role.name, updatedRole); - - migratedCount++; - logger.info(`Migrated role '${role.name}'`); - } catch (error) { - logger.error(`Failed to migrate role '${role.name}': ${error.message}`); - } - } - } - - logger.info(`Migration complete: ${migratedCount} roles migrated`); - return migratedCount; - } catch (error) { - logger.error(`Role schema migration failed: ${error.message}`); - throw error; - } -}; - -module.exports = { - getRoleByName, - updateRoleByName, - migrateRoleSchema, - updateAccessPermissions, -}; diff --git a/api/models/ToolCall.js b/api/models/ToolCall.js deleted file mode 100644 index 689386114b..0000000000 --- a/api/models/ToolCall.js +++ /dev/null @@ -1,96 +0,0 @@ -const { ToolCall } = require('~/db/models'); - -/** - * Create a new tool call - * @param {IToolCallData} toolCallData - The tool call data - * @returns {Promise} The created tool call document - */ -async function createToolCall(toolCallData) { - try { - return await ToolCall.create(toolCallData); - } catch (error) { - throw new Error(`Error creating tool call: ${error.message}`); - } -} - -/** - * Get a tool call by ID - * @param {string} id - The tool call document ID - * @returns {Promise} The tool call document or null if not found - */ -async function getToolCallById(id) { - try { - return await ToolCall.findById(id).lean(); - } catch (error) { - throw new Error(`Error fetching tool call: ${error.message}`); - } -} - -/** - * Get tool calls by message ID and user - * @param {string} messageId - The message ID - * @param {string} userId - The user's ObjectId - * @returns {Promise} Array of tool call documents - */ -async function getToolCallsByMessage(messageId, userId) { - try { - return await ToolCall.find({ messageId, user: userId }).lean(); - } catch (error) { - throw new Error(`Error fetching tool calls: ${error.message}`); - } -} - -/** - * Get tool calls by conversation ID and user - * @param {string} conversationId - The conversation ID - * @param {string} userId - The user's ObjectId - * @returns {Promise} Array of tool call documents - */ -async function getToolCallsByConvo(conversationId, userId) { - try { - return await ToolCall.find({ conversationId, user: userId }).lean(); - } catch (error) { - throw new Error(`Error fetching tool calls: ${error.message}`); - } -} - -/** - * Update a tool call - * @param {string} id - The tool call document ID - * @param {Partial} updateData - The data to update - * @returns {Promise} The updated tool call document or null if not found - */ -async function updateToolCall(id, updateData) { - try { - return await ToolCall.findByIdAndUpdate(id, updateData, { new: true }).lean(); - } catch (error) { - throw new Error(`Error updating tool call: ${error.message}`); - } -} - -/** - * Delete a tool call - * @param {string} userId - The related user's ObjectId - * @param {string} [conversationId] - The tool call conversation ID - * @returns {Promise<{ ok?: number; n?: number; deletedCount?: number }>} The result of the delete operation - */ -async function deleteToolCalls(userId, conversationId) { - try { - const query = { user: userId }; - if (conversationId) { - query.conversationId = conversationId; - } - return await ToolCall.deleteMany(query); - } catch (error) { - throw new Error(`Error deleting tool call: ${error.message}`); - } -} - -module.exports = { - createToolCall, - updateToolCall, - deleteToolCalls, - getToolCallById, - getToolCallsByConvo, - getToolCallsByMessage, -}; diff --git a/api/models/Transaction.js b/api/models/Transaction.js deleted file mode 100644 index 7f018e1c30..0000000000 --- a/api/models/Transaction.js +++ /dev/null @@ -1,223 +0,0 @@ -const { logger, CANCEL_RATE } = require('@librechat/data-schemas'); -const { getMultiplier, getCacheMultiplier } = require('./tx'); -const { Transaction } = require('~/db/models'); -const { updateBalance } = require('~/models'); - -/** Method to calculate and set the tokenValue for a transaction */ -function calculateTokenValue(txn) { - const { valueKey, tokenType, model, endpointTokenConfig, inputTokenCount } = txn; - const multiplier = Math.abs( - getMultiplier({ valueKey, tokenType, model, endpointTokenConfig, inputTokenCount }), - ); - txn.rate = multiplier; - txn.tokenValue = txn.rawAmount * multiplier; - if (txn.context && txn.tokenType === 'completion' && txn.context === 'incomplete') { - txn.tokenValue = Math.ceil(txn.tokenValue * CANCEL_RATE); - txn.rate *= CANCEL_RATE; - } -} - -/** - * New static method to create an auto-refill transaction that does NOT trigger a balance update. - * @param {object} txData - Transaction data. - * @param {string} txData.user - The user ID. - * @param {string} txData.tokenType - The type of token. - * @param {string} txData.context - The context of the transaction. - * @param {number} txData.rawAmount - The raw amount of tokens. - * @returns {Promise} - The created transaction. - */ -async function createAutoRefillTransaction(txData) { - if (txData.rawAmount != null && isNaN(txData.rawAmount)) { - return; - } - const transaction = new Transaction(txData); - transaction.endpointTokenConfig = txData.endpointTokenConfig; - transaction.inputTokenCount = txData.inputTokenCount; - calculateTokenValue(transaction); - await transaction.save(); - - const balanceResponse = await updateBalance({ - user: transaction.user, - incrementValue: txData.rawAmount, - setValues: { lastRefill: new Date() }, - }); - const result = { - rate: transaction.rate, - user: transaction.user.toString(), - balance: balanceResponse.tokenCredits, - }; - logger.debug('[Balance.check] Auto-refill performed', result); - result.transaction = transaction; - return result; -} - -/** - * Static method to create a transaction and update the balance - * @param {txData} _txData - Transaction data. - */ -async function createTransaction(_txData) { - const { balance, transactions, ...txData } = _txData; - if (txData.rawAmount != null && isNaN(txData.rawAmount)) { - return; - } - - if (transactions?.enabled === false) { - return; - } - - const transaction = new Transaction(txData); - transaction.endpointTokenConfig = txData.endpointTokenConfig; - transaction.inputTokenCount = txData.inputTokenCount; - calculateTokenValue(transaction); - - await transaction.save(); - if (!balance?.enabled) { - return; - } - - let incrementValue = transaction.tokenValue; - const balanceResponse = await updateBalance({ - user: transaction.user, - incrementValue, - }); - - return { - rate: transaction.rate, - user: transaction.user.toString(), - balance: balanceResponse.tokenCredits, - [transaction.tokenType]: incrementValue, - }; -} - -/** - * Static method to create a structured transaction and update the balance - * @param {txData} _txData - Transaction data. - */ -async function createStructuredTransaction(_txData) { - const { balance, transactions, ...txData } = _txData; - if (transactions?.enabled === false) { - return; - } - - const transaction = new Transaction(txData); - transaction.endpointTokenConfig = txData.endpointTokenConfig; - transaction.inputTokenCount = txData.inputTokenCount; - - calculateStructuredTokenValue(transaction); - - await transaction.save(); - - if (!balance?.enabled) { - return; - } - - let incrementValue = transaction.tokenValue; - - const balanceResponse = await updateBalance({ - user: transaction.user, - incrementValue, - }); - - return { - rate: transaction.rate, - user: transaction.user.toString(), - balance: balanceResponse.tokenCredits, - [transaction.tokenType]: incrementValue, - }; -} - -/** Method to calculate token value for structured tokens */ -function calculateStructuredTokenValue(txn) { - if (!txn.tokenType) { - txn.tokenValue = txn.rawAmount; - return; - } - - const { model, endpointTokenConfig, inputTokenCount } = txn; - - if (txn.tokenType === 'prompt') { - const inputMultiplier = getMultiplier({ - tokenType: 'prompt', - model, - endpointTokenConfig, - inputTokenCount, - }); - const writeMultiplier = - getCacheMultiplier({ cacheType: 'write', model, endpointTokenConfig }) ?? inputMultiplier; - const readMultiplier = - getCacheMultiplier({ cacheType: 'read', model, endpointTokenConfig }) ?? inputMultiplier; - - txn.rateDetail = { - input: inputMultiplier, - write: writeMultiplier, - read: readMultiplier, - }; - - const totalPromptTokens = - Math.abs(txn.inputTokens || 0) + - Math.abs(txn.writeTokens || 0) + - Math.abs(txn.readTokens || 0); - - if (totalPromptTokens > 0) { - txn.rate = - (Math.abs(inputMultiplier * (txn.inputTokens || 0)) + - Math.abs(writeMultiplier * (txn.writeTokens || 0)) + - Math.abs(readMultiplier * (txn.readTokens || 0))) / - totalPromptTokens; - } else { - txn.rate = Math.abs(inputMultiplier); // Default to input rate if no tokens - } - - txn.tokenValue = -( - Math.abs(txn.inputTokens || 0) * inputMultiplier + - Math.abs(txn.writeTokens || 0) * writeMultiplier + - Math.abs(txn.readTokens || 0) * readMultiplier - ); - - txn.rawAmount = -totalPromptTokens; - } else if (txn.tokenType === 'completion') { - const multiplier = getMultiplier({ - tokenType: txn.tokenType, - model, - endpointTokenConfig, - inputTokenCount, - }); - txn.rate = Math.abs(multiplier); - txn.tokenValue = -Math.abs(txn.rawAmount) * multiplier; - txn.rawAmount = -Math.abs(txn.rawAmount); - } - - if (txn.context && txn.tokenType === 'completion' && txn.context === 'incomplete') { - 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 * CANCEL_RATE]), - ); - } - } -} - -/** - * Queries and retrieves transactions based on a given filter. - * @async - * @function getTransactions - * @param {Object} filter - MongoDB filter object to apply when querying transactions. - * @returns {Promise} A promise that resolves to an array of matched transactions. - * @throws {Error} Throws an error if querying the database fails. - */ -async function getTransactions(filter) { - try { - return await Transaction.find(filter).lean(); - } catch (error) { - logger.error('Error querying transactions:', error); - throw error; - } -} - -module.exports = { - getTransactions, - createTransaction, - createAutoRefillTransaction, - createStructuredTransaction, -}; diff --git a/api/models/balanceMethods.js b/api/models/balanceMethods.js deleted file mode 100644 index e614872eac..0000000000 --- a/api/models/balanceMethods.js +++ /dev/null @@ -1,156 +0,0 @@ -const { logger } = require('@librechat/data-schemas'); -const { ViolationTypes } = require('librechat-data-provider'); -const { createAutoRefillTransaction } = require('./Transaction'); -const { logViolation } = require('~/cache'); -const { getMultiplier } = require('./tx'); -const { Balance } = require('~/db/models'); - -function isInvalidDate(date) { - return isNaN(date); -} - -/** - * Simple check method that calculates token cost and returns balance info. - * The auto-refill logic has been moved to balanceMethods.js to prevent circular dependencies. - */ -const checkBalanceRecord = async function ({ - user, - model, - endpoint, - valueKey, - tokenType, - amount, - endpointTokenConfig, -}) { - const multiplier = getMultiplier({ valueKey, tokenType, model, endpoint, endpointTokenConfig }); - const tokenCost = amount * multiplier; - - // Retrieve the balance record - let record = await Balance.findOne({ user }).lean(); - if (!record) { - logger.debug('[Balance.check] No balance record found for user', { user }); - return { - canSpend: false, - balance: 0, - tokenCost, - }; - } - let balance = record.tokenCredits; - - logger.debug('[Balance.check] Initial state', { - user, - model, - endpoint, - valueKey, - tokenType, - amount, - balance, - multiplier, - endpointTokenConfig: !!endpointTokenConfig, - }); - - // Only perform auto-refill if spending would bring the balance to 0 or below - if (balance - tokenCost <= 0 && record.autoRefillEnabled && record.refillAmount > 0) { - const lastRefillDate = new Date(record.lastRefill); - const now = new Date(); - if ( - isInvalidDate(lastRefillDate) || - now >= - addIntervalToDate(lastRefillDate, record.refillIntervalValue, record.refillIntervalUnit) - ) { - try { - /** @type {{ rate: number, user: string, balance: number, transaction: import('@librechat/data-schemas').ITransaction}} */ - const result = await createAutoRefillTransaction({ - user: user, - tokenType: 'credits', - context: 'autoRefill', - rawAmount: record.refillAmount, - }); - balance = result.balance; - } catch (error) { - logger.error('[Balance.check] Failed to record transaction for auto-refill', error); - } - } - } - - logger.debug('[Balance.check] Token cost', { tokenCost }); - return { canSpend: balance >= tokenCost, balance, tokenCost }; -}; - -/** - * Adds a time interval to a given date. - * @param {Date} date - The starting date. - * @param {number} value - The numeric value of the interval. - * @param {'seconds'|'minutes'|'hours'|'days'|'weeks'|'months'} unit - The unit of time. - * @returns {Date} A new Date representing the starting date plus the interval. - */ -const addIntervalToDate = (date, value, unit) => { - const result = new Date(date); - switch (unit) { - case 'seconds': - result.setSeconds(result.getSeconds() + value); - break; - case 'minutes': - result.setMinutes(result.getMinutes() + value); - break; - case 'hours': - result.setHours(result.getHours() + value); - break; - case 'days': - result.setDate(result.getDate() + value); - break; - case 'weeks': - result.setDate(result.getDate() + value * 7); - break; - case 'months': - result.setMonth(result.getMonth() + value); - break; - default: - break; - } - return result; -}; - -/** - * Checks the balance for a user and determines if they can spend a certain amount. - * If the user cannot spend the amount, it logs a violation and denies the request. - * - * @async - * @function - * @param {Object} params - The function parameters. - * @param {ServerRequest} params.req - The Express request object. - * @param {Express.Response} params.res - The Express response object. - * @param {Object} params.txData - The transaction data. - * @param {string} params.txData.user - The user ID or identifier. - * @param {('prompt' | 'completion')} params.txData.tokenType - The type of token. - * @param {number} params.txData.amount - The amount of tokens. - * @param {string} params.txData.model - The model name or identifier. - * @param {string} [params.txData.endpointTokenConfig] - The token configuration for the endpoint. - * @returns {Promise} Throws error if the user cannot spend the amount. - * @throws {Error} Throws an error if there's an issue with the balance check. - */ -const checkBalance = async ({ req, res, txData }) => { - const { canSpend, balance, tokenCost } = await checkBalanceRecord(txData); - if (canSpend) { - return true; - } - - const type = ViolationTypes.TOKEN_BALANCE; - const errorMessage = { - type, - balance, - tokenCost, - promptTokens: txData.amount, - }; - - if (txData.generations && txData.generations.length > 0) { - errorMessage.generations = txData.generations; - } - - await logViolation(req, res, type, errorMessage, 0); - throw new Error(JSON.stringify(errorMessage)); -}; - -module.exports = { - checkBalance, -}; diff --git a/api/models/index.js b/api/models/index.js index d0b10be079..2a1cb222f9 100644 --- a/api/models/index.js +++ b/api/models/index.js @@ -1,48 +1,22 @@ const mongoose = require('mongoose'); const { createMethods } = require('@librechat/data-schemas'); -const methods = createMethods(mongoose); -const { comparePassword } = require('./userMethods'); -const { - getMessage, - getMessages, - saveMessage, - recordMessage, - updateMessage, - deleteMessagesSince, - deleteMessages, -} = require('./Message'); -const { getConvoTitle, getConvo, saveConvo, deleteConvos } = require('./Conversation'); -const { getPreset, getPresets, savePreset, deletePresets } = require('./Preset'); -const { File } = require('~/db/models'); +const { matchModelName, findMatchingPattern } = require('@librechat/api'); +const getLogStores = require('~/cache/getLogStores'); + +const methods = createMethods(mongoose, { + matchModelName, + findMatchingPattern, + getCache: getLogStores, +}); const seedDatabase = async () => { await methods.initializeRoles(); await methods.seedDefaultRoles(); await methods.ensureDefaultCategories(); + await methods.seedSystemGrants(); }; module.exports = { ...methods, seedDatabase, - comparePassword, - - getMessage, - getMessages, - saveMessage, - recordMessage, - updateMessage, - deleteMessagesSince, - deleteMessages, - - getConvoTitle, - getConvo, - saveConvo, - deleteConvos, - - getPreset, - getPresets, - savePreset, - deletePresets, - - Files: File, }; diff --git a/api/models/interface.js b/api/models/interface.js deleted file mode 100644 index a79a8e747f..0000000000 --- a/api/models/interface.js +++ /dev/null @@ -1,24 +0,0 @@ -const { logger } = require('@librechat/data-schemas'); -const { updateInterfacePermissions: updateInterfacePerms } = require('@librechat/api'); -const { getRoleByName, updateAccessPermissions } = require('./Role'); - -/** - * Update interface permissions based on app configuration. - * Must be done independently from loading the app config. - * @param {AppConfig} appConfig - */ -async function updateInterfacePermissions(appConfig) { - try { - await updateInterfacePerms({ - appConfig, - getRoleByName, - updateAccessPermissions, - }); - } catch (error) { - logger.error('Error updating interface permissions:', error); - } -} - -module.exports = { - updateInterfacePermissions, -}; diff --git a/api/models/inviteUser.js b/api/models/inviteUser.js deleted file mode 100644 index eda8394225..0000000000 --- a/api/models/inviteUser.js +++ /dev/null @@ -1,68 +0,0 @@ -const mongoose = require('mongoose'); -const { logger, hashToken, getRandomValues } = require('@librechat/data-schemas'); -const { createToken, findToken } = require('~/models'); - -/** - * @module inviteUser - * @description This module provides functions to create and get user invites - */ - -/** - * @function createInvite - * @description This function creates a new user invite - * @param {string} email - The email of the user to invite - * @returns {Promise} A promise that resolves to the saved invite document - * @throws {Error} If there is an error creating the invite - */ -const createInvite = async (email) => { - try { - const token = await getRandomValues(32); - const hash = await hashToken(token); - const encodedToken = encodeURIComponent(token); - - const fakeUserId = new mongoose.Types.ObjectId(); - - await createToken({ - userId: fakeUserId, - email, - token: hash, - createdAt: Date.now(), - expiresIn: 604800, - }); - - return encodedToken; - } catch (error) { - logger.error('[createInvite] Error creating invite', error); - return { message: 'Error creating invite' }; - } -}; - -/** - * @function getInvite - * @description This function retrieves a user invite - * @param {string} encodedToken - The token of the invite to retrieve - * @param {string} email - The email of the user to validate - * @returns {Promise} A promise that resolves to the retrieved invite document - * @throws {Error} If there is an error retrieving the invite, if the invite does not exist, or if the email does not match - */ -const getInvite = async (encodedToken, email) => { - try { - const token = decodeURIComponent(encodedToken); - const hash = await hashToken(token); - const invite = await findToken({ token: hash, email }); - - if (!invite) { - throw new Error('Invite not found or email does not match'); - } - - return invite; - } catch (error) { - logger.error('[getInvite] Error getting invite:', error); - return { error: true, message: error.message }; - } -}; - -module.exports = { - createInvite, - getInvite, -}; diff --git a/api/models/loadAddedAgent.js b/api/models/loadAddedAgent.js deleted file mode 100644 index aa83375eae..0000000000 --- a/api/models/loadAddedAgent.js +++ /dev/null @@ -1,218 +0,0 @@ -const { logger } = require('@librechat/data-schemas'); -const { getCustomEndpointConfig } = require('@librechat/api'); -const { - Tools, - Constants, - isAgentsEndpoint, - isEphemeralAgentId, - appendAgentIdSuffix, - encodeEphemeralAgentId, -} = require('librechat-data-provider'); -const { getMCPServerTools } = require('~/server/services/Config'); - -const { mcp_all, mcp_delimiter } = Constants; - -/** - * Constant for added conversation agent ID - */ -const ADDED_AGENT_ID = 'added_agent'; - -/** - * Get an agent document based on the provided ID. - * @param {Object} searchParameter - The search parameters to find the agent. - * @param {string} searchParameter.id - The ID of the agent. - * @returns {Promise} - */ -let getAgent; - -/** - * Set the getAgent function (dependency injection to avoid circular imports) - * @param {Function} fn - */ -const setGetAgent = (fn) => { - getAgent = fn; -}; - -/** - * Load an agent from an added conversation (TConversation). - * Used for multi-convo parallel agent execution. - * - * @param {Object} params - * @param {import('express').Request} params.req - * @param {import('librechat-data-provider').TConversation} params.conversation - The added conversation - * @param {import('librechat-data-provider').Agent} [params.primaryAgent] - The primary agent (used to duplicate tools when both are ephemeral) - * @returns {Promise} The agent config as a plain object, or null if invalid. - */ -const loadAddedAgent = async ({ req, conversation, primaryAgent }) => { - if (!conversation) { - 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'); - } - const agent = await getAgent({ - id: conversation.agent_id, - }); - - if (!agent) { - logger.warn(`[loadAddedAgent] Agent ${conversation.agent_id} not found`); - return null; - } - - agent.version = agent.versions ? agent.versions.length : 0; - // Append suffix to distinguish from primary agent (matches ephemeral format) - // This is needed when both agents have the same ID or for consistent parallel content attribution - agent.id = appendAgentIdSuffix(agent.id, 1); - return agent; - } - - // Otherwise, create an ephemeral agent config from the conversation - const { model, endpoint, promptPrefix, spec, ...rest } = conversation; - - if (!endpoint || !model) { - logger.warn('[loadAddedAgent] Missing required endpoint or model for ephemeral agent'); - return null; - } - - // If both primary and added agents are ephemeral, duplicate tools from primary agent - const primaryIsEphemeral = primaryAgent && isEphemeralAgentId(primaryAgent.id); - if (primaryIsEphemeral && Array.isArray(primaryAgent.tools)) { - // Get endpoint config and model spec for display name fallbacks - const appConfig = req.config; - let endpointConfig = appConfig?.endpoints?.[endpoint]; - if (!isAgentsEndpoint(endpoint) && !endpointConfig) { - try { - endpointConfig = getCustomEndpointConfig({ endpoint, appConfig }); - } catch (err) { - logger.error('[loadAddedAgent] Error getting custom endpoint config', err); - } - } - - // Look up model spec for label fallback - const modelSpecs = appConfig?.modelSpecs?.list; - const modelSpec = spec != null && spec !== '' ? modelSpecs?.find((s) => s.name === spec) : null; - - // For ephemeral agents, use modelLabel if provided, then model spec's label, - // then modelDisplayLabel from endpoint config, otherwise empty string to show model name - const sender = rest.modelLabel ?? modelSpec?.label ?? endpointConfig?.modelDisplayLabel ?? ''; - - const ephemeralId = encodeEphemeralAgentId({ endpoint, model, sender, index: 1 }); - - return { - id: ephemeralId, - instructions: promptPrefix || '', - provider: endpoint, - model_parameters: {}, - model, - tools: [...primaryAgent.tools], - }; - } - - // Extract ephemeral agent options from conversation if present - const ephemeralAgent = rest.ephemeralAgent; - const mcpServers = new Set(ephemeralAgent?.mcp); - const userId = req.user?.id; - - // Check model spec for MCP servers - const modelSpecs = req.config?.modelSpecs?.list; - let modelSpec = null; - if (spec != null && spec !== '') { - modelSpec = modelSpecs?.find((s) => s.name === spec) || null; - } - if (modelSpec?.mcpServers) { - for (const mcpServer of modelSpec.mcpServers) { - mcpServers.add(mcpServer); - } - } - - /** @type {string[]} */ - const tools = []; - if (ephemeralAgent?.execute_code === true || modelSpec?.executeCode === true) { - tools.push(Tools.execute_code); - } - if (ephemeralAgent?.file_search === true || modelSpec?.fileSearch === true) { - tools.push(Tools.file_search); - } - if (ephemeralAgent?.web_search === true || modelSpec?.webSearch === true) { - tools.push(Tools.web_search); - } - - const addedServers = new Set(); - if (mcpServers.size > 0) { - for (const mcpServer of mcpServers) { - if (addedServers.has(mcpServer)) { - continue; - } - const serverTools = await getMCPServerTools(userId, mcpServer); - if (!serverTools) { - tools.push(`${mcp_all}${mcp_delimiter}${mcpServer}`); - addedServers.add(mcpServer); - continue; - } - tools.push(...Object.keys(serverTools)); - addedServers.add(mcpServer); - } - } - - // Build model_parameters from conversation fields - const model_parameters = {}; - const paramKeys = [ - 'temperature', - 'top_p', - 'topP', - 'topK', - 'presence_penalty', - 'frequency_penalty', - 'maxOutputTokens', - 'maxTokens', - 'max_tokens', - ]; - - for (const key of paramKeys) { - if (rest[key] != null) { - model_parameters[key] = rest[key]; - } - } - - // Get endpoint config for modelDisplayLabel fallback - const appConfig = req.config; - let endpointConfig = appConfig?.endpoints?.[endpoint]; - if (!isAgentsEndpoint(endpoint) && !endpointConfig) { - try { - endpointConfig = getCustomEndpointConfig({ endpoint, appConfig }); - } catch (err) { - logger.error('[loadAddedAgent] Error getting custom endpoint config', err); - } - } - - // For ephemeral agents, use modelLabel if provided, then model spec's label, - // then modelDisplayLabel from endpoint config, otherwise empty string to show model name - const sender = rest.modelLabel ?? modelSpec?.label ?? endpointConfig?.modelDisplayLabel ?? ''; - - /** Encoded ephemeral agent ID with endpoint, model, sender, and index=1 to distinguish from primary */ - const ephemeralId = encodeEphemeralAgentId({ endpoint, model, sender, index: 1 }); - - const result = { - id: ephemeralId, - instructions: promptPrefix || '', - provider: endpoint, - model_parameters, - model, - tools, - }; - - if (ephemeralAgent?.artifacts != null && ephemeralAgent.artifacts) { - result.artifacts = ephemeralAgent.artifacts; - } - - return result; -}; - -module.exports = { - ADDED_AGENT_ID, - loadAddedAgent, - setGetAgent, -}; diff --git a/api/models/spendTokens.js b/api/models/spendTokens.js deleted file mode 100644 index afe05969d8..0000000000 --- a/api/models/spendTokens.js +++ /dev/null @@ -1,140 +0,0 @@ -const { logger } = require('@librechat/data-schemas'); -const { createTransaction, createStructuredTransaction } = require('./Transaction'); -/** - * Creates up to two transactions to record the spending of tokens. - * - * @function - * @async - * @param {txData} txData - Transaction data. - * @param {Object} tokenUsage - The number of tokens used. - * @param {Number} tokenUsage.promptTokens - The number of prompt tokens used. - * @param {Number} tokenUsage.completionTokens - The number of completion tokens used. - * @returns {Promise} - Returns nothing. - * @throws {Error} - Throws an error if there's an issue creating the transactions. - */ -const spendTokens = async (txData, tokenUsage) => { - const { promptTokens, completionTokens } = tokenUsage; - logger.debug( - `[spendTokens] conversationId: ${txData.conversationId}${ - txData?.context ? ` | Context: ${txData?.context}` : '' - } | Token usage: `, - { - promptTokens, - completionTokens, - }, - ); - let prompt, completion; - const normalizedPromptTokens = Math.max(promptTokens ?? 0, 0); - try { - if (promptTokens !== undefined) { - prompt = await createTransaction({ - ...txData, - tokenType: 'prompt', - rawAmount: promptTokens === 0 ? 0 : -normalizedPromptTokens, - inputTokenCount: normalizedPromptTokens, - }); - } - - if (completionTokens !== undefined) { - completion = await createTransaction({ - ...txData, - tokenType: 'completion', - rawAmount: completionTokens === 0 ? 0 : -Math.max(completionTokens, 0), - inputTokenCount: normalizedPromptTokens, - }); - } - - if (prompt || completion) { - logger.debug('[spendTokens] Transaction data record against balance:', { - user: txData.user, - prompt: prompt?.prompt, - promptRate: prompt?.rate, - completion: completion?.completion, - completionRate: completion?.rate, - balance: completion?.balance ?? prompt?.balance, - }); - } else { - logger.debug('[spendTokens] No transactions incurred against balance'); - } - } catch (err) { - logger.error('[spendTokens]', err); - } -}; - -/** - * Creates transactions to record the spending of structured tokens. - * - * @function - * @async - * @param {txData} txData - Transaction data. - * @param {Object} tokenUsage - The number of tokens used. - * @param {Object} tokenUsage.promptTokens - The number of prompt tokens used. - * @param {Number} tokenUsage.promptTokens.input - The number of input tokens. - * @param {Number} tokenUsage.promptTokens.write - The number of write tokens. - * @param {Number} tokenUsage.promptTokens.read - The number of read tokens. - * @param {Number} tokenUsage.completionTokens - The number of completion tokens used. - * @returns {Promise} - Returns nothing. - * @throws {Error} - Throws an error if there's an issue creating the transactions. - */ -const spendStructuredTokens = async (txData, tokenUsage) => { - const { promptTokens, completionTokens } = tokenUsage; - logger.debug( - `[spendStructuredTokens] conversationId: ${txData.conversationId}${ - txData?.context ? ` | Context: ${txData?.context}` : '' - } | Token usage: `, - { - promptTokens, - completionTokens, - }, - ); - let prompt, completion; - try { - if (promptTokens) { - const input = Math.max(promptTokens.input ?? 0, 0); - const write = Math.max(promptTokens.write ?? 0, 0); - const read = Math.max(promptTokens.read ?? 0, 0); - const totalInputTokens = input + write + read; - prompt = await createStructuredTransaction({ - ...txData, - tokenType: 'prompt', - inputTokens: -input, - writeTokens: -write, - readTokens: -read, - inputTokenCount: totalInputTokens, - }); - } - - if (completionTokens) { - const totalInputTokens = promptTokens - ? Math.max(promptTokens.input ?? 0, 0) + - Math.max(promptTokens.write ?? 0, 0) + - Math.max(promptTokens.read ?? 0, 0) - : undefined; - completion = await createTransaction({ - ...txData, - tokenType: 'completion', - rawAmount: -Math.max(completionTokens, 0), - inputTokenCount: totalInputTokens, - }); - } - - if (prompt || completion) { - logger.debug('[spendStructuredTokens] Transaction data record against balance:', { - user: txData.user, - prompt: prompt?.prompt, - promptRate: prompt?.rate, - completion: completion?.completion, - completionRate: completion?.rate, - balance: completion?.balance ?? prompt?.balance, - }); - } else { - logger.debug('[spendStructuredTokens] No transactions incurred against balance'); - } - } catch (err) { - logger.error('[spendStructuredTokens]', err); - } - - return { prompt, completion }; -}; - -module.exports = { spendTokens, spendStructuredTokens }; diff --git a/api/models/userMethods.js b/api/models/userMethods.js deleted file mode 100644 index b57b24e641..0000000000 --- a/api/models/userMethods.js +++ /dev/null @@ -1,31 +0,0 @@ -const bcrypt = require('bcryptjs'); - -/** - * Compares the provided password with the user's password. - * - * @param {IUser} user - The user to compare the password for. - * @param {string} candidatePassword - The password to test against the user's password. - * @returns {Promise} A promise that resolves to a boolean indicating if the password matches. - */ -const comparePassword = async (user, candidatePassword) => { - if (!user) { - throw new Error('No user provided'); - } - - if (!user.password) { - throw new Error('No password, likely an email first registered via Social/OIDC login'); - } - - return new Promise((resolve, reject) => { - bcrypt.compare(candidatePassword, user.password, (err, isMatch) => { - if (err) { - reject(err); - } - resolve(isMatch); - }); - }); -}; - -module.exports = { - comparePassword, -}; diff --git a/api/package.json b/api/package.json index 7710956701..8b2f156cd3 100644 --- a/api/package.json +++ b/api/package.json @@ -1,6 +1,6 @@ { "name": "@librechat/backend", - "version": "v0.8.3-rc2", + "version": "v0.8.4", "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.55", + "@librechat/agents": "^3.1.62", "@librechat/api": "*", "@librechat/data-schemas": "*", "@microsoft/microsoft-graph-client": "^3.0.7", "@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", @@ -106,13 +107,13 @@ "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", + "yauzl": "^3.2.1", "zod": "^3.22.4" }, "devDependencies": { diff --git a/api/server/controllers/AuthController.js b/api/server/controllers/AuthController.js index 13d024cd03..eb44feffa4 100644 --- a/api/server/controllers/AuthController.js +++ b/api/server/controllers/AuthController.js @@ -119,14 +119,8 @@ const refreshController = async (req, res) => { const token = setOpenIDAuthTokens(tokenset, req, res, user._id.toString(), refreshToken); - user.federatedTokens = { - access_token: tokenset.access_token, - id_token: tokenset.id_token, - refresh_token: refreshToken, - expires_at: claims.exp, - }; - - return res.status(200).send({ token, user }); + const { password: _pw, __v: _v, totpSecret: _ts, backupCodes: _bc, ...safeUser } = user; + return res.status(200).send({ token, user: safeUser }); } catch (error) { logger.error('[refreshController] OpenID token refresh error', error); return res.status(403).send('Invalid OpenID refresh token'); diff --git a/api/server/controllers/AuthController.spec.js b/api/server/controllers/AuthController.spec.js index fef670baa8..964947def9 100644 --- a/api/server/controllers/AuthController.spec.js +++ b/api/server/controllers/AuthController.spec.js @@ -163,6 +163,16 @@ describe('refreshController – OpenID path', () => { exp: 9999999999, }; + const defaultUser = { + _id: 'user-db-id', + email: baseClaims.email, + openidId: baseClaims.sub, + password: '$2b$10$hashedpassword', + __v: 0, + totpSecret: 'encrypted-totp-secret', + backupCodes: ['hashed-code-1', 'hashed-code-2'], + }; + let req, res; beforeEach(() => { @@ -174,6 +184,7 @@ describe('refreshController – OpenID path', () => { mockTokenset.claims.mockReturnValue(baseClaims); getOpenIdEmail.mockReturnValue(baseClaims.email); setOpenIDAuthTokens.mockReturnValue('new-app-token'); + findOpenIDUser.mockResolvedValue({ user: { ...defaultUser }, error: null, migration: false }); updateUser.mockResolvedValue({}); req = { @@ -189,13 +200,6 @@ describe('refreshController – OpenID path', () => { }); 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); @@ -229,13 +233,6 @@ describe('refreshController – OpenID path', () => { 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( @@ -243,6 +240,25 @@ describe('refreshController – OpenID path', () => { ); }); + it('should not expose sensitive fields or federatedTokens in refresh response', async () => { + await refreshController(req, res); + + const sentPayload = res.send.mock.calls[0][0]; + expect(sentPayload).toEqual({ + token: 'new-app-token', + user: expect.objectContaining({ + _id: 'user-db-id', + email: baseClaims.email, + openidId: baseClaims.sub, + }), + }); + expect(sentPayload.user).not.toHaveProperty('federatedTokens'); + expect(sentPayload.user).not.toHaveProperty('password'); + expect(sentPayload.user).not.toHaveProperty('totpSecret'); + expect(sentPayload.user).not.toHaveProperty('backupCodes'); + expect(sentPayload.user).not.toHaveProperty('__v'); + }); + 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 }); diff --git a/api/server/controllers/Balance.js b/api/server/controllers/Balance.js index c892a73b0c..fd9b32e74c 100644 --- a/api/server/controllers/Balance.js +++ b/api/server/controllers/Balance.js @@ -1,24 +1,22 @@ -const { Balance } = require('~/db/models'); +const { findBalanceByUser } = require('~/models'); async function balanceController(req, res) { - const balanceData = await Balance.findOne( - { user: req.user.id }, - '-_id tokenCredits autoRefillEnabled refillIntervalValue refillIntervalUnit lastRefill refillAmount', - ).lean(); + const balanceData = await findBalanceByUser(req.user.id); if (!balanceData) { return res.status(404).json({ error: 'Balance not found' }); } - // If auto-refill is not enabled, remove auto-refill related fields from the response - if (!balanceData.autoRefillEnabled) { - delete balanceData.refillIntervalValue; - delete balanceData.refillIntervalUnit; - delete balanceData.lastRefill; - delete balanceData.refillAmount; + const { _id: _, ...result } = balanceData; + + if (!result.autoRefillEnabled) { + delete result.refillIntervalValue; + delete result.refillIntervalUnit; + delete result.lastRefill; + delete result.refillAmount; } - res.status(200).json(balanceData); + res.status(200).json(result); } module.exports = balanceController; diff --git a/api/server/controllers/PermissionsController.js b/api/server/controllers/PermissionsController.js index 51993d083c..1f200fce83 100644 --- a/api/server/controllers/PermissionsController.js +++ b/api/server/controllers/PermissionsController.js @@ -9,22 +9,17 @@ const { enrichRemoteAgentPrincipals, backfillRemoteAgentPermissions } = require( const { bulkUpdateResourcePermissions, ensureGroupPrincipalExists, + getResourcePermissionsMap, + findAccessibleResources, getEffectivePermissions, ensurePrincipalExists, getAvailableRoles, - findAccessibleResources, - getResourcePermissionsMap, } = require('~/server/services/PermissionService'); -const { - searchPrincipals: searchLocalPrincipals, - sortPrincipalsByRelevance, - calculateRelevanceScore, -} = require('~/models'); const { entraIdPrincipalFeatureEnabled, searchEntraIdPrincipals, } = require('~/server/services/GraphApiService'); -const { AclEntry, AccessRole } = require('~/db/models'); +const db = require('~/models'); /** * Generic controller for resource permission endpoints @@ -155,6 +150,18 @@ const updateResourcePermissions = async (req, res) => { grantedBy: userId, }); + const isAgentResource = + resourceType === ResourceType.AGENT || resourceType === ResourceType.REMOTE_AGENT; + const revokedUserIds = results.revoked + .filter((p) => p.type === PrincipalType.USER && p.id) + .map((p) => p.id); + + if (isAgentResource && revokedUserIds.length > 0) { + db.removeAgentFromUserFavorites(resourceId, revokedUserIds).catch((err) => { + logger.error('[removeRevokedAgentFromFavorites] Error cleaning up favorites', err); + }); + } + /** @type {TUpdateResourcePermissionsResponse} */ const response = { message: 'Permissions updated successfully', @@ -185,8 +192,7 @@ const getResourcePermissions = async (req, res) => { const { resourceType, resourceId } = req.params; validateResourceType(resourceType); - // Use aggregation pipeline for efficient single-query data retrieval - const results = await AclEntry.aggregate([ + const results = await db.aggregateAclEntries([ // Match ACL entries for this resource { $match: { @@ -282,7 +288,12 @@ const getResourcePermissions = async (req, res) => { } if (resourceType === ResourceType.REMOTE_AGENT) { - const enricherDeps = { AclEntry, AccessRole, logger }; + const enricherDeps = { + aggregateAclEntries: db.aggregateAclEntries, + bulkWriteAclEntries: db.bulkWriteAclEntries, + findRoleByIdentifier: db.findRoleByIdentifier, + logger, + }; const enrichResult = await enrichRemoteAgentPrincipals(enricherDeps, resourceId, principals); principals = enrichResult.principals; backfillRemoteAgentPermissions(enricherDeps, resourceId, enrichResult.entriesToBackfill); @@ -399,7 +410,7 @@ const searchPrincipals = async (req, res) => { typeFilters = validTypes.length > 0 ? validTypes : null; } - const localResults = await searchLocalPrincipals(query.trim(), searchLimit, typeFilters); + const localResults = await db.searchPrincipals(query.trim(), searchLimit, typeFilters); let allPrincipals = [...localResults]; const useEntraId = entraIdPrincipalFeatureEnabled(req.user); @@ -455,10 +466,11 @@ const searchPrincipals = async (req, res) => { } const scoredResults = allPrincipals.map((item) => ({ ...item, - _searchScore: calculateRelevanceScore(item, query.trim()), + _searchScore: db.calculateRelevanceScore(item, query.trim()), })); - const finalResults = sortPrincipalsByRelevance(scoredResults) + const finalResults = db + .sortPrincipalsByRelevance(scoredResults) .slice(0, searchLimit) .map((result) => { const { _searchScore, ...resultWithoutScore } = result; 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..301c6d2f76 100644 --- a/api/server/controllers/UserController.js +++ b/api/server/controllers/UserController.js @@ -1,49 +1,29 @@ +const mongoose = require('mongoose'); const { logger, webSearchKeys } = require('@librechat/data-schemas'); -const { Tools, CacheKeys, Constants, FileSources } = require('librechat-data-provider'); const { + getNewS3URL, + needsRefresh, MCPOAuthHandler, MCPTokenStorage, normalizeHttpError, extractWebSearchEnvVars, } = require('@librechat/api'); const { - deleteAllUserSessions, - deleteAllSharedLinks, - updateUserPlugins, - deleteUserById, - deleteMessages, - deletePresets, - deleteUserKey, - deleteConvos, - deleteFiles, - updateUser, - findToken, - getFiles, -} = require('~/models'); -const { - ConversationTag, - AgentApiKey, - Transaction, - MemoryEntry, - Assistant, - AclEntry, - Balance, - Action, - Group, - Token, - User, -} = require('~/db/models'); + Tools, + CacheKeys, + Constants, + FileSources, + ResourceType, +} = require('librechat-data-provider'); 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'); -const { needsRefresh, getNewS3URL } = require('~/server/services/Files/S3/crud'); const { processDeleteRequest } = require('~/server/services/Files/process'); const { getAppConfig } = require('~/server/services/Config'); -const { deleteToolCalls } = require('~/models/ToolCall'); -const { deleteUserPrompts } = require('~/models/Prompt'); -const { deleteUserAgents } = require('~/models/Agent'); const { getLogStores } = require('~/cache'); +const db = require('~/models'); const getUserController = async (req, res) => { const appConfig = await getAppConfig({ role: req.user?.role }); @@ -64,7 +44,7 @@ const getUserController = async (req, res) => { const originalAvatar = userData.avatar; try { userData.avatar = await getNewS3URL(userData.avatar); - await updateUser(userData.id, { avatar: userData.avatar }); + await db.updateUser(userData.id, { avatar: userData.avatar }); } catch (error) { userData.avatar = originalAvatar; logger.error('Error getting new S3 URL for avatar:', error); @@ -75,7 +55,7 @@ const getUserController = async (req, res) => { const getTermsStatusController = async (req, res) => { try { - const user = await User.findById(req.user.id); + const user = await db.getUserById(req.user.id, 'termsAccepted'); if (!user) { return res.status(404).json({ message: 'User not found' }); } @@ -88,7 +68,7 @@ const getTermsStatusController = async (req, res) => { const acceptTermsController = async (req, res) => { try { - const user = await User.findByIdAndUpdate(req.user.id, { termsAccepted: true }, { new: true }); + const user = await db.updateUser(req.user.id, { termsAccepted: true }); if (!user) { return res.status(404).json({ message: 'User not found' }); } @@ -101,7 +81,7 @@ const acceptTermsController = async (req, res) => { const deleteUserFiles = async (req) => { try { - const userFiles = await getFiles({ user: req.user.id }); + const userFiles = await db.getFiles({ user: req.user.id }); await processDeleteRequest({ req, files: userFiles, @@ -111,13 +91,86 @@ const deleteUserFiles = async (req) => { } }; +/** + * Deletes MCP servers solely owned by the user and cleans up their ACLs. + * Disconnects live sessions for deleted servers before removing DB records. + * Servers with other owners are left intact; the caller is responsible for + * removing the user's own ACL principal entries separately. + * + * Also handles legacy (pre-ACL) MCP servers that only have the author field set, + * ensuring they are not orphaned if no permission migration has been run. + * @param {string} userId - The ID of the user. + */ +const deleteUserMcpServers = async (userId) => { + try { + const MCPServer = mongoose.models.MCPServer; + const AclEntry = mongoose.models.AclEntry; + if (!MCPServer) { + return; + } + + const userObjectId = new mongoose.Types.ObjectId(userId); + const soleOwnedIds = await db.getSoleOwnedResourceIds(userObjectId, ResourceType.MCPSERVER); + + const authoredServers = await MCPServer.find({ author: userObjectId }) + .select('_id serverName') + .lean(); + + const migratedEntries = + authoredServers.length > 0 + ? await AclEntry.find({ + resourceType: ResourceType.MCPSERVER, + resourceId: { $in: authoredServers.map((s) => s._id) }, + }) + .select('resourceId') + .lean() + : []; + const migratedIds = new Set(migratedEntries.map((e) => e.resourceId.toString())); + const legacyServers = authoredServers.filter((s) => !migratedIds.has(s._id.toString())); + const legacyServerIds = legacyServers.map((s) => s._id); + + const allServerIdsToDelete = [...soleOwnedIds, ...legacyServerIds]; + + if (allServerIdsToDelete.length === 0) { + return; + } + + const aclOwnedServers = + soleOwnedIds.length > 0 + ? await MCPServer.find({ _id: { $in: soleOwnedIds } }) + .select('serverName') + .lean() + : []; + const allServersToDelete = [...aclOwnedServers, ...legacyServers]; + + const mcpManager = getMCPManager(); + if (mcpManager) { + await Promise.all( + allServersToDelete.map(async (s) => { + await mcpManager.disconnectUserConnection(userId, s.serverName); + await invalidateCachedTools({ userId, serverName: s.serverName }); + }), + ); + } + + await AclEntry.deleteMany({ + resourceType: ResourceType.MCPSERVER, + resourceId: { $in: allServerIdsToDelete }, + }); + + await MCPServer.deleteMany({ _id: { $in: allServerIdsToDelete } }); + } catch (error) { + logger.error('[deleteUserMcpServers] General error:', error); + } +}; + const updateUserPluginsController = async (req, res) => { const appConfig = await getAppConfig({ role: req.user?.role }); const { user } = req; const { pluginKey, action, auth, isEntityTool } = req.body; try { if (!isEntityTool) { - await updateUserPlugins(user._id, user.plugins, pluginKey, action); + await db.updateUserPlugins(user._id, user.plugins, pluginKey, action); } if (auth == null) { @@ -241,37 +294,50 @@ const deleteUserController = async (req, res) => { const { user } = req; try { - 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 - await deleteUserKey({ userId: user.id, all: true }); // delete user keys - await Balance.deleteMany({ user: user._id }); // delete user balances - await deletePresets(user.id); // delete user presets + const existingUser = await db.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 db.deleteMessages({ user: user.id }); + await db.deleteAllUserSessions({ userId: user.id }); + await db.deleteTransactions({ user: user.id }); + await db.deleteUserKey({ userId: user.id, all: true }); + await db.deleteBalances({ user: user._id }); + await db.deletePresets(user.id); try { - await deleteConvos(user.id); // delete user convos + await db.deleteConvos(user.id); } catch (error) { logger.error('[deleteUserController] Error deleting user convos, likely no convos', error); } - await deleteUserPluginAuth(user.id, null, true); // delete user plugin auth - await deleteUserById(user.id); // delete user - await deleteAllSharedLinks(user.id); // delete user shared links - await deleteUserFiles(req); // delete user files - await deleteFiles(null, user.id); // delete database files in case of orphaned files from previous steps - await deleteToolCalls(user.id); // delete user tool calls - await deleteUserAgents(user.id); // delete user agents - await AgentApiKey.deleteMany({ user: user._id }); // delete user agent API keys - await Assistant.deleteMany({ user: user.id }); // delete user assistants - await ConversationTag.deleteMany({ user: user.id }); // delete user conversation tags - await MemoryEntry.deleteMany({ userId: user.id }); // delete user memory entries - await deleteUserPrompts(req, user.id); // delete user prompts - await Action.deleteMany({ user: user.id }); // delete user actions - await Token.deleteMany({ userId: user.id }); // delete user OAuth tokens - await Group.updateMany( - // remove user from all groups - { memberIds: user.id }, - { $pull: { memberIds: user.id } }, - ); - await AclEntry.deleteMany({ principalId: user._id }); // delete user ACL entries + await deleteUserPluginAuth(user.id, null, true); + await db.deleteUserById(user.id); + await db.deleteAllSharedLinks(user.id); + await deleteUserFiles(req); + await db.deleteFiles(null, user.id); + await db.deleteToolCalls(user.id); + await db.deleteUserAgents(user.id); + await db.deleteAllAgentApiKeys(user._id); + await db.deleteAssistants({ user: user.id }); + await db.deleteConversationTags({ user: user.id }); + await db.deleteAllUserMemories(user.id); + await db.deleteUserPrompts(user.id); + await deleteUserMcpServers(user.id); + await db.deleteActions({ user: user.id }); + await db.deleteTokens({ userId: user.id }); + await db.removeUserFromAllGroups(user.id); + await db.deleteAclEntries({ principalId: user._id }); logger.info(`User deleted account. Email: ${user.email} ID: ${user.id}`); res.status(200).send({ message: 'User deleted' }); } catch (err) { @@ -331,7 +397,7 @@ const maybeUninstallOAuthMCP = async (userId, pluginKey, appConfig) => { const clientTokenData = await MCPTokenStorage.getClientInfoAndMetadata({ userId, serverName, - findToken, + findToken: db.findToken, }); if (clientTokenData == null) { return; @@ -342,7 +408,7 @@ const maybeUninstallOAuthMCP = async (userId, pluginKey, appConfig) => { const tokens = await MCPTokenStorage.getTokens({ userId, serverName, - findToken, + findToken: db.findToken, }); // 3. revoke OAuth tokens at the provider @@ -352,6 +418,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 +434,7 @@ const maybeUninstallOAuthMCP = async (userId, pluginKey, appConfig) => { revocationEndpointAuthMethodsSupported, }, oauthHeaders, + allowedDomains, ); } catch (error) { logger.error(`Error revoking OAuth access token for ${serverName}:`, error); @@ -387,6 +455,7 @@ const maybeUninstallOAuthMCP = async (userId, pluginKey, appConfig) => { revocationEndpointAuthMethodsSupported, }, oauthHeaders, + allowedDomains, ); } catch (error) { logger.error(`Error revoking OAuth refresh token for ${serverName}:`, error); @@ -398,7 +467,7 @@ const maybeUninstallOAuthMCP = async (userId, pluginKey, appConfig) => { userId, serverName, deleteToken: async (filter) => { - await Token.deleteOne(filter); + await db.deleteTokens(filter); }, }); @@ -418,4 +487,5 @@ module.exports = { verifyEmailController, updateUserPluginsController, resendVerificationController, + deleteUserMcpServers, }; diff --git a/api/server/controllers/UserController.spec.js b/api/server/controllers/UserController.spec.js new file mode 100644 index 0000000000..4a96072062 --- /dev/null +++ b/api/server/controllers/UserController.spec.js @@ -0,0 +1,225 @@ +const mongoose = require('mongoose'); +const { MongoMemoryServer } = require('mongodb-memory-server'); + +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(), + }, + }; +}); + +jest.mock('~/models', () => { + const _mongoose = require('mongoose'); + return { + deleteAllUserSessions: jest.fn().mockResolvedValue(undefined), + deleteAllSharedLinks: jest.fn().mockResolvedValue(undefined), + deleteAllAgentApiKeys: jest.fn().mockResolvedValue(undefined), + deleteConversationTags: jest.fn().mockResolvedValue(undefined), + deleteAllUserMemories: jest.fn().mockResolvedValue(undefined), + deleteTransactions: jest.fn().mockResolvedValue(undefined), + deleteAclEntries: jest.fn().mockResolvedValue(undefined), + updateUserPlugins: jest.fn(), + deleteAssistants: jest.fn().mockResolvedValue(undefined), + deleteUserById: jest.fn().mockResolvedValue(undefined), + deleteUserPrompts: jest.fn().mockResolvedValue(undefined), + deleteMessages: jest.fn().mockResolvedValue(undefined), + deleteBalances: jest.fn().mockResolvedValue(undefined), + deleteActions: jest.fn().mockResolvedValue(undefined), + deletePresets: jest.fn().mockResolvedValue(undefined), + deleteUserKey: jest.fn().mockResolvedValue(undefined), + deleteToolCalls: jest.fn().mockResolvedValue(undefined), + deleteUserAgents: jest.fn().mockResolvedValue(undefined), + deleteTokens: jest.fn().mockResolvedValue(undefined), + deleteConvos: jest.fn().mockResolvedValue(undefined), + deleteFiles: jest.fn().mockResolvedValue(undefined), + updateUser: jest.fn(), + getUserById: jest.fn().mockResolvedValue(null), + findToken: jest.fn(), + getFiles: jest.fn().mockResolvedValue([]), + removeUserFromAllGroups: jest.fn().mockImplementation(async (userId) => { + const Group = _mongoose.models.Group; + await Group.updateMany({ memberIds: userId }, { $pullAll: { memberIds: [userId] } }); + }), + }; +}); + +jest.mock('~/server/services/PluginService', () => ({ + updateUserPluginAuth: jest.fn(), + deleteUserPluginAuth: jest.fn().mockResolvedValue(undefined), +})); + +jest.mock('~/server/services/AuthService', () => ({ + verifyEmail: jest.fn(), + resendVerificationEmail: jest.fn(), +})); + +jest.mock('sharp', () => + jest.fn(() => ({ + metadata: jest.fn().mockResolvedValue({}), + toFormat: jest.fn().mockReturnThis(), + toBuffer: jest.fn().mockResolvedValue(Buffer.alloc(0)), + })), +); + +jest.mock('@librechat/api', () => ({ + ...jest.requireActual('@librechat/api'), + needsRefresh: jest.fn(), + getNewS3URL: jest.fn(), +})); + +jest.mock('~/server/services/Files/process', () => ({ + processDeleteRequest: jest.fn().mockResolvedValue(undefined), +})); + +jest.mock('~/server/services/Config', () => ({ + getAppConfig: jest.fn().mockResolvedValue({}), + getMCPManager: jest.fn(), + getFlowStateManager: jest.fn(), + getMCPServersRegistry: jest.fn(), +})); + +jest.mock('~/cache', () => ({ + getLogStores: jest.fn(), +})); + +let mongoServer; + +beforeAll(async () => { + mongoServer = await MongoMemoryServer.create(); + await mongoose.connect(mongoServer.getUri()); +}); + +afterAll(async () => { + await mongoose.disconnect(); + await mongoServer.stop(); +}); + +afterEach(async () => { + const collections = mongoose.connection.collections; + for (const key in collections) { + await collections[key].deleteMany({}); + } +}); + +const { deleteUserController } = require('./UserController'); +const { Group } = require('~/db/models'); +const { deleteConvos } = require('~/models'); + +describe('deleteUserController', () => { + const mockRes = { + status: jest.fn().mockReturnThis(), + send: jest.fn().mockReturnThis(), + json: jest.fn().mockReturnThis(), + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should return 200 on successful deletion', async () => { + const userId = new mongoose.Types.ObjectId(); + const req = { user: { id: userId.toString(), _id: userId, email: 'test@test.com' } }; + + await deleteUserController(req, mockRes); + + expect(mockRes.status).toHaveBeenCalledWith(200); + expect(mockRes.send).toHaveBeenCalledWith({ message: 'User deleted' }); + }); + + it('should remove the user from all groups via $pullAll', async () => { + const userId = new mongoose.Types.ObjectId(); + const userIdStr = userId.toString(); + const otherUser = new mongoose.Types.ObjectId().toString(); + + await Group.create([ + { name: 'Group A', memberIds: [userIdStr, otherUser], source: 'local' }, + { name: 'Group B', memberIds: [userIdStr], source: 'local' }, + { name: 'Group C', memberIds: [otherUser], source: 'local' }, + ]); + + const req = { user: { id: userIdStr, _id: userId, email: 'del@test.com' } }; + await deleteUserController(req, mockRes); + + const groups = await Group.find({}).sort({ name: 1 }).lean(); + expect(groups[0].memberIds).toEqual([otherUser]); + expect(groups[1].memberIds).toEqual([]); + expect(groups[2].memberIds).toEqual([otherUser]); + }); + + it('should handle user that exists in no groups', async () => { + const userId = new mongoose.Types.ObjectId(); + await Group.create({ name: 'Empty', memberIds: ['someone-else'], source: 'local' }); + + const req = { user: { id: userId.toString(), _id: userId, email: 'no-groups@test.com' } }; + await deleteUserController(req, mockRes); + + expect(mockRes.status).toHaveBeenCalledWith(200); + const group = await Group.findOne({ name: 'Empty' }).lean(); + expect(group.memberIds).toEqual(['someone-else']); + }); + + it('should remove duplicate memberIds if the user appears more than once', async () => { + const userId = new mongoose.Types.ObjectId(); + const userIdStr = userId.toString(); + + await Group.create({ + name: 'Dupes', + memberIds: [userIdStr, 'other', userIdStr], + source: 'local', + }); + + const req = { user: { id: userIdStr, _id: userId, email: 'dupe@test.com' } }; + await deleteUserController(req, mockRes); + + const group = await Group.findOne({ name: 'Dupes' }).lean(); + expect(group.memberIds).toEqual(['other']); + }); + + it('should still succeed when deleteConvos throws', async () => { + const userId = new mongoose.Types.ObjectId(); + deleteConvos.mockRejectedValueOnce(new Error('no convos')); + + const req = { user: { id: userId.toString(), _id: userId, email: 'convos@test.com' } }; + await deleteUserController(req, mockRes); + + expect(mockRes.status).toHaveBeenCalledWith(200); + expect(mockRes.send).toHaveBeenCalledWith({ message: 'User deleted' }); + }); + + it('should return 500 when a critical operation fails', async () => { + const userId = new mongoose.Types.ObjectId(); + const { deleteMessages } = require('~/models'); + deleteMessages.mockRejectedValueOnce(new Error('db down')); + + const req = { user: { id: userId.toString(), _id: userId, email: 'fail@test.com' } }; + await deleteUserController(req, mockRes); + + expect(mockRes.status).toHaveBeenCalledWith(500); + expect(mockRes.json).toHaveBeenCalledWith({ message: 'Something went wrong.' }); + }); + + it('should use string user.id (not ObjectId user._id) for memberIds removal', async () => { + const userId = new mongoose.Types.ObjectId(); + const userIdStr = userId.toString(); + const otherUser = 'other-user-id'; + + await Group.create({ + name: 'StringCheck', + memberIds: [userIdStr, otherUser], + source: 'local', + }); + + const req = { user: { id: userIdStr, _id: userId, email: 'stringcheck@test.com' } }; + await deleteUserController(req, mockRes); + + const group = await Group.findOne({ name: 'StringCheck' }).lean(); + expect(group.memberIds).toEqual([otherUser]); + expect(group.memberIds).not.toContain(userIdStr); + }); +}); diff --git a/api/server/controllers/__tests__/PermissionsController.spec.js b/api/server/controllers/__tests__/PermissionsController.spec.js new file mode 100644 index 0000000000..a8d9518455 --- /dev/null +++ b/api/server/controllers/__tests__/PermissionsController.spec.js @@ -0,0 +1,242 @@ +const mongoose = require('mongoose'); + +const mockLogger = { error: jest.fn(), warn: jest.fn(), info: jest.fn(), debug: jest.fn() }; + +jest.mock('@librechat/data-schemas', () => ({ + logger: mockLogger, +})); + +const { ResourceType, PrincipalType } = jest.requireActual('librechat-data-provider'); + +jest.mock('librechat-data-provider', () => ({ + ...jest.requireActual('librechat-data-provider'), +})); + +jest.mock('@librechat/api', () => ({ + enrichRemoteAgentPrincipals: jest.fn(), + backfillRemoteAgentPermissions: jest.fn(), +})); + +const mockBulkUpdateResourcePermissions = jest.fn(); + +jest.mock('~/server/services/PermissionService', () => ({ + bulkUpdateResourcePermissions: (...args) => mockBulkUpdateResourcePermissions(...args), + ensureGroupPrincipalExists: jest.fn(), + getEffectivePermissions: jest.fn(), + ensurePrincipalExists: jest.fn(), + getAvailableRoles: jest.fn(), + findAccessibleResources: jest.fn(), + getResourcePermissionsMap: jest.fn(), +})); + +const mockRemoveAgentFromUserFavorites = jest.fn(); + +jest.mock('~/models', () => ({ + searchPrincipals: jest.fn(), + sortPrincipalsByRelevance: jest.fn(), + calculateRelevanceScore: jest.fn(), + removeAgentFromUserFavorites: (...args) => mockRemoveAgentFromUserFavorites(...args), +})); + +jest.mock('~/server/services/GraphApiService', () => ({ + entraIdPrincipalFeatureEnabled: jest.fn(() => false), + searchEntraIdPrincipals: jest.fn(), +})); + +const { updateResourcePermissions } = require('../PermissionsController'); + +const createMockReq = (overrides = {}) => ({ + params: { resourceType: ResourceType.AGENT, resourceId: '507f1f77bcf86cd799439011' }, + body: { updated: [], removed: [], public: false }, + user: { id: 'user-1', role: 'USER' }, + headers: { authorization: '' }, + ...overrides, +}); + +const createMockRes = () => { + const res = {}; + res.status = jest.fn().mockReturnValue(res); + res.json = jest.fn().mockReturnValue(res); + return res; +}; + +const flushPromises = () => new Promise((resolve) => setImmediate(resolve)); + +describe('PermissionsController', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('updateResourcePermissions — favorites cleanup', () => { + const agentObjectId = new mongoose.Types.ObjectId().toString(); + const revokedUserId = new mongoose.Types.ObjectId().toString(); + + beforeEach(() => { + mockBulkUpdateResourcePermissions.mockResolvedValue({ + granted: [], + updated: [], + revoked: [{ type: PrincipalType.USER, id: revokedUserId, name: 'Revoked User' }], + errors: [], + }); + + mockRemoveAgentFromUserFavorites.mockResolvedValue(undefined); + }); + + it('removes agent from revoked users favorites on AGENT resource type', async () => { + const req = createMockReq({ + params: { resourceType: ResourceType.AGENT, resourceId: agentObjectId }, + body: { + updated: [], + removed: [{ type: PrincipalType.USER, id: revokedUserId }], + public: false, + }, + }); + const res = createMockRes(); + + await updateResourcePermissions(req, res); + await flushPromises(); + + expect(res.status).toHaveBeenCalledWith(200); + expect(mockRemoveAgentFromUserFavorites).toHaveBeenCalledWith(agentObjectId, [revokedUserId]); + }); + + it('removes agent from revoked users favorites on REMOTE_AGENT resource type', async () => { + const req = createMockReq({ + params: { resourceType: ResourceType.REMOTE_AGENT, resourceId: agentObjectId }, + body: { + updated: [], + removed: [{ type: PrincipalType.USER, id: revokedUserId }], + public: false, + }, + }); + const res = createMockRes(); + + await updateResourcePermissions(req, res); + await flushPromises(); + + expect(mockRemoveAgentFromUserFavorites).toHaveBeenCalledWith(agentObjectId, [revokedUserId]); + }); + + it('uses results.revoked (validated) not raw request payload', async () => { + const validId = new mongoose.Types.ObjectId().toString(); + const invalidId = 'not-a-valid-id'; + + mockBulkUpdateResourcePermissions.mockResolvedValue({ + granted: [], + updated: [], + revoked: [{ type: PrincipalType.USER, id: validId }], + errors: [{ principal: { type: PrincipalType.USER, id: invalidId }, error: 'Invalid ID' }], + }); + + const req = createMockReq({ + params: { resourceType: ResourceType.AGENT, resourceId: agentObjectId }, + body: { + updated: [], + removed: [ + { type: PrincipalType.USER, id: validId }, + { type: PrincipalType.USER, id: invalidId }, + ], + public: false, + }, + }); + const res = createMockRes(); + + await updateResourcePermissions(req, res); + await flushPromises(); + + expect(mockRemoveAgentFromUserFavorites).toHaveBeenCalledWith(agentObjectId, [validId]); + }); + + it('skips cleanup when no USER principals are revoked', async () => { + mockBulkUpdateResourcePermissions.mockResolvedValue({ + granted: [], + updated: [], + revoked: [{ type: PrincipalType.GROUP, id: 'group-1' }], + errors: [], + }); + + const req = createMockReq({ + params: { resourceType: ResourceType.AGENT, resourceId: agentObjectId }, + body: { + updated: [], + removed: [{ type: PrincipalType.GROUP, id: 'group-1' }], + public: false, + }, + }); + const res = createMockRes(); + + await updateResourcePermissions(req, res); + await flushPromises(); + + expect(mockRemoveAgentFromUserFavorites).not.toHaveBeenCalled(); + }); + + it('skips cleanup for non-agent resource types', async () => { + mockBulkUpdateResourcePermissions.mockResolvedValue({ + granted: [], + updated: [], + revoked: [{ type: PrincipalType.USER, id: revokedUserId }], + errors: [], + }); + + const req = createMockReq({ + params: { resourceType: ResourceType.PROMPTGROUP, resourceId: agentObjectId }, + body: { + updated: [], + removed: [{ type: PrincipalType.USER, id: revokedUserId }], + public: false, + }, + }); + const res = createMockRes(); + + await updateResourcePermissions(req, res); + await flushPromises(); + + expect(res.status).toHaveBeenCalledWith(200); + expect(mockRemoveAgentFromUserFavorites).not.toHaveBeenCalled(); + }); + + it('handles agent not found gracefully', async () => { + mockRemoveAgentFromUserFavorites.mockResolvedValue(undefined); + + const req = createMockReq({ + params: { resourceType: ResourceType.AGENT, resourceId: agentObjectId }, + body: { + updated: [], + removed: [{ type: PrincipalType.USER, id: revokedUserId }], + public: false, + }, + }); + const res = createMockRes(); + + await updateResourcePermissions(req, res); + await flushPromises(); + + expect(mockRemoveAgentFromUserFavorites).toHaveBeenCalled(); + expect(res.status).toHaveBeenCalledWith(200); + }); + + it('logs error when removeAgentFromUserFavorites fails without blocking response', async () => { + mockRemoveAgentFromUserFavorites.mockRejectedValue(new Error('DB connection lost')); + + const req = createMockReq({ + params: { resourceType: ResourceType.AGENT, resourceId: agentObjectId }, + body: { + updated: [], + removed: [{ type: PrincipalType.USER, id: revokedUserId }], + public: false, + }, + }); + const res = createMockRes(); + + await updateResourcePermissions(req, res); + await flushPromises(); + + expect(res.status).toHaveBeenCalledWith(200); + expect(mockLogger.error).toHaveBeenCalledWith( + '[removeRevokedAgentFromFavorites] Error cleaning up favorites', + expect.any(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..a382a6cdc7 --- /dev/null +++ b/api/server/controllers/__tests__/deleteUser.spec.js @@ -0,0 +1,287 @@ +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(), + needsRefresh: jest.fn(), + getNewS3URL: 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), + deleteToolCalls: (...args) => mockDeleteToolCalls(...args), + deleteUserAgents: (...args) => mockDeleteUserAgents(...args), + deleteUserPrompts: (...args) => mockDeleteUserPrompts(...args), + deleteTransactions: jest.fn(), + deleteBalances: jest.fn(), + deleteAllAgentApiKeys: jest.fn(), + deleteAssistants: jest.fn(), + deleteConversationTags: jest.fn(), + deleteAllUserMemories: jest.fn(), + deleteActions: jest.fn(), + deleteTokens: jest.fn(), + removeUserFromAllGroups: jest.fn(), + deleteAclEntries: jest.fn(), + getSoleOwnedResourceIds: jest.fn().mockResolvedValue([]), +})); + +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/process', () => ({ + processDeleteRequest: (...args) => mockProcessDeleteRequest(...args), +})); + +jest.mock('~/server/services/Config', () => ({ + getAppConfig: jest.fn(), +})); + +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/__tests__/deleteUserMcpServers.spec.js b/api/server/controllers/__tests__/deleteUserMcpServers.spec.js new file mode 100644 index 0000000000..fcb3211f24 --- /dev/null +++ b/api/server/controllers/__tests__/deleteUserMcpServers.spec.js @@ -0,0 +1,319 @@ +const mockGetMCPManager = jest.fn(); +const mockInvalidateCachedTools = jest.fn(); + +jest.mock('~/config', () => ({ + getMCPManager: (...args) => mockGetMCPManager(...args), + getFlowStateManager: jest.fn(), + getMCPServersRegistry: jest.fn(), +})); + +jest.mock('~/server/services/Config/getCachedTools', () => ({ + invalidateCachedTools: (...args) => mockInvalidateCachedTools(...args), +})); + +jest.mock('~/server/services/Config', () => ({ + getAppConfig: jest.fn(), + getMCPServerTools: jest.fn(), +})); + +const mongoose = require('mongoose'); +const { mcpServerSchema } = require('@librechat/data-schemas'); +const { MongoMemoryServer } = require('mongodb-memory-server'); +const { + ResourceType, + AccessRoleIds, + PrincipalType, + PermissionBits, +} = require('librechat-data-provider'); +const permissionService = require('~/server/services/PermissionService'); +const { deleteUserMcpServers } = require('~/server/controllers/UserController'); +const { AclEntry, AccessRole } = require('~/db/models'); + +let MCPServer; + +describe('deleteUserMcpServers', () => { + let mongoServer; + + beforeAll(async () => { + mongoServer = await MongoMemoryServer.create(); + const mongoUri = mongoServer.getUri(); + MCPServer = mongoose.models.MCPServer || mongoose.model('MCPServer', mcpServerSchema); + await mongoose.connect(mongoUri); + + await AccessRole.create({ + accessRoleId: AccessRoleIds.MCPSERVER_OWNER, + name: 'MCP Server Owner', + resourceType: ResourceType.MCPSERVER, + permBits: + PermissionBits.VIEW | PermissionBits.EDIT | PermissionBits.DELETE | PermissionBits.SHARE, + }); + + await AccessRole.create({ + accessRoleId: AccessRoleIds.MCPSERVER_VIEWER, + name: 'MCP Server Viewer', + resourceType: ResourceType.MCPSERVER, + permBits: PermissionBits.VIEW, + }); + }, 20000); + + afterAll(async () => { + await mongoose.disconnect(); + await mongoServer.stop(); + }); + + beforeEach(async () => { + await MCPServer.deleteMany({}); + await AclEntry.deleteMany({}); + jest.clearAllMocks(); + }); + + test('should delete solely-owned MCP servers and their ACL entries', async () => { + const userId = new mongoose.Types.ObjectId(); + + const server = await MCPServer.create({ + serverName: 'sole-owned-server', + config: { title: 'Test Server' }, + author: userId, + }); + + await permissionService.grantPermission({ + principalType: PrincipalType.USER, + principalId: userId, + resourceType: ResourceType.MCPSERVER, + resourceId: server._id, + accessRoleId: AccessRoleIds.MCPSERVER_OWNER, + grantedBy: userId, + }); + + mockGetMCPManager.mockReturnValue({ + disconnectUserConnection: jest.fn().mockResolvedValue(undefined), + }); + + await deleteUserMcpServers(userId.toString()); + + expect(await MCPServer.findById(server._id)).toBeNull(); + + const aclEntries = await AclEntry.find({ + resourceType: ResourceType.MCPSERVER, + resourceId: server._id, + }); + expect(aclEntries).toHaveLength(0); + }); + + test('should disconnect MCP sessions and invalidate tool cache before deletion', async () => { + const userId = new mongoose.Types.ObjectId(); + const mockDisconnect = jest.fn().mockResolvedValue(undefined); + + const server = await MCPServer.create({ + serverName: 'session-server', + config: { title: 'Session Server' }, + author: userId, + }); + + await permissionService.grantPermission({ + principalType: PrincipalType.USER, + principalId: userId, + resourceType: ResourceType.MCPSERVER, + resourceId: server._id, + accessRoleId: AccessRoleIds.MCPSERVER_OWNER, + grantedBy: userId, + }); + + mockGetMCPManager.mockReturnValue({ disconnectUserConnection: mockDisconnect }); + + await deleteUserMcpServers(userId.toString()); + + expect(mockDisconnect).toHaveBeenCalledWith(userId.toString(), 'session-server'); + expect(mockInvalidateCachedTools).toHaveBeenCalledWith({ + userId: userId.toString(), + serverName: 'session-server', + }); + }); + + test('should preserve multi-owned MCP servers', async () => { + const deletingUserId = new mongoose.Types.ObjectId(); + const otherOwnerId = new mongoose.Types.ObjectId(); + + const soleServer = await MCPServer.create({ + serverName: 'sole-server', + config: { title: 'Sole Server' }, + author: deletingUserId, + }); + + const multiServer = await MCPServer.create({ + serverName: 'multi-server', + config: { title: 'Multi Server' }, + author: deletingUserId, + }); + + await permissionService.grantPermission({ + principalType: PrincipalType.USER, + principalId: deletingUserId, + resourceType: ResourceType.MCPSERVER, + resourceId: soleServer._id, + accessRoleId: AccessRoleIds.MCPSERVER_OWNER, + grantedBy: deletingUserId, + }); + + await permissionService.grantPermission({ + principalType: PrincipalType.USER, + principalId: deletingUserId, + resourceType: ResourceType.MCPSERVER, + resourceId: multiServer._id, + accessRoleId: AccessRoleIds.MCPSERVER_OWNER, + grantedBy: deletingUserId, + }); + await permissionService.grantPermission({ + principalType: PrincipalType.USER, + principalId: otherOwnerId, + resourceType: ResourceType.MCPSERVER, + resourceId: multiServer._id, + accessRoleId: AccessRoleIds.MCPSERVER_OWNER, + grantedBy: otherOwnerId, + }); + + mockGetMCPManager.mockReturnValue({ + disconnectUserConnection: jest.fn().mockResolvedValue(undefined), + }); + + await deleteUserMcpServers(deletingUserId.toString()); + + expect(await MCPServer.findById(soleServer._id)).toBeNull(); + expect(await MCPServer.findById(multiServer._id)).not.toBeNull(); + + const soleAcl = await AclEntry.find({ + resourceType: ResourceType.MCPSERVER, + resourceId: soleServer._id, + }); + expect(soleAcl).toHaveLength(0); + + const multiAclOther = await AclEntry.find({ + resourceType: ResourceType.MCPSERVER, + resourceId: multiServer._id, + principalId: otherOwnerId, + }); + expect(multiAclOther).toHaveLength(1); + expect(multiAclOther[0].permBits & PermissionBits.DELETE).toBeTruthy(); + + const multiAclDeleting = await AclEntry.find({ + resourceType: ResourceType.MCPSERVER, + resourceId: multiServer._id, + principalId: deletingUserId, + }); + expect(multiAclDeleting).toHaveLength(1); + }); + + test('should be a no-op when user has no owned MCP servers', async () => { + const userId = new mongoose.Types.ObjectId(); + + const otherUserId = new mongoose.Types.ObjectId(); + const server = await MCPServer.create({ + serverName: 'other-server', + config: { title: 'Other Server' }, + author: otherUserId, + }); + + await permissionService.grantPermission({ + principalType: PrincipalType.USER, + principalId: otherUserId, + resourceType: ResourceType.MCPSERVER, + resourceId: server._id, + accessRoleId: AccessRoleIds.MCPSERVER_OWNER, + grantedBy: otherUserId, + }); + + await deleteUserMcpServers(userId.toString()); + + expect(await MCPServer.findById(server._id)).not.toBeNull(); + expect(mockGetMCPManager).not.toHaveBeenCalled(); + }); + + test('should handle gracefully when MCPServer model is not registered', async () => { + const originalModel = mongoose.models.MCPServer; + delete mongoose.models.MCPServer; + + try { + const userId = new mongoose.Types.ObjectId(); + await expect(deleteUserMcpServers(userId.toString())).resolves.toBeUndefined(); + } finally { + mongoose.models.MCPServer = originalModel; + } + }); + + test('should handle gracefully when MCPManager is not available', async () => { + const userId = new mongoose.Types.ObjectId(); + + const server = await MCPServer.create({ + serverName: 'no-manager-server', + config: { title: 'No Manager Server' }, + author: userId, + }); + + await permissionService.grantPermission({ + principalType: PrincipalType.USER, + principalId: userId, + resourceType: ResourceType.MCPSERVER, + resourceId: server._id, + accessRoleId: AccessRoleIds.MCPSERVER_OWNER, + grantedBy: userId, + }); + + mockGetMCPManager.mockReturnValue(null); + + await deleteUserMcpServers(userId.toString()); + + expect(await MCPServer.findById(server._id)).toBeNull(); + }); + + test('should delete legacy MCP servers that have author but no ACL entries', async () => { + const legacyUserId = new mongoose.Types.ObjectId(); + + const legacyServer = await MCPServer.create({ + serverName: 'legacy-server', + config: { title: 'Legacy Server' }, + author: legacyUserId, + }); + + mockGetMCPManager.mockReturnValue({ + disconnectUserConnection: jest.fn().mockResolvedValue(undefined), + }); + + await deleteUserMcpServers(legacyUserId.toString()); + + expect(await MCPServer.findById(legacyServer._id)).toBeNull(); + }); + + test('should delete both ACL-owned and legacy servers in one call', async () => { + const userId = new mongoose.Types.ObjectId(); + + const aclServer = await MCPServer.create({ + serverName: 'acl-server', + config: { title: 'ACL Server' }, + author: userId, + }); + + await permissionService.grantPermission({ + principalType: PrincipalType.USER, + principalId: userId, + resourceType: ResourceType.MCPSERVER, + resourceId: aclServer._id, + accessRoleId: AccessRoleIds.MCPSERVER_OWNER, + grantedBy: userId, + }); + + const legacyServer = await MCPServer.create({ + serverName: 'legacy-mixed-server', + config: { title: 'Legacy Mixed' }, + author: userId, + }); + + mockGetMCPManager.mockReturnValue({ + disconnectUserConnection: jest.fn().mockResolvedValue(undefined), + }); + + await deleteUserMcpServers(userId.toString()); + + expect(await MCPServer.findById(aclServer._id)).toBeNull(); + expect(await MCPServer.findById(legacyServer._id)).toBeNull(); + }); +}); diff --git a/api/server/controllers/__tests__/deleteUserResourceCoverage.spec.js b/api/server/controllers/__tests__/deleteUserResourceCoverage.spec.js new file mode 100644 index 0000000000..b08e502800 --- /dev/null +++ b/api/server/controllers/__tests__/deleteUserResourceCoverage.spec.js @@ -0,0 +1,53 @@ +const fs = require('fs'); +const path = require('path'); +const { ResourceType } = require('librechat-data-provider'); + +/** + * Maps each ResourceType to the cleanup function name that must appear in + * deleteUserController's source to prove it is handled during user deletion. + * + * When a new ResourceType is added, this test will fail until a corresponding + * entry is added here (or to NO_USER_CLEANUP_NEEDED) AND the actual cleanup + * logic is implemented. + */ +const HANDLED_RESOURCE_TYPES = { + [ResourceType.AGENT]: 'deleteUserAgents', + [ResourceType.REMOTE_AGENT]: 'deleteUserAgents', + [ResourceType.PROMPTGROUP]: 'deleteUserPrompts', + [ResourceType.MCPSERVER]: 'deleteUserMcpServers', +}; + +/** + * ResourceTypes that are ACL-tracked but have no per-user deletion semantics + * (e.g., system resources, public-only). Must be explicitly listed here with + * a justification to prevent silent omissions. + */ +const NO_USER_CLEANUP_NEEDED = new Set([ + // Example: ResourceType.SYSTEM_TEMPLATE — public/system; not user-owned +]); + +describe('deleteUserController - resource type coverage guard', () => { + let controllerSource; + + beforeAll(() => { + controllerSource = fs.readFileSync(path.resolve(__dirname, '../UserController.js'), 'utf-8'); + }); + + test('every ResourceType must have a documented cleanup handler or explicit exclusion', () => { + const allTypes = Object.values(ResourceType); + const handledTypes = Object.keys(HANDLED_RESOURCE_TYPES); + const unhandledTypes = allTypes.filter( + (t) => !handledTypes.includes(t) && !NO_USER_CLEANUP_NEEDED.has(t), + ); + + expect(unhandledTypes).toEqual([]); + }); + + test('every cleanup handler referenced in HANDLED_RESOURCE_TYPES must appear in the controller source', () => { + const uniqueHandlers = [...new Set(Object.values(HANDLED_RESOURCE_TYPES))]; + + for (const handler of uniqueHandlers) { + expect(controllerSource).toContain(handler); + } + }); +}); diff --git a/api/server/controllers/agents/__tests__/openai.spec.js b/api/server/controllers/agents/__tests__/openai.spec.js index 835343e798..c2f13f7837 100644 --- a/api/server/controllers/agents/__tests__/openai.spec.js +++ b/api/server/controllers/agents/__tests__/openai.spec.js @@ -77,42 +77,25 @@ jest.mock('~/server/services/ToolService', () => ({ loadToolsForExecution: jest.fn().mockResolvedValue([]), })); -jest.mock('~/models/spendTokens', () => ({ - spendTokens: mockSpendTokens, - 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()), + buildSummarizationHandlers: jest.fn().mockReturnValue({}), + markSummarizationUsage: jest.fn().mockImplementation((usage) => usage), + agentLogHandlerObj: { handle: jest.fn() }, })); jest.mock('~/server/services/PermissionService', () => ({ findAccessibleResources: jest.fn().mockResolvedValue([]), })); -jest.mock('~/models/Conversation', () => ({ - getConvoFiles: jest.fn().mockResolvedValue([]), -})); - -jest.mock('~/models/Agent', () => ({ - getAgent: jest.fn().mockResolvedValue({ - id: 'agent-123', - provider: 'openAI', - model_parameters: { model: 'gpt-4' }, - }), - getAgents: jest.fn().mockResolvedValue([]), -})); - const mockUpdateBalance = jest.fn().mockResolvedValue({}); const mockBulkInsertTransactions = jest.fn().mockResolvedValue(undefined); + jest.mock('~/models', () => ({ + getAgent: jest.fn().mockResolvedValue({ id: 'agent-123', name: 'Test Agent' }), getFiles: jest.fn(), getUserKey: jest.fn(), getMessages: jest.fn(), @@ -123,6 +106,12 @@ jest.mock('~/models', () => ({ getCodeGeneratedFiles: jest.fn(), updateBalance: mockUpdateBalance, bulkInsertTransactions: mockBulkInsertTransactions, + spendTokens: mockSpendTokens, + spendStructuredTokens: mockSpendStructuredTokens, + getMultiplier: mockGetMultiplier, + getCacheMultiplier: mockGetCacheMultiplier, + getConvoFiles: jest.fn().mockResolvedValue([]), + getConvo: jest.fn().mockResolvedValue(null), })); describe('OpenAIChatCompletionController', () => { @@ -160,6 +149,77 @@ describe('OpenAIChatCompletionController', () => { }; }); + describe('conversation ownership validation', () => { + it('should skip ownership check when conversation_id is not provided', async () => { + const { getConvo } = require('~/models'); + await OpenAIChatCompletionController(req, res); + expect(getConvo).not.toHaveBeenCalled(); + }); + + it('should return 400 when conversation_id is not a string', async () => { + const { validateRequest } = require('@librechat/api'); + validateRequest.mockReturnValueOnce({ + request: { model: 'agent-123', messages: [], stream: false, conversation_id: { $gt: '' } }, + }); + + await OpenAIChatCompletionController(req, res); + expect(res.status).toHaveBeenCalledWith(400); + }); + + it('should return 404 when conversation is not owned by user', async () => { + const { validateRequest } = require('@librechat/api'); + const { getConvo } = require('~/models'); + validateRequest.mockReturnValueOnce({ + request: { + model: 'agent-123', + messages: [], + stream: false, + conversation_id: 'convo-abc', + }, + }); + getConvo.mockResolvedValueOnce(null); + + await OpenAIChatCompletionController(req, res); + expect(getConvo).toHaveBeenCalledWith('user-123', 'convo-abc'); + expect(res.status).toHaveBeenCalledWith(404); + }); + + it('should proceed when conversation is owned by user', async () => { + const { validateRequest } = require('@librechat/api'); + const { getConvo } = require('~/models'); + validateRequest.mockReturnValueOnce({ + request: { + model: 'agent-123', + messages: [], + stream: false, + conversation_id: 'convo-abc', + }, + }); + getConvo.mockResolvedValueOnce({ conversationId: 'convo-abc', user: 'user-123' }); + + await OpenAIChatCompletionController(req, res); + expect(getConvo).toHaveBeenCalledWith('user-123', 'convo-abc'); + expect(res.status).not.toHaveBeenCalledWith(404); + }); + + it('should return 500 when getConvo throws a DB error', async () => { + const { validateRequest } = require('@librechat/api'); + const { getConvo } = require('~/models'); + validateRequest.mockReturnValueOnce({ + request: { + model: 'agent-123', + messages: [], + stream: false, + conversation_id: 'convo-abc', + }, + }); + getConvo.mockRejectedValueOnce(new Error('DB connection failed')); + + await OpenAIChatCompletionController(req, res); + expect(res.status).toHaveBeenCalledWith(500); + }); + }); + describe('token usage recording', () => { it('should call recordCollectedUsage after successful non-streaming completion', async () => { await OpenAIChatCompletionController(req, res); diff --git a/api/server/controllers/agents/__tests__/responses.unit.spec.js b/api/server/controllers/agents/__tests__/responses.unit.spec.js index 45ec31fc68..26f5f5d30b 100644 --- a/api/server/controllers/agents/__tests__/responses.unit.spec.js +++ b/api/server/controllers/agents/__tests__/responses.unit.spec.js @@ -101,46 +101,33 @@ jest.mock('~/server/services/ToolService', () => ({ loadToolsForExecution: jest.fn().mockResolvedValue([]), })); -jest.mock('~/models/spendTokens', () => ({ - spendTokens: mockSpendTokens, - 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()), -})); +jest.mock('~/server/controllers/agents/callbacks', () => { + const noop = { handle: jest.fn() }; + return { + createToolEndCallback: jest.fn().mockReturnValue(jest.fn()), + createResponsesToolEndCallback: jest.fn().mockReturnValue(jest.fn()), + markSummarizationUsage: jest.fn().mockImplementation((usage) => usage), + agentLogHandlerObj: noop, + buildSummarizationHandlers: jest.fn().mockReturnValue({ + on_summarize_start: noop, + on_summarize_delta: noop, + on_summarize_complete: noop, + }), + }; +}); jest.mock('~/server/services/PermissionService', () => ({ findAccessibleResources: jest.fn().mockResolvedValue([]), })); -jest.mock('~/models/Conversation', () => ({ - getConvoFiles: jest.fn().mockResolvedValue([]), - saveConvo: jest.fn().mockResolvedValue({}), - getConvo: jest.fn().mockResolvedValue(null), -})); - -jest.mock('~/models/Agent', () => ({ - getAgent: jest.fn().mockResolvedValue({ - id: 'agent-123', - name: 'Test Agent', - provider: 'anthropic', - model_parameters: { model: 'claude-3' }, - }), - getAgents: jest.fn().mockResolvedValue([]), -})); - const mockUpdateBalance = jest.fn().mockResolvedValue({}); const mockBulkInsertTransactions = jest.fn().mockResolvedValue(undefined); + jest.mock('~/models', () => ({ + getAgent: jest.fn().mockResolvedValue({ id: 'agent-123', name: 'Test Agent' }), getFiles: jest.fn(), getUserKey: jest.fn(), getMessages: jest.fn().mockResolvedValue([]), @@ -152,6 +139,13 @@ jest.mock('~/models', () => ({ getCodeGeneratedFiles: jest.fn(), updateBalance: mockUpdateBalance, bulkInsertTransactions: mockBulkInsertTransactions, + spendTokens: mockSpendTokens, + spendStructuredTokens: mockSpendStructuredTokens, + getMultiplier: mockGetMultiplier, + getCacheMultiplier: mockGetCacheMultiplier, + getConvoFiles: jest.fn().mockResolvedValue([]), + saveConvo: jest.fn().mockResolvedValue({}), + getConvo: jest.fn().mockResolvedValue(null), })); describe('createResponse controller', () => { @@ -189,6 +183,102 @@ describe('createResponse controller', () => { }; }); + describe('conversation ownership validation', () => { + it('should skip ownership check when previous_response_id is not provided', async () => { + const { getConvo } = require('~/models'); + await createResponse(req, res); + expect(getConvo).not.toHaveBeenCalled(); + }); + + it('should return 400 when previous_response_id is not a string', async () => { + const { validateResponseRequest, sendResponsesErrorResponse } = require('@librechat/api'); + validateResponseRequest.mockReturnValueOnce({ + request: { + model: 'agent-123', + input: 'Hello', + stream: false, + previous_response_id: { $gt: '' }, + }, + }); + + await createResponse(req, res); + expect(sendResponsesErrorResponse).toHaveBeenCalledWith( + res, + 400, + 'previous_response_id must be a string', + 'invalid_request', + ); + }); + + it('should return 404 when conversation is not owned by user', async () => { + const { validateResponseRequest, sendResponsesErrorResponse } = require('@librechat/api'); + const { getConvo } = require('~/models'); + validateResponseRequest.mockReturnValueOnce({ + request: { + model: 'agent-123', + input: 'Hello', + stream: false, + previous_response_id: 'resp_abc', + }, + }); + getConvo.mockResolvedValueOnce(null); + + await createResponse(req, res); + expect(getConvo).toHaveBeenCalledWith('user-123', 'resp_abc'); + expect(sendResponsesErrorResponse).toHaveBeenCalledWith( + res, + 404, + 'Conversation not found', + 'not_found', + ); + }); + + it('should proceed when conversation is owned by user', async () => { + const { validateResponseRequest, sendResponsesErrorResponse } = require('@librechat/api'); + const { getConvo } = require('~/models'); + validateResponseRequest.mockReturnValueOnce({ + request: { + model: 'agent-123', + input: 'Hello', + stream: false, + previous_response_id: 'resp_abc', + }, + }); + getConvo.mockResolvedValueOnce({ conversationId: 'resp_abc', user: 'user-123' }); + + await createResponse(req, res); + expect(getConvo).toHaveBeenCalledWith('user-123', 'resp_abc'); + expect(sendResponsesErrorResponse).not.toHaveBeenCalledWith( + res, + 404, + expect.any(String), + expect.any(String), + ); + }); + + it('should return 500 when getConvo throws a DB error', async () => { + const { validateResponseRequest, sendResponsesErrorResponse } = require('@librechat/api'); + const { getConvo } = require('~/models'); + validateResponseRequest.mockReturnValueOnce({ + request: { + model: 'agent-123', + input: 'Hello', + stream: false, + previous_response_id: 'resp_abc', + }, + }); + getConvo.mockRejectedValueOnce(new Error('DB connection failed')); + + await createResponse(req, res); + expect(sendResponsesErrorResponse).toHaveBeenCalledWith( + res, + 500, + expect.any(String), + expect.any(String), + ); + }); + }); + describe('token usage recording - non-streaming', () => { it('should call recordCollectedUsage after successful non-streaming completion', async () => { await createResponse(req, res); @@ -290,28 +380,7 @@ describe('createResponse controller', () => { it('should collect usage from on_chat_model_end events', async () => { const api = require('@librechat/api'); - let capturedOnChatModelEnd; - api.createAggregatorEventHandlers.mockImplementation(() => { - return { - on_message_delta: { handle: jest.fn() }, - on_reasoning_delta: { handle: jest.fn() }, - on_run_step: { handle: jest.fn() }, - on_run_step_delta: { handle: jest.fn() }, - on_chat_model_end: { - handle: jest.fn((event, data) => { - if (capturedOnChatModelEnd) { - capturedOnChatModelEnd(event, data); - } - }), - }, - }; - }); - api.createRun.mockImplementation(async ({ customHandlers }) => { - capturedOnChatModelEnd = (event, data) => { - customHandlers.on_chat_model_end.handle(event, data); - }; - return { processStream: jest.fn().mockImplementation(async () => { customHandlers.on_chat_model_end.handle('on_chat_model_end', { @@ -328,7 +397,6 @@ describe('createResponse controller', () => { }); await createResponse(req, res); - expect(mockRecordCollectedUsage).toHaveBeenCalledWith( expect.any(Object), expect.objectContaining({ 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/__tests__/v1.spec.js b/api/server/controllers/agents/__tests__/v1.spec.js index b7e7b67a22..39cf994fef 100644 --- a/api/server/controllers/agents/__tests__/v1.spec.js +++ b/api/server/controllers/agents/__tests__/v1.spec.js @@ -1,10 +1,8 @@ const { duplicateAgent } = require('../v1'); -const { getAgent, createAgent } = require('~/models/Agent'); -const { getActions } = require('~/models/Action'); +const { getAgent, createAgent, getActions } = require('~/models'); const { nanoid } = require('nanoid'); -jest.mock('~/models/Agent'); -jest.mock('~/models/Action'); +jest.mock('~/models'); jest.mock('nanoid'); describe('duplicateAgent', () => { diff --git a/api/server/controllers/agents/callbacks.js b/api/server/controllers/agents/callbacks.js index 0bb935795d..40fdf74212 100644 --- a/api/server/controllers/agents/callbacks.js +++ b/api/server/controllers/agents/callbacks.js @@ -1,7 +1,13 @@ const { nanoid } = require('nanoid'); const { logger } = require('@librechat/data-schemas'); -const { Constants, EnvVar, GraphEvents, ToolEndHandler } = require('@librechat/agents'); const { Tools, StepTypes, FileContext, ErrorTypes } = require('librechat-data-provider'); +const { + EnvVar, + Constants, + GraphEvents, + GraphNodeKeys, + ToolEndHandler, +} = require('@librechat/agents'); const { sendEvent, GenerationJobManager, @@ -71,7 +77,9 @@ class ModelEndHandler { usage.model = modelName; } - this.collectedUsage.push(usage); + const taggedUsage = markSummarizationUsage(usage, metadata); + + this.collectedUsage.push(taggedUsage); } catch (error) { logger.error('Error handling model end event:', error); return this.finalize(errorMessage); @@ -133,6 +141,7 @@ function getDefaultHandlers({ collectedUsage, streamId = null, toolExecuteOptions = null, + summarizationOptions = null, }) { if (!res || !aggregateContent) { throw new Error( @@ -245,6 +254,37 @@ function getDefaultHandlers({ handlers[GraphEvents.ON_TOOL_EXECUTE] = createToolExecuteHandler(toolExecuteOptions); } + if (summarizationOptions?.enabled !== false) { + handlers[GraphEvents.ON_SUMMARIZE_START] = { + handle: async (_event, data) => { + await emitEvent(res, streamId, { + event: GraphEvents.ON_SUMMARIZE_START, + data, + }); + }, + }; + handlers[GraphEvents.ON_SUMMARIZE_DELTA] = { + handle: async (_event, data) => { + aggregateContent({ event: GraphEvents.ON_SUMMARIZE_DELTA, data }); + await emitEvent(res, streamId, { + event: GraphEvents.ON_SUMMARIZE_DELTA, + data, + }); + }, + }; + handlers[GraphEvents.ON_SUMMARIZE_COMPLETE] = { + handle: async (_event, data) => { + aggregateContent({ event: GraphEvents.ON_SUMMARIZE_COMPLETE, data }); + await emitEvent(res, streamId, { + event: GraphEvents.ON_SUMMARIZE_COMPLETE, + data, + }); + }, + }; + } + + handlers[GraphEvents.ON_AGENT_LOG] = { handle: agentLogHandler }; + return handlers; } @@ -668,8 +708,62 @@ function createResponsesToolEndCallback({ req, res, tracker, artifactPromises }) }; } +const ALLOWED_LOG_LEVELS = new Set(['debug', 'info', 'warn', 'error']); + +function agentLogHandler(_event, data) { + if (!data) { + return; + } + const logFn = ALLOWED_LOG_LEVELS.has(data.level) ? logger[data.level] : logger.debug; + const meta = typeof data.data === 'object' && data.data != null ? data.data : {}; + logFn(`[agents:${data.scope ?? 'unknown'}] ${data.message ?? ''}`, { + ...meta, + runId: data.runId, + agentId: data.agentId, + }); +} + +function markSummarizationUsage(usage, metadata) { + const node = metadata?.langgraph_node; + if (typeof node === 'string' && node.startsWith(GraphNodeKeys.SUMMARIZE)) { + return { ...usage, usage_type: 'summarization' }; + } + return usage; +} + +const agentLogHandlerObj = { handle: agentLogHandler }; + +/** + * Builds the three summarization SSE event handlers. + * In streaming mode, each event is forwarded to the client via `res.write`. + * In non-streaming mode, the handlers are no-ops. + * @param {{ isStreaming: boolean, res: import('express').Response }} opts + */ +function buildSummarizationHandlers({ isStreaming, res }) { + if (!isStreaming) { + const noop = { handle: () => {} }; + return { on_summarize_start: noop, on_summarize_delta: noop, on_summarize_complete: noop }; + } + const writeEvent = (name) => ({ + handle: async (_event, data) => { + if (!res.writableEnded) { + res.write(`event: ${name}\ndata: ${JSON.stringify(data)}\n\n`); + } + }, + }); + return { + on_summarize_start: writeEvent('on_summarize_start'), + on_summarize_delta: writeEvent('on_summarize_delta'), + on_summarize_complete: writeEvent('on_summarize_complete'), + }; +} + module.exports = { + agentLogHandler, + agentLogHandlerObj, getDefaultHandlers, createToolEndCallback, + markSummarizationUsage, + buildSummarizationHandlers, createResponsesToolEndCallback, }; diff --git a/api/server/controllers/agents/client.js b/api/server/controllers/agents/client.js index 5f99a0762b..47a10165e3 100644 --- a/api/server/controllers/agents/client.js +++ b/api/server/controllers/agents/client.js @@ -3,11 +3,11 @@ const { logger } = require('@librechat/data-schemas'); const { getBufferString, HumanMessage } = require('@langchain/core/messages'); const { createRun, - Tokenizer, + isEnabled, checkAccess, buildToolSet, - sanitizeTitle, logToolError, + sanitizeTitle, payloadParser, resolveHeaders, createSafeUser, @@ -22,8 +22,11 @@ const { GenerationJobManager, getTransactionsConfig, createMemoryProcessor, + loadAgent: loadAgentFn, createMultiAgentMapper, filterMalformedContentParts, + countFormattedMessageTokens, + hydrateMissingIndexTokenCounts, } = require('@librechat/api'); const { Callback, @@ -44,18 +47,16 @@ const { isEphemeralAgentId, removeNullishValues, } = require('librechat-data-provider'); -const { spendTokens, spendStructuredTokens } = require('~/models/spendTokens'); +const { filterFilesByAgentAccess } = require('~/server/services/Files/permissions'); 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 { getMCPServerTools } = require('~/server/services/Config'); const BaseClient = require('~/app/clients/BaseClient'); -const { getRoleByName } = require('~/models/Role'); -const { loadAgent } = require('~/models/Agent'); const { getMCPManager } = require('~/config'); const db = require('~/models'); +const loadAgent = (params) => loadAgentFn(params, { getAgent: db.getAgent, getMCPServerTools }); + class AgentClient extends BaseClient { constructor(options = {}) { super(null, options); @@ -63,9 +64,6 @@ class AgentClient extends BaseClient { * @type {string} */ this.clientName = EModelEndpoint.agents; - /** @type {'discard' | 'summarize'} */ - this.contextStrategy = 'discard'; - /** @deprecated @type {true} - Is a Chat Completion Request */ this.isChatCompletion = true; @@ -217,7 +215,6 @@ class AgentClient extends BaseClient { })) : []), ]; - if (this.options.attachments) { const attachments = await this.options.attachments; const latestMessage = orderedMessages[orderedMessages.length - 1]; @@ -244,6 +241,11 @@ class AgentClient extends BaseClient { ); } + /** @type {Record} */ + const canonicalTokenCountMap = {}; + /** @type {Record} */ + const tokenCountMap = {}; + let promptTokenTotal = 0; const formattedMessages = orderedMessages.map((message, i) => { const formattedMessage = formatMessage({ message, @@ -263,12 +265,14 @@ class AgentClient extends BaseClient { } } - const needsTokenCount = - (this.contextStrategy && !orderedMessages[i].tokenCount) || message.fileContext; + const dbTokenCount = orderedMessages[i].tokenCount; + const needsTokenCount = !dbTokenCount || message.fileContext; - /* If tokens were never counted, or, is a Vision request and the message has files, count again */ if (needsTokenCount || (this.isVisionModel && (message.image_urls || message.files))) { - orderedMessages[i].tokenCount = this.getTokenCountForMessage(formattedMessage); + orderedMessages[i].tokenCount = countFormattedMessageTokens( + formattedMessage, + this.getEncoding(), + ); } /* If message has files, calculate image token cost */ @@ -282,17 +286,37 @@ class AgentClient extends BaseClient { if (file.metadata?.fileIdentifier) { continue; } - // orderedMessages[i].tokenCount += this.calculateImageTokenCost({ - // width: file.width, - // height: file.height, - // detail: this.options.imageDetail ?? ImageDetail.auto, - // }); } } + const tokenCount = Number(orderedMessages[i].tokenCount); + const normalizedTokenCount = Number.isFinite(tokenCount) && tokenCount > 0 ? tokenCount : 0; + canonicalTokenCountMap[i] = normalizedTokenCount; + promptTokenTotal += normalizedTokenCount; + + if (message.messageId) { + tokenCountMap[message.messageId] = normalizedTokenCount; + } + + if (isEnabled(process.env.AGENT_DEBUG_LOGGING)) { + const role = message.isCreatedByUser ? 'user' : 'assistant'; + const hasSummary = + Array.isArray(message.content) && message.content.some((p) => p && p.type === 'summary'); + const suffix = hasSummary ? '[S]' : ''; + const id = (message.messageId ?? message.id ?? '').slice(-8); + const recalced = needsTokenCount ? orderedMessages[i].tokenCount : null; + logger.debug( + `[AgentClient] msg[${i}] ${role}${suffix} id=…${id} db=${dbTokenCount} needsRecount=${needsTokenCount} recalced=${recalced} tokens=${normalizedTokenCount}`, + ); + } + return formattedMessage; }); + payload = formattedMessages; + messages = orderedMessages; + promptTokens = promptTokenTotal; + /** * Build shared run context - applies to ALL agents in the run. * This includes: file context (latest message), augmented prompt (RAG), memory context. @@ -322,23 +346,20 @@ class AgentClient extends BaseClient { const sharedRunContext = sharedRunContextParts.join('\n\n'); - /** @type {Record | undefined} */ - let tokenCountMap; + /** Preserve canonical pre-format token counts for all history entering graph formatting */ + this.indexTokenCountMap = canonicalTokenCountMap; - if (this.contextStrategy) { - ({ payload, promptTokens, tokenCountMap, messages } = await this.handleContextStrategy({ - orderedMessages, - formattedMessages, - })); - } - - for (let i = 0; i < messages.length; i++) { - this.indexTokenCountMap[i] = messages[i].tokenCount; + /** Extract contextMeta from the parent response (second-to-last in ordered chain; + * last is the current user message). Seeds the pruner's calibration EMA for this run. */ + const parentResponse = + orderedMessages.length >= 2 ? orderedMessages[orderedMessages.length - 2] : undefined; + if (parentResponse?.contextMeta && !parentResponse.isCreatedByUser) { + this.contextMeta = parentResponse.contextMeta; } const result = { - tokenCountMap, prompt: payload, + tokenCountMap, promptTokens, messages, }; @@ -412,7 +433,7 @@ class AgentClient extends BaseClient { user, permissionType: PermissionTypes.MEMORIES, permissions: [Permissions.USE], - getRoleByName, + getRoleByName: db.getRoleByName, }); if (!hasAccess) { @@ -472,13 +493,14 @@ class AgentClient extends BaseClient { }, }, { - getConvoFiles, getFiles: db.getFiles, getUserKey: db.getUserKey, + getConvoFiles: db.getConvoFiles, updateFilesUsage: db.updateFilesUsage, getUserKeyValues: db.getUserKeyValues, getToolFilesByIds: db.getToolFilesByIds, getCodeGeneratedFiles: db.getCodeGeneratedFiles, + filterFilesByAgentAccess, }, ); @@ -629,10 +651,10 @@ class AgentClient extends BaseClient { }) { const result = await recordCollectedUsage( { - spendTokens, - spendStructuredTokens, - pricing: { getMultiplier, getCacheMultiplier }, - bulkWriteOps: { insertMany: bulkInsertTransactions, updateBalance }, + spendTokens: db.spendTokens, + spendStructuredTokens: db.spendStructuredTokens, + pricing: { getMultiplier: db.getMultiplier, getCacheMultiplier: db.getCacheMultiplier }, + bulkWriteOps: { insertMany: db.bulkInsertTransactions, updateBalance: db.updateBalance }, }, { user: this.user ?? this.options.req.user?.id, @@ -665,39 +687,7 @@ class AgentClient extends BaseClient { * @returns {number} */ getTokenCountForResponse({ content }) { - return this.getTokenCountForMessage({ - role: 'assistant', - content, - }); - } - - /** - * Calculates the correct token count for the current user message based on the token count map and API usage. - * Edge case: If the calculation results in a negative value, it returns the original estimate. - * If revisiting a conversation with a chat history entirely composed of token estimates, - * the cumulative token count going forward should become more accurate as the conversation progresses. - * @param {Object} params - The parameters for the calculation. - * @param {Record} params.tokenCountMap - A map of message IDs to their token counts. - * @param {string} params.currentMessageId - The ID of the current message to calculate. - * @param {OpenAIUsageMetadata} params.usage - The usage object returned by the API. - * @returns {number} The correct token count for the current user message. - */ - calculateCurrentTokenCount({ tokenCountMap, currentMessageId, usage }) { - const originalEstimate = tokenCountMap[currentMessageId] || 0; - - if (!usage || typeof usage[this.inputTokensKey] !== 'number') { - return originalEstimate; - } - - tokenCountMap[currentMessageId] = 0; - const totalTokensFromMap = Object.values(tokenCountMap).reduce((sum, count) => { - const numCount = Number(count); - return sum + (isNaN(numCount) ? 0 : numCount); - }, 0); - const totalInputTokens = usage[this.inputTokensKey] ?? 0; - - const currentMessageTokens = totalInputTokens - totalTokensFromMap; - return currentMessageTokens > 0 ? currentMessageTokens : originalEstimate; + return countFormattedMessageTokens({ role: 'assistant', content }, this.getEncoding()); } /** @@ -745,11 +735,34 @@ class AgentClient extends BaseClient { }; const toolSet = buildToolSet(this.options.agent); - let { messages: initialMessages, indexTokenCountMap } = formatAgentMessages( - payload, - this.indexTokenCountMap, - toolSet, - ); + const tokenCounter = createTokenCounter(this.getEncoding()); + let { + messages: initialMessages, + indexTokenCountMap, + summary: initialSummary, + boundaryTokenAdjustment, + } = formatAgentMessages(payload, this.indexTokenCountMap, toolSet); + if (boundaryTokenAdjustment) { + logger.debug( + `[AgentClient] Boundary token adjustment: ${boundaryTokenAdjustment.original} → ${boundaryTokenAdjustment.adjusted} (${boundaryTokenAdjustment.remainingChars}/${boundaryTokenAdjustment.totalChars} chars)`, + ); + } + if (indexTokenCountMap && isEnabled(process.env.AGENT_DEBUG_LOGGING)) { + const entries = Object.entries(indexTokenCountMap); + const perMsg = entries.map(([idx, count]) => { + const msg = initialMessages[Number(idx)]; + const type = msg ? msg._getType() : '?'; + return `${idx}:${type}=${count}`; + }); + logger.debug( + `[AgentClient] Token map after format: [${perMsg.join(', ')}] (payload=${payload.length}, formatted=${initialMessages.length})`, + ); + } + indexTokenCountMap = hydrateMissingIndexTokenCounts({ + messages: initialMessages, + indexTokenCountMap, + tokenCounter, + }); /** * @param {BaseMessage[]} messages @@ -803,16 +816,32 @@ class AgentClient extends BaseClient { memoryPromise = this.runMemory(messages); + /** Seed calibration state from previous run if encoding matches */ + const currentEncoding = this.getEncoding(); + const prevMeta = this.contextMeta; + const encodingMatch = prevMeta?.encoding === currentEncoding; + const calibrationRatio = + encodingMatch && prevMeta?.calibrationRatio > 0 ? prevMeta.calibrationRatio : undefined; + + if (prevMeta) { + logger.debug( + `[AgentClient] contextMeta from parent: ratio=${prevMeta.calibrationRatio}, encoding=${prevMeta.encoding}, current=${currentEncoding}, seeded=${calibrationRatio ?? 'none'}`, + ); + } + run = await createRun({ agents, messages, indexTokenCountMap, + initialSummary, + calibrationRatio, runId: this.responseMessageId, signal: abortController.signal, customHandlers: this.options.eventHandlers, requestBody: config.configurable.requestBody, user: createSafeUser(this.options.req?.user), - tokenCounter: createTokenCounter(this.getEncoding()), + summarizationConfig: appConfig?.summarization, + tokenCounter, }); if (!run) { @@ -843,6 +872,7 @@ class AgentClient extends BaseClient { const hideSequentialOutputs = config.configurable.hide_sequential_outputs; await runAgents(initialMessages); + /** @deprecated Agent Chain */ if (hideSequentialOutputs) { this.contentParts = this.contentParts.filter((part, index) => { @@ -873,6 +903,18 @@ class AgentClient extends BaseClient { }); } } finally { + /** Capture calibration state from the run for persistence on the response message. + * Runs in finally so values are captured even on abort. */ + const ratio = this.run?.getCalibrationRatio() ?? 0; + if (ratio > 0 && ratio !== 1) { + this.contextMeta = { + calibrationRatio: Math.round(ratio * 1000) / 1000, + encoding: this.getEncoding(), + }; + } else { + this.contextMeta = undefined; + } + try { const attachments = await this.awaitMemoryWithTimeout(memoryPromise); if (attachments && attachments.length > 0) { @@ -1058,6 +1100,7 @@ class AgentClient extends BaseClient { titlePrompt: endpointConfig?.titlePrompt, titlePromptTemplate: endpointConfig?.titlePromptTemplate, chainOptions: { + runName: 'TitleRun', signal: abortController.signal, callbacks: [ { @@ -1132,7 +1175,7 @@ class AgentClient extends BaseClient { context = 'message', }) { try { - await spendTokens( + await db.spendTokens( { model, context, @@ -1151,7 +1194,7 @@ class AgentClient extends BaseClient { 'reasoning_tokens' in usage && typeof usage.reasoning_tokens === 'number' ) { - await spendTokens( + await db.spendTokens( { model, balance, @@ -1172,19 +1215,13 @@ 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'; } - - /** - * Returns the token count of a given text. It also checks and resets the tokenizers if necessary. - * @param {string} text - The text to get the token count for. - * @returns {number} The token count of the given text. - */ - getTokenCount(text) { - const encoding = this.getEncoding(); - return Tokenizer.getTokenCount(text, encoding); - } } module.exports = AgentClient; diff --git a/api/server/controllers/agents/client.test.js b/api/server/controllers/agents/client.test.js index 42481e1644..41a806f66d 100644 --- a/api/server/controllers/agents/client.test.js +++ b/api/server/controllers/agents/client.test.js @@ -15,13 +15,15 @@ jest.mock('@librechat/api', () => ({ checkAccess: jest.fn(), initializeAgent: jest.fn(), createMemoryProcessor: jest.fn(), -})); - -jest.mock('~/models/Agent', () => ({ loadAgent: jest.fn(), })); -jest.mock('~/models/Role', () => ({ +jest.mock('~/server/services/Config', () => ({ + getMCPServerTools: jest.fn(), +})); + +jest.mock('~/models', () => ({ + getAgent: jest.fn(), getRoleByName: jest.fn(), })); @@ -1816,7 +1818,7 @@ describe('AgentClient - titleConvo', () => { /** Traversal stops at msg-2 (has summary), so we get msg-4 -> msg-3 -> msg-2 */ expect(result).toHaveLength(3); - expect(result[0].text).toBe('Summary of conversation'); + expect(result[0].content).toEqual([{ type: 'text', text: 'Summary of conversation' }]); expect(result[0].role).toBe('system'); expect(result[0].mapped).toBe(true); expect(result[1].mapped).toBe(true); @@ -2138,7 +2140,7 @@ describe('AgentClient - titleConvo', () => { }; mockCheckAccess = require('@librechat/api').checkAccess; - mockLoadAgent = require('~/models/Agent').loadAgent; + mockLoadAgent = require('@librechat/api').loadAgent; mockInitializeAgent = require('@librechat/api').initializeAgent; mockCreateMemoryProcessor = require('@librechat/api').createMemoryProcessor; }); @@ -2195,6 +2197,7 @@ describe('AgentClient - titleConvo', () => { expect.objectContaining({ agent_id: differentAgentId, }), + expect.any(Object), ); expect(mockInitializeAgent).toHaveBeenCalledWith( expect.objectContaining({ diff --git a/api/server/controllers/agents/errors.js b/api/server/controllers/agents/errors.js index 54b296a5d2..b16ce75591 100644 --- a/api/server/controllers/agents/errors.js +++ b/api/server/controllers/agents/errors.js @@ -3,8 +3,8 @@ const { logger } = require('@librechat/data-schemas'); const { CacheKeys, ViolationTypes } = require('librechat-data-provider'); const { sendResponse } = require('~/server/middleware/error'); const { recordUsage } = require('~/server/services/Threads'); -const { getConvo } = require('~/models/Conversation'); const getLogStores = require('~/cache/getLogStores'); +const { getConvo } = require('~/models'); /** * @typedef {Object} ErrorHandlerContext diff --git a/api/server/controllers/agents/filterAuthorizedTools.spec.js b/api/server/controllers/agents/filterAuthorizedTools.spec.js new file mode 100644 index 0000000000..e215fdc1fc --- /dev/null +++ b/api/server/controllers/agents/filterAuthorizedTools.spec.js @@ -0,0 +1,668 @@ +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('~/server/services/Files/strategies', () => ({ + getStrategyFunctions: jest.fn(), +})); + +jest.mock('~/server/services/Files/images/avatar', () => ({ + resizeAvatar: jest.fn(), +})); + +jest.mock('~/server/services/Files/process', () => ({ + filterFile: 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', () => { + const mongoose = require('mongoose'); + const { createModels, createMethods } = require('@librechat/data-schemas'); + createModels(mongoose); + const methods = createMethods(mongoose); + return { + ...methods, + getCategoriesWithCounts: jest.fn(), + deleteFileByFilter: 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 e8561f15fe..b649058806 100644 --- a/api/server/controllers/agents/openai.js +++ b/api/server/controllers/agents/openai.js @@ -21,13 +21,14 @@ const { createOpenAIContentAggregator, isChatCompletionValidationFailure, } = require('@librechat/api'); +const { + buildSummarizationHandlers, + markSummarizationUsage, + createToolEndCallback, + agentLogHandlerObj, +} = require('~/server/controllers/agents/callbacks'); const { loadAgentTools, loadToolsForExecution } = require('~/server/services/ToolService'); -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'); /** @@ -139,7 +140,7 @@ const OpenAIChatCompletionController = async (req, res) => { const agentId = request.model; // Look up the agent - const agent = await getAgent({ id: agentId }); + const agent = await db.getAgent({ id: agentId }); if (!agent) { return sendErrorResponse( res, @@ -151,8 +152,6 @@ const OpenAIChatCompletionController = async (req, res) => { } 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 */ @@ -178,6 +177,23 @@ const OpenAIChatCompletionController = async (req, res) => { }); try { + if (request.conversation_id != null) { + if (typeof request.conversation_id !== 'string') { + return sendErrorResponse( + res, + 400, + 'conversation_id must be a string', + 'invalid_request_error', + ); + } + if (!(await db.getConvo(req.user?.id, request.conversation_id))) { + return sendErrorResponse(res, 404, 'Conversation not found', 'invalid_request_error'); + } + } + + const conversationId = request.conversation_id ?? nanoid(); + const parentMessageId = request.parent_message_id ?? null; + // Build allowed providers set const allowedProviders = new Set( appConfig?.endpoints?.[EModelEndpoint.agents]?.allowedProviders, @@ -206,7 +222,7 @@ const OpenAIChatCompletionController = async (req, res) => { isInitialAgent: true, }, { - getConvoFiles, + getConvoFiles: db.getConvoFiles, getFiles: db.getFiles, getUserKey: db.getUserKey, getMessages: db.getMessages, @@ -265,19 +281,22 @@ const OpenAIChatCompletionController = async (req, res) => { toolRegistry: primaryConfig.toolRegistry, userMCPAuthMap: primaryConfig.userMCPAuthMap, tool_resources: primaryConfig.tool_resources, + actionsEnabled: primaryConfig.actionsEnabled, }); }, toolEndCallback, }; + const summarizationConfig = appConfig?.summarization; + const openaiMessages = convertMessages(request.messages); const toolSet = buildToolSet(primaryConfig); - const { messages: formattedMessages, indexTokenCountMap } = formatAgentMessages( - openaiMessages, - {}, - toolSet, - ); + const { + messages: formattedMessages, + indexTokenCountMap, + summary: initialSummary, + } = formatAgentMessages(openaiMessages, {}, toolSet); /** * Create a simple handler that processes data @@ -420,24 +439,30 @@ const OpenAIChatCompletionController = async (req, res) => { }), // Usage tracking - on_chat_model_end: createHandler((data) => { - const usage = data?.output?.usage_metadata; - if (usage) { - collectedUsage.push(usage); - const target = isStreaming ? tracker : aggregator; - target.usage.promptTokens += usage.input_tokens ?? 0; - target.usage.completionTokens += usage.output_tokens ?? 0; - } - }), + on_chat_model_end: { + handle: (_event, data, metadata) => { + const usage = data?.output?.usage_metadata; + if (usage) { + const taggedUsage = markSummarizationUsage(usage, metadata); + collectedUsage.push(taggedUsage); + const target = isStreaming ? tracker : aggregator; + target.usage.promptTokens += taggedUsage.input_tokens ?? 0; + target.usage.completionTokens += taggedUsage.output_tokens ?? 0; + } + }, + }, on_run_step_completed: createHandler(), // Use proper ToolEndHandler for processing artifacts (images, file citations, code output) on_tool_end: new ToolEndHandler(toolEndCallback, logger), on_chain_stream: createHandler(), on_chain_end: createHandler(), on_agent_update: createHandler(), + on_agent_log: agentLogHandlerObj, on_custom_event: createHandler(), - // Event-driven tool execution handler on_tool_execute: createToolExecuteHandler(toolExecuteOptions), + ...(summarizationConfig?.enabled !== false + ? buildSummarizationHandlers({ isStreaming, res }) + : {}), }; // Create and run the agent @@ -450,7 +475,9 @@ const OpenAIChatCompletionController = async (req, res) => { agents: [primaryConfig], messages: formattedMessages, indexTokenCountMap, + initialSummary, runId: responseId, + summarizationConfig, signal: abortController.signal, customHandlers: handlers, requestBody: { @@ -495,9 +522,9 @@ const OpenAIChatCompletionController = async (req, res) => { const transactionsConfig = getTransactionsConfig(appConfig); recordCollectedUsage( { - spendTokens, - spendStructuredTokens, - pricing: { getMultiplier, getCacheMultiplier }, + spendTokens: db.spendTokens, + spendStructuredTokens: db.spendStructuredTokens, + pricing: { getMultiplier: db.getMultiplier, getCacheMultiplier: db.getCacheMultiplier }, bulkWriteOps: { insertMany: db.bulkInsertTransactions, updateBalance: db.updateBalance }, }, { @@ -611,7 +638,7 @@ const ListModelsController = async (req, res) => { // Get the accessible agents let agents = []; if (accessibleAgentIds.length > 0) { - agents = await getAgents({ _id: { $in: accessibleAgentIds } }); + agents = await db.getAgents({ _id: { $in: accessibleAgentIds } }); } const models = agents.map((agent) => ({ @@ -654,7 +681,7 @@ const GetModelController = async (req, res) => { return sendErrorResponse(res, 401, 'Authentication required', 'auth_error'); } - const agent = await getAgent({ id: model }); + const agent = await db.getAgent({ id: model }); if (!agent) { return sendErrorResponse( diff --git a/api/server/controllers/agents/recordCollectedUsage.spec.js b/api/server/controllers/agents/recordCollectedUsage.spec.js index 21720023ca..009c5b262c 100644 --- a/api/server/controllers/agents/recordCollectedUsage.spec.js +++ b/api/server/controllers/agents/recordCollectedUsage.spec.js @@ -18,17 +18,11 @@ const mockRecordCollectedUsage = jest .fn() .mockResolvedValue({ input_tokens: 100, output_tokens: 50 }); -jest.mock('~/models/spendTokens', () => ({ +jest.mock('~/models', () => ({ spendTokens: (...args) => mockSpendTokens(...args), spendStructuredTokens: (...args) => mockSpendStructuredTokens(...args), -})); - -jest.mock('~/models/tx', () => ({ getMultiplier: mockGetMultiplier, getCacheMultiplier: mockGetCacheMultiplier, -})); - -jest.mock('~/models', () => ({ updateBalance: mockUpdateBalance, bulkInsertTransactions: mockBulkInsertTransactions, })); diff --git a/api/server/controllers/agents/request.js b/api/server/controllers/agents/request.js index dea5400036..6f7e1b88c1 100644 --- a/api/server/controllers/agents/request.js +++ b/api/server/controllers/agents/request.js @@ -131,9 +131,15 @@ const ResumableAgentController = async (req, res, next, initializeClient, addTit partialMessage.agent_id = req.body.agent_id; } - await saveMessage(req, partialMessage, { - context: 'api/server/controllers/agents/request.js - partial response on disconnect', - }); + await saveMessage( + { + userId: req?.user?.id, + isTemporary: req?.body?.isTemporary, + interfaceConfig: req?.config?.interfaceConfig, + }, + partialMessage, + { context: 'api/server/controllers/agents/request.js - partial response on disconnect' }, + ); logger.debug( `[ResumableAgentController] Saved partial response for ${streamId}, content parts: ${aggregatedContent.length}`, @@ -271,8 +277,14 @@ const ResumableAgentController = async (req, res, next, initializeClient, addTit // Save user message BEFORE sending final event to avoid race condition // where client refetch happens before database is updated + const reqCtx = { + userId: req?.user?.id, + isTemporary: req?.body?.isTemporary, + interfaceConfig: req?.config?.interfaceConfig, + }; + if (!client.skipSaveUserMessage && userMessage) { - await saveMessage(req, userMessage, { + await saveMessage(reqCtx, userMessage, { context: 'api/server/controllers/agents/request.js - resumable user message', }); } @@ -282,7 +294,7 @@ const ResumableAgentController = async (req, res, next, initializeClient, addTit // before the response is saved to the database, causing orphaned parentMessageIds. if (client.savedMessageIds && !client.savedMessageIds.has(messageId)) { await saveMessage( - req, + reqCtx, { ...response, user: userId, unfinished: wasAbortedBeforeComplete }, { context: 'api/server/controllers/agents/request.js - resumable response end' }, ); @@ -661,7 +673,11 @@ const _LegacyAgentController = async (req, res, next, initializeClient, addTitle // Save the message if needed if (client.savedMessageIds && !client.savedMessageIds.has(messageId)) { await saveMessage( - req, + { + userId: req?.user?.id, + isTemporary: req?.body?.isTemporary, + interfaceConfig: req?.config?.interfaceConfig, + }, { ...finalResponse, user: userId }, { context: 'api/server/controllers/agents/request.js - response end' }, ); @@ -690,9 +706,15 @@ const _LegacyAgentController = async (req, res, next, initializeClient, addTitle // Save user message if needed if (!client.skipSaveUserMessage) { - await saveMessage(req, userMessage, { - context: "api/server/controllers/agents/request.js - don't skip saving user message", - }); + await saveMessage( + { + userId: req?.user?.id, + isTemporary: req?.body?.isTemporary, + interfaceConfig: req?.config?.interfaceConfig, + }, + userMessage, + { context: "api/server/controllers/agents/request.js - don't skip saving user message" }, + ); } // Add title if needed - extract minimal data diff --git a/api/server/controllers/agents/responses.js b/api/server/controllers/agents/responses.js index 83e6ad6efd..7abddf5e2f 100644 --- a/api/server/controllers/agents/responses.js +++ b/api/server/controllers/agents/responses.js @@ -32,14 +32,13 @@ const { } = require('@librechat/api'); const { createResponsesToolEndCallback, + buildSummarizationHandlers, + markSummarizationUsage, createToolEndCallback, + agentLogHandlerObj, } = require('~/server/controllers/agents/callbacks'); const { loadAgentTools, loadToolsForExecution } = require('~/server/services/ToolService'); 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'); /** @type {import('@librechat/api').AppConfig | null} */ @@ -214,8 +213,12 @@ async function saveResponseOutput(req, conversationId, responseId, response, age * @returns {Promise} */ async function saveConversation(req, conversationId, agentId, agent) { - await saveConvo( - req, + await db.saveConvo( + { + userId: req?.user?.id, + isTemporary: req?.body?.isTemporary, + interfaceConfig: req?.config?.interfaceConfig, + }, { conversationId, endpoint: EModelEndpoint.agents, @@ -277,9 +280,10 @@ const createResponse = async (req, res) => { const request = validation.request; const agentId = request.model; const isStreaming = request.stream === true; + const summarizationConfig = req.config?.summarization; // Look up the agent - const agent = await getAgent({ id: agentId }); + const agent = await db.getAgent({ id: agentId }); if (!agent) { return sendResponsesErrorResponse( res, @@ -292,10 +296,6 @@ const createResponse = async (req, res) => { // Generate IDs const responseId = generateResponseId(); - const conversationId = request.previous_response_id ?? uuidv4(); - const parentMessageId = null; - - // Create response context const context = createResponseContext(request, responseId); logger.debug( @@ -314,6 +314,23 @@ const createResponse = async (req, res) => { }); try { + if (request.previous_response_id != null) { + if (typeof request.previous_response_id !== 'string') { + return sendResponsesErrorResponse( + res, + 400, + 'previous_response_id must be a string', + 'invalid_request', + ); + } + if (!(await db.getConvo(req.user?.id, request.previous_response_id))) { + return sendResponsesErrorResponse(res, 404, 'Conversation not found', 'not_found'); + } + } + + const conversationId = request.previous_response_id ?? uuidv4(); + const parentMessageId = null; + // Build allowed providers set const allowedProviders = new Set( appConfig?.endpoints?.[EModelEndpoint.agents]?.allowedProviders, @@ -342,7 +359,7 @@ const createResponse = async (req, res) => { isInitialAgent: true, }, { - getConvoFiles, + getConvoFiles: db.getConvoFiles, getFiles: db.getFiles, getUserKey: db.getUserKey, getMessages: db.getMessages, @@ -374,11 +391,11 @@ const createResponse = async (req, res) => { const allMessages = [...previousMessages, ...inputMessages]; const toolSet = buildToolSet(primaryConfig); - const { messages: formattedMessages, indexTokenCountMap } = formatAgentMessages( - allMessages, - {}, - toolSet, - ); + const { + messages: formattedMessages, + indexTokenCountMap, + summary: initialSummary, + } = formatAgentMessages(allMessages, {}, toolSet); // Create tracker for streaming or aggregator for non-streaming const tracker = actuallyStreaming ? createResponseTracker() : null; @@ -429,6 +446,7 @@ const createResponse = async (req, res) => { toolRegistry: primaryConfig.toolRegistry, userMCPAuthMap: primaryConfig.userMCPAuthMap, tool_resources: primaryConfig.tool_resources, + actionsEnabled: primaryConfig.actionsEnabled, }); }, toolEndCallback, @@ -441,11 +459,12 @@ const createResponse = async (req, res) => { on_run_step: responsesHandlers.on_run_step, on_run_step_delta: responsesHandlers.on_run_step_delta, on_chat_model_end: { - handle: (event, data) => { + handle: (event, data, metadata) => { responsesHandlers.on_chat_model_end.handle(event, data); const usage = data?.output?.usage_metadata; if (usage) { - collectedUsage.push(usage); + const taggedUsage = markSummarizationUsage(usage, metadata); + collectedUsage.push(taggedUsage); } }, }, @@ -456,6 +475,10 @@ const createResponse = async (req, res) => { on_agent_update: { handle: () => {} }, on_custom_event: { handle: () => {} }, on_tool_execute: createToolExecuteHandler(toolExecuteOptions), + on_agent_log: agentLogHandlerObj, + ...(summarizationConfig?.enabled !== false + ? buildSummarizationHandlers({ isStreaming: actuallyStreaming, res }) + : {}), }; // Create and run the agent @@ -466,7 +489,9 @@ const createResponse = async (req, res) => { agents: [primaryConfig], messages: formattedMessages, indexTokenCountMap, + initialSummary, runId: responseId, + summarizationConfig, signal: abortController.signal, customHandlers: handlers, requestBody: { @@ -511,9 +536,9 @@ const createResponse = async (req, res) => { const transactionsConfig = getTransactionsConfig(req.config); recordCollectedUsage( { - spendTokens, - spendStructuredTokens, - pricing: { getMultiplier, getCacheMultiplier }, + spendTokens: db.spendTokens, + spendStructuredTokens: db.spendStructuredTokens, + pricing: { getMultiplier: db.getMultiplier, getCacheMultiplier: db.getCacheMultiplier }, bulkWriteOps: { insertMany: db.bulkInsertTransactions, updateBalance: db.updateBalance }, }, { @@ -586,6 +611,7 @@ const createResponse = async (req, res) => { toolRegistry: primaryConfig.toolRegistry, userMCPAuthMap: primaryConfig.userMCPAuthMap, tool_resources: primaryConfig.tool_resources, + actionsEnabled: primaryConfig.actionsEnabled, }); }, toolEndCallback, @@ -597,11 +623,12 @@ const createResponse = async (req, res) => { on_run_step: aggregatorHandlers.on_run_step, on_run_step_delta: aggregatorHandlers.on_run_step_delta, on_chat_model_end: { - handle: (event, data) => { + handle: (event, data, metadata) => { aggregatorHandlers.on_chat_model_end.handle(event, data); const usage = data?.output?.usage_metadata; if (usage) { - collectedUsage.push(usage); + const taggedUsage = markSummarizationUsage(usage, metadata); + collectedUsage.push(taggedUsage); } }, }, @@ -612,6 +639,10 @@ const createResponse = async (req, res) => { on_agent_update: { handle: () => {} }, on_custom_event: { handle: () => {} }, on_tool_execute: createToolExecuteHandler(toolExecuteOptions), + on_agent_log: agentLogHandlerObj, + ...(summarizationConfig?.enabled !== false + ? buildSummarizationHandlers({ isStreaming: false, res }) + : {}), }; const userId = req.user?.id ?? 'api-user'; @@ -621,7 +652,9 @@ const createResponse = async (req, res) => { agents: [primaryConfig], messages: formattedMessages, indexTokenCountMap, + initialSummary, runId: responseId, + summarizationConfig, signal: abortController.signal, customHandlers: handlers, requestBody: { @@ -665,9 +698,9 @@ const createResponse = async (req, res) => { const transactionsConfig = getTransactionsConfig(req.config); recordCollectedUsage( { - spendTokens, - spendStructuredTokens, - pricing: { getMultiplier, getCacheMultiplier }, + spendTokens: db.spendTokens, + spendStructuredTokens: db.spendStructuredTokens, + pricing: { getMultiplier: db.getMultiplier, getCacheMultiplier: db.getCacheMultiplier }, bulkWriteOps: { insertMany: db.bulkInsertTransactions, updateBalance: db.updateBalance }, }, { @@ -767,7 +800,7 @@ const listModels = async (req, res) => { // Get the accessible agents let agents = []; if (accessibleAgentIds.length > 0) { - agents = await getAgents({ _id: { $in: accessibleAgentIds } }); + agents = await db.getAgents({ _id: { $in: accessibleAgentIds } }); } // Convert to models format @@ -817,7 +850,7 @@ const getResponse = async (req, res) => { // The responseId could be either the response ID or the conversation ID // Try to find a conversation with this ID - const conversation = await getConvo(userId, responseId); + const conversation = await db.getConvo(userId, responseId); if (!conversation) { return sendResponsesErrorResponse( diff --git a/api/server/controllers/agents/v1.js b/api/server/controllers/agents/v1.js index a2c0d55186..17985f97ce 100644 --- a/api/server/controllers/agents/v1.js +++ b/api/server/controllers/agents/v1.js @@ -3,9 +3,11 @@ const fs = require('fs').promises; const { nanoid } = require('nanoid'); const { logger } = require('@librechat/data-schemas'); const { + refreshS3Url, agentCreateSchema, agentUpdateSchema, refreshListAvatars, + collectEdgeAgentIds, mergeAgentOcrConversion, MAX_AVATAR_REFRESH_AGENTS, convertOcrToContextInPlace, @@ -24,30 +26,21 @@ const { actionDelimiter, removeNullishValues, } = require('librechat-data-provider'); -const { - getListAgentsByAccess, - countPromotedAgents, - revertAgentVersion, - createAgent, - updateAgent, - deleteAgent, - getAgent, -} = require('~/models/Agent'); const { findPubliclyAccessibleResources, + getResourcePermissionsMap, findAccessibleResources, hasPublicPermission, grantPermission, } = require('~/server/services/PermissionService'); const { getStrategyFunctions } = require('~/server/services/Files/strategies'); -const { getCategoriesWithCounts, deleteFileByFilter } = require('~/models'); const { resizeAvatar } = require('~/server/services/Files/images/avatar'); const { getFileStrategy } = require('~/server/utils/getFileStrategy'); -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 db = require('~/models'); const systemTools = { [Tools.execute_code]: true, @@ -58,6 +51,114 @@ 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 db.getAgents({ id: { $in: [...edgeAgentIds] } }); + + 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,24 +176,26 @@ 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); + const agent = await db.createAgent(agentData); try { await Promise.all([ @@ -152,7 +255,7 @@ const getAgentHandler = async (req, res, expandProperties = false) => { // Permissions are validated by middleware before calling this function // Simply load the agent by ID - const agent = await getAgent({ id }); + const agent = await db.getAgent({ id }); if (!agent) { return res.status(404).json({ error: 'Agent not found' }); @@ -173,9 +276,6 @@ const getAgentHandler = async (req, res, expandProperties = false) => { agent.author = agent.author.toString(); - // @deprecated - isCollaborative replaced by ACL permissions - agent.isCollaborative = !!agent.isCollaborative; - // Check if agent is public const isPublic = await hasPublicPermission({ resourceType: ResourceType.AGENT, @@ -199,9 +299,6 @@ const getAgentHandler = async (req, res, expandProperties = false) => { author: agent.author, provider: agent.provider, model: agent.model, - projectIds: agent.projectIds, - // @deprecated - isCollaborative replaced by ACL permissions - isCollaborative: agent.isCollaborative, isPublic: agent.isPublic, version: agent.version, // Safe metadata @@ -243,10 +340,21 @@ 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); - const existingAgent = await getAgent({ id }); + const existingAgent = await db.getAgent({ id }); if (!existingAgent) { return res.status(404).json({ error: 'Agent not found' }); @@ -261,9 +369,29 @@ 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, { + ? await db.updateAgent({ id }, updateData, { updatingUserId: req.user.id, }) : existingAgent; @@ -313,7 +441,7 @@ const duplicateAgentHandler = async (req, res) => { const sensitiveFields = ['api_key', 'oauth_client_id', 'oauth_client_secret']; try { - const agent = await getAgent({ id }); + const agent = await db.getAgent({ id }); if (!agent) { return res.status(404).json({ error: 'Agent not found', @@ -361,7 +489,7 @@ const duplicateAgentHandler = async (req, res) => { }); const newActionsList = []; - const originalActions = (await getActions({ agent_id: id }, true)) ?? []; + const originalActions = (await db.getActions({ agent_id: id }, true)) ?? []; const promises = []; /** @@ -371,7 +499,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 @@ -380,8 +508,8 @@ const duplicateAgentHandler = async (req, res) => { delete filteredMetadata[field]; } - const newAction = await updateAction( - { action_id: newActionId }, + const newAction = await db.updateAction( + { action_id: newActionId, agent_id: newAgentId }, { metadata: filteredMetadata, agent_id: newAgentId, @@ -403,7 +531,18 @@ const duplicateAgentHandler = async (req, res) => { const agentActions = await Promise.all(promises); newAgentData.actions = agentActions; - const newAgent = await createAgent(newAgentData); + + if (newAgentData.tools?.length) { + const availableTools = (await getCachedTools()) ?? {}; + newAgentData.tools = await filterAuthorizedTools({ + tools: newAgentData.tools, + userId, + availableTools, + existingTools: newAgentData.tools, + }); + } + + const newAgent = await db.createAgent(newAgentData); try { await Promise.all([ @@ -456,11 +595,11 @@ const duplicateAgentHandler = async (req, res) => { const deleteAgentHandler = async (req, res) => { try { const id = req.params.id; - const agent = await getAgent({ id }); + const agent = await db.getAgent({ id }); if (!agent) { return res.status(404).json({ error: 'Agent not found' }); } - await deleteAgent({ id }); + await db.deleteAgent({ id }); return res.json({ message: 'Agent deleted' }); } catch (error) { logger.error('[/Agents/:id] Error deleting Agent', error); @@ -535,7 +674,7 @@ const getListAgentsHandler = async (req, res) => { cachedRefresh != null && typeof cachedRefresh === 'object' && cachedRefresh.urlCache != null; if (!isValidCachedRefresh) { try { - const fullList = await getListAgentsByAccess({ + const fullList = await db.getListAgentsByAccess({ accessibleIds, otherParams: {}, limit: MAX_AVATAR_REFRESH_AGENTS, @@ -545,7 +684,7 @@ const getListAgentsHandler = async (req, res) => { agents: fullList?.data ?? [], userId, refreshS3Url, - updateAgent, + updateAgent: db.updateAgent, }); cachedRefresh = { urlCache }; await cache.set(refreshKey, cachedRefresh, Time.THIRTY_MINUTES); @@ -557,7 +696,7 @@ const getListAgentsHandler = async (req, res) => { } // Use the new ACL-aware function - const data = await getListAgentsByAccess({ + const data = await db.getListAgentsByAccess({ accessibleIds, otherParams: filter, limit, @@ -622,7 +761,7 @@ const uploadAgentAvatarHandler = async (req, res) => { return res.status(400).json({ message: 'Agent ID is required' }); } - const existingAgent = await getAgent({ id: agent_id }); + const existingAgent = await db.getAgent({ id: agent_id }); if (!existingAgent) { return res.status(404).json({ error: 'Agent not found' }); @@ -654,7 +793,7 @@ const uploadAgentAvatarHandler = async (req, res) => { const { deleteFile } = getStrategyFunctions(_avatar.source); try { await deleteFile(req, { filepath: _avatar.filepath }); - await deleteFileByFilter({ user: req.user.id, filepath: _avatar.filepath }); + await db.deleteFileByFilter({ user: req.user.id, filepath: _avatar.filepath }); } catch (error) { logger.error('[/:agent_id/avatar] Error deleting old avatar', error); } @@ -667,7 +806,7 @@ const uploadAgentAvatarHandler = async (req, res) => { }, }; - const updatedAgent = await updateAgent({ id: agent_id }, data, { + const updatedAgent = await db.updateAgent({ id: agent_id }, data, { updatingUserId: req.user.id, }); @@ -723,7 +862,7 @@ const revertAgentVersionHandler = async (req, res) => { return res.status(400).json({ error: 'version_index is required' }); } - const existingAgent = await getAgent({ id }); + const existingAgent = await db.getAgent({ id }); if (!existingAgent) { return res.status(404).json({ error: 'Agent not found' }); @@ -731,7 +870,24 @@ const revertAgentVersionHandler = async (req, res) => { // Permissions are enforced via route middleware (ACL EDIT) - const updatedAgent = await revertAgentVersion({ id }, version_index); + let updatedAgent = await db.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 db.updateAgent( + { id }, + { tools: filteredTools }, + { updatingUserId: req.user.id }, + ); + } + } if (updatedAgent.author) { updatedAgent.author = updatedAgent.author.toString(); @@ -755,8 +911,8 @@ const revertAgentVersionHandler = async (req, res) => { */ const getAgentCategories = async (_req, res) => { try { - const categories = await getCategoriesWithCounts(); - const promotedCount = await countPromotedAgents(); + const categories = await db.getCategoriesWithCounts(); + const promotedCount = await db.countPromotedAgents(); const formattedCategories = categories.map((category) => ({ value: category.value, label: category.label, @@ -799,4 +955,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 ce68cc241f..455cea2e7c 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 @@ -14,10 +14,6 @@ jest.mock('~/server/services/Config', () => ({ }), })); -jest.mock('~/models/Project', () => ({ - getProjectByName: jest.fn().mockResolvedValue(null), -})); - jest.mock('~/server/services/Files/strategies', () => ({ getStrategyFunctions: jest.fn(), })); @@ -26,7 +22,16 @@ jest.mock('~/server/services/Files/images/avatar', () => ({ resizeAvatar: jest.fn(), })); -jest.mock('~/server/services/Files/S3/crud', () => ({ +jest.mock('sharp', () => + jest.fn(() => ({ + metadata: jest.fn().mockResolvedValue({}), + toFormat: jest.fn().mockReturnThis(), + toBuffer: jest.fn().mockResolvedValue(Buffer.alloc(0)), + })), +); + +jest.mock('@librechat/api', () => ({ + ...jest.requireActual('@librechat/api'), refreshS3Url: jest.fn(), })); @@ -34,26 +39,26 @@ 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([]), + getResourcePermissionsMap: jest.fn().mockResolvedValue(new Map()), grantPermission: jest.fn(), hasPublicPermission: jest.fn().mockResolvedValue(false), - checkPermission: jest.fn().mockResolvedValue(true), })); -jest.mock('~/models', () => ({ - getCategoriesWithCounts: jest.fn(), -})); +jest.mock('~/models', () => { + const mongoose = require('mongoose'); + const { createMethods } = require('@librechat/data-schemas'); + const methods = createMethods(mongoose, { + removeAllPermissions: jest.fn().mockResolvedValue(undefined), + }); + return { + ...methods, + getCategoriesWithCounts: jest.fn(), + deleteFileByFilter: jest.fn(), + }; +}); // Mock cache for S3 avatar refresh tests const mockCache = { @@ -74,9 +79,10 @@ const { const { findAccessibleResources, findPubliclyAccessibleResources, + getResourcePermissionsMap, } = require('~/server/services/PermissionService'); -const { refreshS3Url } = require('~/server/services/Files/S3/crud'); +const { refreshS3Url } = require('@librechat/api'); /** * @type {import('mongoose').Model} @@ -175,7 +181,6 @@ describe('Agent Controllers - Mass Assignment Protection', () => { // Unauthorized fields that should be stripped author: new mongoose.Types.ObjectId().toString(), // Should not be able to set author authorName: 'Hacker', // Should be stripped - isCollaborative: true, // Should be stripped on creation versions: [], // Should be stripped _id: new mongoose.Types.ObjectId(), // Should be stripped id: 'custom_agent_id', // Should be overridden @@ -194,7 +199,6 @@ describe('Agent Controllers - Mass Assignment Protection', () => { // Verify unauthorized fields were not set expect(createdAgent.author.toString()).toBe(mockReq.user.id); // Should be the request user, not the malicious value expect(createdAgent.authorName).toBeUndefined(); - expect(createdAgent.isCollaborative).toBeFalsy(); expect(createdAgent.versions).toHaveLength(1); // Should have exactly 1 version from creation expect(createdAgent.id).not.toBe('custom_agent_id'); // Should have generated ID expect(createdAgent.id).toMatch(/^agent_/); // Should have proper prefix @@ -445,7 +449,6 @@ describe('Agent Controllers - Mass Assignment Protection', () => { model: 'gpt-3.5-turbo', author: existingAgentAuthorId, description: 'Original description', - isCollaborative: false, versions: [ { name: 'Original Agent', @@ -467,7 +470,6 @@ describe('Agent Controllers - Mass Assignment Protection', () => { name: 'Updated Agent', description: 'Updated description', model: 'gpt-4', - isCollaborative: true, // This IS allowed in updates }; await updateAgentHandler(mockReq, mockRes); @@ -480,13 +482,11 @@ describe('Agent Controllers - Mass Assignment Protection', () => { expect(updatedAgent.name).toBe('Updated Agent'); expect(updatedAgent.description).toBe('Updated description'); expect(updatedAgent.model).toBe('gpt-4'); - expect(updatedAgent.isCollaborative).toBe(true); expect(updatedAgent.author).toBe(existingAgentAuthorId.toString()); // Verify in database const agentInDb = await Agent.findOne({ id: existingAgentId }); expect(agentInDb.name).toBe('Updated Agent'); - expect(agentInDb.isCollaborative).toBe(true); }); test('should reject update with unauthorized fields (mass assignment protection)', async () => { @@ -541,26 +541,6 @@ describe('Agent Controllers - Mass Assignment Protection', () => { expect(updatedAgent.name).toBe('Admin Update'); }); - test('should handle projectIds updates', async () => { - mockReq.user.id = existingAgentAuthorId.toString(); - mockReq.params.id = existingAgentId; - - const projectId1 = new mongoose.Types.ObjectId().toString(); - const projectId2 = new mongoose.Types.ObjectId().toString(); - - mockReq.body = { - projectIds: [projectId1, projectId2], - }; - - await updateAgentHandler(mockReq, mockRes); - - expect(mockRes.json).toHaveBeenCalled(); - - const updatedAgent = mockRes.json.mock.calls[0][0]; - expect(updatedAgent).toBeDefined(); - // Note: updateAgentProjects requires more setup, so we just verify the handler doesn't crash - }); - test('should validate tool_resources in updates', async () => { mockReq.user.id = existingAgentAuthorId.toString(); mockReq.params.id = existingAgentId; @@ -1647,4 +1627,112 @@ describe('Agent Controllers - Mass Assignment Protection', () => { 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/assistants/chatV1.js b/api/server/controllers/assistants/chatV1.js index 804594d0bf..e4a20c2a5e 100644 --- a/api/server/controllers/assistants/chatV1.js +++ b/api/server/controllers/assistants/chatV1.js @@ -1,7 +1,13 @@ const { v4 } = require('uuid'); const { sleep } = require('@librechat/agents'); const { logger } = require('@librechat/data-schemas'); -const { sendEvent, getBalanceConfig, getModelMaxTokens, countTokens } = require('@librechat/api'); +const { + sendEvent, + countTokens, + checkBalance, + getBalanceConfig, + getModelMaxTokens, +} = require('@librechat/api'); const { Time, Constants, @@ -31,10 +37,14 @@ const { createRun, StreamRunManager } = require('~/server/services/Runs'); const { addTitle } = require('~/server/services/Endpoints/assistants'); const { createRunBody } = require('~/server/services/createRunBody'); const { sendResponse } = require('~/server/middleware/error'); -const { getTransactions } = require('~/models/Transaction'); -const { checkBalance } = require('~/models/balanceMethods'); -const { getConvo } = require('~/models/Conversation'); -const getLogStores = require('~/cache/getLogStores'); +const { + createAutoRefillTransaction, + findBalanceByUser, + getTransactions, + getMultiplier, + getConvo, +} = require('~/models'); +const { logViolation, getLogStores } = require('~/cache'); const { getOpenAIClient } = require('./helpers'); /** @@ -275,16 +285,19 @@ const chatV1 = async (req, res) => { // Count tokens up to the current context window promptTokens = Math.min(promptTokens, getModelMaxTokens(model)); - await checkBalance({ - req, - res, - txData: { - model, - user: req.user.id, - tokenType: 'prompt', - amount: promptTokens, + await checkBalance( + { + req, + res, + txData: { + model, + user: req.user.id, + tokenType: 'prompt', + amount: promptTokens, + }, }, - }); + { findBalanceByUser, getMultiplier, createAutoRefillTransaction, logViolation }, + ); }; const { openai: _openai } = await getOpenAIClient({ diff --git a/api/server/controllers/assistants/chatV2.js b/api/server/controllers/assistants/chatV2.js index 414681d6dc..559d9d8953 100644 --- a/api/server/controllers/assistants/chatV2.js +++ b/api/server/controllers/assistants/chatV2.js @@ -1,7 +1,13 @@ const { v4 } = require('uuid'); const { sleep } = require('@librechat/agents'); const { logger } = require('@librechat/data-schemas'); -const { sendEvent, getBalanceConfig, getModelMaxTokens, countTokens } = require('@librechat/api'); +const { + sendEvent, + countTokens, + checkBalance, + getBalanceConfig, + getModelMaxTokens, +} = require('@librechat/api'); const { Time, Constants, @@ -26,10 +32,14 @@ const validateAuthor = require('~/server/middleware/assistants/validateAuthor'); const { createRun, StreamRunManager } = require('~/server/services/Runs'); const { addTitle } = require('~/server/services/Endpoints/assistants'); const { createRunBody } = require('~/server/services/createRunBody'); -const { getTransactions } = require('~/models/Transaction'); -const { checkBalance } = require('~/models/balanceMethods'); -const { getConvo } = require('~/models/Conversation'); -const getLogStores = require('~/cache/getLogStores'); +const { + getConvo, + getMultiplier, + getTransactions, + findBalanceByUser, + createAutoRefillTransaction, +} = require('~/models'); +const { logViolation, getLogStores } = require('~/cache'); const { getOpenAIClient } = require('./helpers'); /** @@ -148,16 +158,19 @@ const chatV2 = async (req, res) => { // Count tokens up to the current context window promptTokens = Math.min(promptTokens, getModelMaxTokens(model)); - await checkBalance({ - req, - res, - txData: { - model, - user: req.user.id, - tokenType: 'prompt', - amount: promptTokens, + await checkBalance( + { + req, + res, + txData: { + model, + user: req.user.id, + tokenType: 'prompt', + amount: promptTokens, + }, }, - }); + { findBalanceByUser, getMultiplier, createAutoRefillTransaction, logViolation }, + ); }; const { openai: _openai } = await getOpenAIClient({ diff --git a/api/server/controllers/assistants/errors.js b/api/server/controllers/assistants/errors.js index 1ae12ea3d5..f8dcf39f2b 100644 --- a/api/server/controllers/assistants/errors.js +++ b/api/server/controllers/assistants/errors.js @@ -3,8 +3,8 @@ const { logger } = require('@librechat/data-schemas'); const { CacheKeys, ViolationTypes, ContentTypes } = require('librechat-data-provider'); const { recordUsage, checkMessageGaps } = require('~/server/services/Threads'); const { sendResponse } = require('~/server/middleware/error'); -const { getConvo } = require('~/models/Conversation'); const getLogStores = require('~/cache/getLogStores'); +const { getConvo } = require('~/models'); /** * @typedef {Object} ErrorHandlerContext diff --git a/api/server/controllers/assistants/helpers.js b/api/server/controllers/assistants/helpers.js index 9183680f1e..4630bfe7ef 100644 --- a/api/server/controllers/assistants/helpers.js +++ b/api/server/controllers/assistants/helpers.js @@ -1,13 +1,14 @@ const { - SystemRoles, EModelEndpoint, defaultOrderQuery, defaultAssistantsVersion, } = require('librechat-data-provider'); +const { logger, SystemCapabilities } = require('@librechat/data-schemas'); const { initializeClient: initAzureClient, } = require('~/server/services/Endpoints/azureAssistants'); const { initializeClient } = require('~/server/services/Endpoints/assistants'); +const { hasCapability } = require('~/server/middleware/roles/capabilities'); const { getEndpointsConfig } = require('~/server/services/Config'); /** @@ -236,9 +237,19 @@ const fetchAssistants = async ({ req, res, overrideEndpoint }) => { body = await listAssistantsForAzure({ req, res, version, azureConfig, query }); } - if (req.user.role === SystemRoles.ADMIN) { + if (!appConfig.endpoints?.[endpoint]) { return body; - } else if (!appConfig.endpoints?.[endpoint]) { + } + + let canManageAssistants = false; + try { + canManageAssistants = await hasCapability(req.user, SystemCapabilities.MANAGE_ASSISTANTS); + } catch (err) { + logger.warn(`[fetchAssistants] capability check failed, denying bypass: ${err.message}`); + } + + if (canManageAssistants) { + logger.debug(`[fetchAssistants] MANAGE_ASSISTANTS bypass for user ${req.user.id}`); return body; } diff --git a/api/server/controllers/assistants/v1.js b/api/server/controllers/assistants/v1.js index 5d13d30334..c441b7ec59 100644 --- a/api/server/controllers/assistants/v1.js +++ b/api/server/controllers/assistants/v1.js @@ -1,15 +1,14 @@ const fs = require('fs').promises; const { logger } = require('@librechat/data-schemas'); const { FileContext } = require('librechat-data-provider'); +const { deleteFileByFilter, updateAssistantDoc, getAssistants } = require('~/models'); const { uploadImageBuffer, filterFile } = require('~/server/services/Files/process'); const validateAuthor = require('~/server/middleware/assistants/validateAuthor'); const { getStrategyFunctions } = require('~/server/services/Files/strategies'); const { deleteAssistantActions } = require('~/server/services/ActionService'); -const { updateAssistantDoc, getAssistants } = require('~/models/Assistant'); const { getOpenAIClient, fetchAssistants } = require('./helpers'); const { getCachedTools } = require('~/server/services/Config'); const { manifestToolMap } = require('~/app/clients/tools'); -const { deleteFileByFilter } = require('~/models'); /** * Create an assistant. diff --git a/api/server/controllers/assistants/v2.js b/api/server/controllers/assistants/v2.js index b9c5cd709f..cc0e03916d 100644 --- a/api/server/controllers/assistants/v2.js +++ b/api/server/controllers/assistants/v2.js @@ -3,8 +3,8 @@ const { ToolCallTypes } = require('librechat-data-provider'); const validateAuthor = require('~/server/middleware/assistants/validateAuthor'); const { validateAndUpdateTool } = require('~/server/services/ActionService'); const { getCachedTools } = require('~/server/services/Config'); -const { updateAssistantDoc } = require('~/models/Assistant'); const { manifestToolMap } = require('~/app/clients/tools'); +const { updateAssistantDoc } = require('~/models'); const { getOpenAIClient } = require('./helpers'); /** diff --git a/api/server/controllers/auth/LogoutController.js b/api/server/controllers/auth/LogoutController.js index 039ed630c2..381bfc58b2 100644 --- a/api/server/controllers/auth/LogoutController.js +++ b/api/server/controllers/auth/LogoutController.js @@ -4,11 +4,27 @@ const { logger } = require('@librechat/data-schemas'); const { logoutUser } = require('~/server/services/AuthService'); const { getOpenIdConfig } = require('~/strategies'); +/** Parses and validates OPENID_MAX_LOGOUT_URL_LENGTH, returning defaultValue on invalid input */ +function parseMaxLogoutUrlLength(defaultValue = 2000) { + const raw = process.env.OPENID_MAX_LOGOUT_URL_LENGTH; + const trimmed = raw == null ? '' : raw.trim(); + if (trimmed === '') { + return defaultValue; + } + const parsed = /^\d+$/.test(trimmed) ? Number(trimmed) : NaN; + if (!Number.isFinite(parsed) || parsed <= 0) { + logger.warn( + `[logoutController] Invalid OPENID_MAX_LOGOUT_URL_LENGTH value "${raw}", using default ${defaultValue}`, + ); + return defaultValue; + } + return parsed; +} + 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 tokens from session (with cookie fallback) */ let refreshToken; let idToken; if (isOpenIdUser && req.session?.openidTokens) { @@ -44,22 +60,64 @@ const logoutController = async (req, res) => { 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 */ + /** + * OIDC RP-Initiated Logout cascading strategy: + * 1. id_token_hint (most secure, identifies exact session) + * 2. logout_hint + client_id (when URL would exceed safe length) + * 3. client_id only (when no token available) + * + * JWT tokens from spec-compliant OIDC providers use base64url + * encoding (RFC 7515), whose characters are all URL-safe, so + * token length equals URL-encoded length for projection. + * Non-compliant issuers using standard base64 (+/=) will cause + * underestimation; increase OPENID_MAX_LOGOUT_URL_LENGTH if the + * fallback does not trigger as expected. + */ + const maxLogoutUrlLength = parseMaxLogoutUrlLength(); + let strategy = 'no_token'; if (idToken) { + const baseLength = endSessionUrl.toString().length; + const projectedLength = baseLength + '&id_token_hint='.length + idToken.length; + if (projectedLength > maxLogoutUrlLength) { + strategy = 'too_long'; + logger.debug( + `[logoutController] Logout URL too long (${projectedLength} chars, max ${maxLogoutUrlLength}), ` + + 'switching to logout_hint strategy', + ); + } else { + strategy = 'use_token'; + } + } + + if (strategy === 'use_token') { 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.', - ); + if (strategy === 'too_long') { + const logoutHint = req.user?.email || req.user?.username || req.user?.openidId; + if (logoutHint) { + endSessionUrl.searchParams.set('logout_hint', logoutHint); + } + } + + if (process.env.OPENID_CLIENT_ID) { + endSessionUrl.searchParams.set('client_id', process.env.OPENID_CLIENT_ID); + } else if (strategy === 'too_long') { + logger.warn( + '[logoutController] Logout URL exceeds max length and OPENID_CLIENT_ID is not set. ' + + 'The OIDC end-session request may be rejected. ' + + 'Consider setting OPENID_CLIENT_ID or increasing OPENID_MAX_LOGOUT_URL_LENGTH.', + ); + } 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(); diff --git a/api/server/controllers/auth/LogoutController.spec.js b/api/server/controllers/auth/LogoutController.spec.js index 3f2a2de8e1..c9294fdcec 100644 --- a/api/server/controllers/auth/LogoutController.spec.js +++ b/api/server/controllers/auth/LogoutController.spec.js @@ -1,7 +1,7 @@ const cookies = require('cookie'); const mockLogoutUser = jest.fn(); -const mockLogger = { warn: jest.fn(), error: jest.fn() }; +const mockLogger = { warn: jest.fn(), error: jest.fn(), debug: jest.fn() }; const mockIsEnabled = jest.fn(); const mockGetOpenIdConfig = jest.fn(); @@ -256,4 +256,312 @@ describe('LogoutController', () => { expect(res.clearCookie).toHaveBeenCalledWith('token_provider'); }); }); + + describe('URL length limit and logout_hint fallback', () => { + it('uses logout_hint when id_token makes URL exceed default limit (2000 chars)', async () => { + const longIdToken = 'a'.repeat(3000); + const req = buildReq({ + user: { _id: 'user1', openidId: 'oid1', provider: 'openid', email: 'user@example.com' }, + session: { + openidTokens: { refreshToken: 'srt', idToken: longIdToken }, + destroy: jest.fn(), + }, + }); + const res = buildRes(); + + await logoutController(req, res); + + const body = res.send.mock.calls[0][0]; + expect(body.redirect).not.toContain('id_token_hint='); + expect(body.redirect).toContain('logout_hint=user%40example.com'); + expect(body.redirect).toContain('client_id=my-client-id'); + expect(mockLogger.debug).toHaveBeenCalledWith(expect.stringContaining('Logout URL too long')); + }); + + it('uses id_token_hint when URL is within default limit', async () => { + const shortIdToken = 'short-token'; + const req = buildReq({ + session: { + openidTokens: { refreshToken: 'srt', idToken: shortIdToken }, + 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=short-token'); + expect(body.redirect).not.toContain('logout_hint='); + expect(body.redirect).not.toContain('client_id='); + }); + + it('respects custom OPENID_MAX_LOGOUT_URL_LENGTH', async () => { + process.env.OPENID_MAX_LOGOUT_URL_LENGTH = '500'; + const mediumIdToken = 'a'.repeat(600); + const req = buildReq({ + user: { _id: 'user1', openidId: 'oid1', provider: 'openid', email: 'user@example.com' }, + session: { + openidTokens: { refreshToken: 'srt', idToken: mediumIdToken }, + destroy: jest.fn(), + }, + }); + const res = buildRes(); + + await logoutController(req, res); + + const body = res.send.mock.calls[0][0]; + expect(body.redirect).not.toContain('id_token_hint='); + expect(body.redirect).toContain('logout_hint=user%40example.com'); + }); + + it('uses username as logout_hint when email is not available', async () => { + const longIdToken = 'a'.repeat(3000); + const req = buildReq({ + user: { + _id: 'user1', + openidId: 'oid1', + provider: 'openid', + username: 'testuser', + }, + session: { + openidTokens: { refreshToken: 'srt', idToken: longIdToken }, + destroy: jest.fn(), + }, + }); + const res = buildRes(); + + await logoutController(req, res); + + const body = res.send.mock.calls[0][0]; + expect(body.redirect).toContain('logout_hint=testuser'); + }); + + it('uses openidId as logout_hint when email and username are not available', async () => { + const longIdToken = 'a'.repeat(3000); + const req = buildReq({ + user: { _id: 'user1', openidId: 'unique-oid-123', provider: 'openid' }, + session: { + openidTokens: { refreshToken: 'srt', idToken: longIdToken }, + destroy: jest.fn(), + }, + }); + const res = buildRes(); + + await logoutController(req, res); + + const body = res.send.mock.calls[0][0]; + expect(body.redirect).toContain('logout_hint=unique-oid-123'); + }); + + it('uses openidId as logout_hint when email and username are explicitly null', async () => { + const longIdToken = 'a'.repeat(3000); + const req = buildReq({ + user: { + _id: 'user1', + openidId: 'oid-without-email', + provider: 'openid', + email: null, + username: null, + }, + session: { + openidTokens: { refreshToken: 'srt', idToken: longIdToken }, + destroy: jest.fn(), + }, + }); + const res = buildRes(); + + await logoutController(req, res); + + const body = res.send.mock.calls[0][0]; + expect(body.redirect).not.toContain('id_token_hint='); + expect(body.redirect).toContain('logout_hint=oid-without-email'); + expect(body.redirect).toContain('client_id=my-client-id'); + }); + + it('uses only client_id when absolutely no hint is available', async () => { + const longIdToken = 'a'.repeat(3000); + const req = buildReq({ + user: { + _id: 'user1', + openidId: '', + provider: 'openid', + email: '', + username: '', + }, + session: { + openidTokens: { refreshToken: 'srt', idToken: longIdToken }, + destroy: jest.fn(), + }, + }); + const res = buildRes(); + + await logoutController(req, res); + + const body = res.send.mock.calls[0][0]; + expect(body.redirect).not.toContain('id_token_hint='); + expect(body.redirect).not.toContain('logout_hint='); + expect(body.redirect).toContain('client_id=my-client-id'); + }); + + it('warns about missing OPENID_CLIENT_ID when URL is too long', async () => { + delete process.env.OPENID_CLIENT_ID; + const longIdToken = 'a'.repeat(3000); + const req = buildReq({ + user: { _id: 'user1', openidId: 'oid1', provider: 'openid', email: 'user@example.com' }, + session: { + openidTokens: { refreshToken: 'srt', idToken: longIdToken }, + destroy: jest.fn(), + }, + }); + const res = buildRes(); + + await logoutController(req, res); + + const body = res.send.mock.calls[0][0]; + expect(body.redirect).not.toContain('id_token_hint='); + expect(body.redirect).toContain('logout_hint='); + expect(body.redirect).not.toContain('client_id='); + expect(mockLogger.warn).toHaveBeenCalledWith( + expect.stringContaining('OPENID_CLIENT_ID is not set'), + ); + }); + + it('falls back to logout_hint for cookie-sourced long token', async () => { + const longCookieToken = 'a'.repeat(3000); + cookies.parse.mockReturnValue({ + refreshToken: 'cookie-rt', + openid_id_token: longCookieToken, + }); + const req = buildReq({ + user: { _id: 'user1', openidId: 'oid1', provider: 'openid', email: 'user@example.com' }, + session: { destroy: jest.fn() }, + }); + const res = buildRes(); + + await logoutController(req, res); + + const body = res.send.mock.calls[0][0]; + expect(body.redirect).not.toContain('id_token_hint='); + expect(body.redirect).toContain('logout_hint=user%40example.com'); + expect(body.redirect).toContain('client_id=my-client-id'); + }); + + it('keeps id_token_hint when projected URL length equals the max', async () => { + const baseUrl = new URL('https://idp.example.com/logout'); + baseUrl.searchParams.set('post_logout_redirect_uri', 'https://app.example.com/login'); + const baseLength = baseUrl.toString().length; + const tokenLength = 2000 - baseLength - '&id_token_hint='.length; + const exactToken = 'a'.repeat(tokenLength); + + const req = buildReq({ + session: { + openidTokens: { refreshToken: 'srt', idToken: exactToken }, + 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='); + expect(body.redirect).not.toContain('logout_hint='); + }); + + it('falls back to logout_hint when projected URL is one char over the max', async () => { + const baseUrl = new URL('https://idp.example.com/logout'); + baseUrl.searchParams.set('post_logout_redirect_uri', 'https://app.example.com/login'); + const baseLength = baseUrl.toString().length; + const tokenLength = 2000 - baseLength - '&id_token_hint='.length + 1; + const overToken = 'a'.repeat(tokenLength); + + const req = buildReq({ + user: { _id: 'user1', openidId: 'oid1', provider: 'openid', email: 'user@example.com' }, + session: { + openidTokens: { refreshToken: 'srt', idToken: overToken }, + destroy: jest.fn(), + }, + }); + const res = buildRes(); + + await logoutController(req, res); + + const body = res.send.mock.calls[0][0]; + expect(body.redirect).not.toContain('id_token_hint='); + expect(body.redirect).toContain('logout_hint='); + }); + }); + + describe('invalid OPENID_MAX_LOGOUT_URL_LENGTH values', () => { + it('silently uses default when value is empty', async () => { + process.env.OPENID_MAX_LOGOUT_URL_LENGTH = ''; + const req = buildReq(); + const res = buildRes(); + + await logoutController(req, res); + + expect(mockLogger.warn).not.toHaveBeenCalledWith( + expect.stringContaining('Invalid OPENID_MAX_LOGOUT_URL_LENGTH'), + ); + const body = res.send.mock.calls[0][0]; + expect(body.redirect).toContain('id_token_hint=small-id-token'); + }); + + it('warns and uses default for partial numeric string', async () => { + process.env.OPENID_MAX_LOGOUT_URL_LENGTH = '500abc'; + const req = buildReq(); + const res = buildRes(); + + await logoutController(req, res); + + expect(mockLogger.warn).toHaveBeenCalledWith( + expect.stringContaining('Invalid OPENID_MAX_LOGOUT_URL_LENGTH'), + ); + const body = res.send.mock.calls[0][0]; + expect(body.redirect).toContain('id_token_hint=small-id-token'); + }); + + it('warns and uses default for zero value', async () => { + process.env.OPENID_MAX_LOGOUT_URL_LENGTH = '0'; + const req = buildReq(); + const res = buildRes(); + + await logoutController(req, res); + + expect(mockLogger.warn).toHaveBeenCalledWith( + expect.stringContaining('Invalid OPENID_MAX_LOGOUT_URL_LENGTH'), + ); + const body = res.send.mock.calls[0][0]; + expect(body.redirect).toContain('id_token_hint=small-id-token'); + }); + + it('warns and uses default for negative value', async () => { + process.env.OPENID_MAX_LOGOUT_URL_LENGTH = '-1'; + const req = buildReq(); + const res = buildRes(); + + await logoutController(req, res); + + expect(mockLogger.warn).toHaveBeenCalledWith( + expect.stringContaining('Invalid OPENID_MAX_LOGOUT_URL_LENGTH'), + ); + const body = res.send.mock.calls[0][0]; + expect(body.redirect).toContain('id_token_hint=small-id-token'); + }); + + it('warns and uses default for non-numeric string', async () => { + process.env.OPENID_MAX_LOGOUT_URL_LENGTH = 'abc'; + const req = buildReq(); + const res = buildRes(); + + await logoutController(req, res); + + expect(mockLogger.warn).toHaveBeenCalledWith( + expect.stringContaining('Invalid OPENID_MAX_LOGOUT_URL_LENGTH'), + ); + const body = res.send.mock.calls[0][0]; + expect(body.redirect).toContain('id_token_hint=small-id-token'); + }); + }); }); 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/controllers/tools.js b/api/server/controllers/tools.js index 14a757e2bc..1df11b1059 100644 --- a/api/server/controllers/tools.js +++ b/api/server/controllers/tools.js @@ -9,13 +9,11 @@ const { ToolCallTypes, PermissionTypes, } = require('librechat-data-provider'); +const { getRoleByName, createToolCall, getToolCallsByConvo, getMessage } = require('~/models'); const { processFileURL, uploadImageBuffer } = require('~/server/services/Files/process'); const { processCodeOutput } = require('~/server/services/Files/Code/process'); -const { createToolCall, getToolCallsByConvo } = require('~/models/ToolCall'); const { loadAuthValues } = require('~/server/services/Tools/credentials'); const { loadTools } = require('~/app/clients/tools/util'); -const { getRoleByName } = require('~/models/Role'); -const { getMessage } = require('~/models/Message'); const fieldsMap = { [Tools.execute_code]: [EnvVar.CODE_API_KEY], diff --git a/api/server/experimental.js b/api/server/experimental.js index 7b60ad7fd2..8982b69afb 100644 --- a/api/server/experimental.js +++ b/api/server/experimental.js @@ -24,14 +24,14 @@ const { connectDb, indexSync } = require('~/db'); const initializeOAuthReconnectManager = require('./services/initializeOAuthReconnectManager'); const createValidateImageRequest = require('./middleware/validateImageRequest'); const { jwtLogin, ldapLogin, passportLogin } = require('~/strategies'); -const { updateInterfacePermissions } = require('~/models/interface'); +const { updateInterfacePermissions: updateInterfacePerms } = require('@librechat/api'); +const { getRoleByName, updateAccessPermissions, seedDatabase } = require('~/models'); const { checkMigrations } = require('./services/start/migration'); const initializeMCPs = require('./services/initializeMCPs'); const configureSocialLogins = require('./socialLogins'); const { getAppConfig } = require('./services/Config'); const staticCache = require('./utils/staticCache'); const noIndex = require('./middleware/noIndex'); -const { seedDatabase } = require('~/models'); const routes = require('./routes'); const { PORT, HOST, ALLOW_SOCIAL_LOGIN, DISABLE_COMPRESSION, TRUST_PROXY } = process.env ?? {}; @@ -222,7 +222,7 @@ if (cluster.isMaster) { const appConfig = await getAppConfig(); initializeFileStorage(appConfig); await performStartupChecks(appConfig); - await updateInterfacePermissions(appConfig); + await updateInterfacePerms({ appConfig, getRoleByName, updateAccessPermissions }); /** Load index.html for SPA serving */ const indexPath = path.join(appConfig.paths.dist, 'index.html'); diff --git a/api/server/index.js b/api/server/index.js index f034f10236..ba376ab335 100644 --- a/api/server/index.js +++ b/api/server/index.js @@ -20,19 +20,20 @@ const { GenerationJobManager, createStreamServices, initializeFileStorage, + updateInterfacePermissions, } = require('@librechat/api'); const { connectDb, indexSync } = require('~/db'); const initializeOAuthReconnectManager = require('./services/initializeOAuthReconnectManager'); +const { getRoleByName, updateAccessPermissions, seedDatabase } = require('~/models'); +const { capabilityContextMiddleware } = require('./middleware/roles/capabilities'); const createValidateImageRequest = require('./middleware/validateImageRequest'); const { jwtLogin, ldapLogin, passportLogin } = require('~/strategies'); -const { updateInterfacePermissions } = require('~/models/interface'); const { checkMigrations } = require('./services/start/migration'); const initializeMCPs = require('./services/initializeMCPs'); const configureSocialLogins = require('./socialLogins'); const { getAppConfig } = require('./services/Config'); const staticCache = require('./utils/staticCache'); const noIndex = require('./middleware/noIndex'); -const { seedDatabase } = require('~/models'); const routes = require('./routes'); const { PORT, HOST, ALLOW_SOCIAL_LOGIN, DISABLE_COMPRESSION, TRUST_PROXY } = process.env ?? {}; @@ -62,7 +63,7 @@ const startServer = async () => { const appConfig = await getAppConfig(); initializeFileStorage(appConfig); await performStartupChecks(appConfig); - await updateInterfacePermissions(appConfig); + await updateInterfacePermissions({ appConfig, getRoleByName, updateAccessPermissions }); const indexPath = path.join(appConfig.paths.dist, 'index.html'); let indexHTML = fs.readFileSync(indexPath, 'utf8'); @@ -133,6 +134,9 @@ const startServer = async () => { await configureSocialLogins(app); } + /* Per-request capability cache — must be registered before any route that calls hasCapability */ + app.use(capabilityContextMiddleware); + app.use('/oauth', routes.oauth); /* API Endpoints */ app.use('/api/auth', routes.auth); diff --git a/api/server/middleware/abortMiddleware.js b/api/server/middleware/abortMiddleware.js index d39b0104a8..e0c5ae0ff0 100644 --- a/api/server/middleware/abortMiddleware.js +++ b/api/server/middleware/abortMiddleware.js @@ -1,4 +1,5 @@ const { logger } = require('@librechat/data-schemas'); +const { isAssistantsEndpoint, ErrorTypes } = require('librechat-data-provider'); const { isEnabled, sendEvent, @@ -7,14 +8,11 @@ const { 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 { abortRun } = require('./abortRun'); +const db = require('~/models'); /** * Spend tokens for all models from collected usage. @@ -44,10 +42,10 @@ async function spendCollectedUsage({ await recordCollectedUsage( { - spendTokens, - spendStructuredTokens, - pricing: { getMultiplier, getCacheMultiplier }, - bulkWriteOps: { insertMany: bulkInsertTransactions, updateBalance }, + spendTokens: db.spendTokens, + spendStructuredTokens: db.spendStructuredTokens, + pricing: { getMultiplier: db.getMultiplier, getCacheMultiplier: db.getCacheMultiplier }, + bulkWriteOps: { insertMany: db.bulkInsertTransactions, updateBalance: db.updateBalance }, }, { user: userId, @@ -123,20 +121,24 @@ async function abortMessage(req, res) { }); } else { // Fallback: no collected usage, use text-based token counting for primary model only - await spendTokens( + await db.spendTokens( { ...responseMessage, context: 'incomplete', user: userId }, { promptTokens, completionTokens }, ); } - await saveMessage( - req, + await db.saveMessage( + { + userId: req?.user?.id, + isTemporary: req?.body?.isTemporary, + interfaceConfig: req?.config?.interfaceConfig, + }, { ...responseMessage, user: userId }, { context: 'api/server/middleware/abortMiddleware.js' }, ); // Get conversation for title - const conversation = await getConvo(userId, conversationId); + const conversation = await db.getConvo(userId, conversationId); const finalEvent = { title: conversation && !conversation.title ? null : conversation?.title || 'New Chat', diff --git a/api/server/middleware/abortMiddleware.spec.js b/api/server/middleware/abortMiddleware.spec.js index 795814a928..a4ce85674b 100644 --- a/api/server/middleware/abortMiddleware.spec.js +++ b/api/server/middleware/abortMiddleware.spec.js @@ -20,16 +20,6 @@ const mockRecordCollectedUsage = jest 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(), @@ -73,6 +63,10 @@ jest.mock('~/models', () => ({ getConvo: jest.fn().mockResolvedValue({ title: 'Test Chat' }), updateBalance: mockUpdateBalance, bulkInsertTransactions: mockBulkInsertTransactions, + spendTokens: (...args) => mockSpendTokens(...args), + spendStructuredTokens: (...args) => mockSpendStructuredTokens(...args), + getMultiplier: mockGetMultiplier, + getCacheMultiplier: mockGetCacheMultiplier, })); jest.mock('./abortRun', () => ({ diff --git a/api/server/middleware/abortRun.js b/api/server/middleware/abortRun.js index 44375f5024..318693fe15 100644 --- a/api/server/middleware/abortRun.js +++ b/api/server/middleware/abortRun.js @@ -3,8 +3,7 @@ const { logger } = require('@librechat/data-schemas'); const { CacheKeys, RunStatus, isUUID } = require('librechat-data-provider'); const { initializeClient } = require('~/server/services/Endpoints/assistants'); const { checkMessageGaps, recordUsage } = require('~/server/services/Threads'); -const { deleteMessages } = require('~/models/Message'); -const { getConvo } = require('~/models/Conversation'); +const { deleteMessages, getConvo } = require('~/models'); const getLogStores = require('~/cache/getLogStores'); const three_minutes = 1000 * 60 * 3; diff --git a/api/server/middleware/accessResources/canAccessAgentFromBody.js b/api/server/middleware/accessResources/canAccessAgentFromBody.js index f8112af14d..5ade76bb77 100644 --- a/api/server/middleware/accessResources/canAccessAgentFromBody.js +++ b/api/server/middleware/accessResources/canAccessAgentFromBody.js @@ -1,42 +1,145 @@ 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 { getAgent } = require('~/models/Agent'); +const db = require('~/models'); + +const { getRoleByName, getAgent } = db; /** - * 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 +149,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 +171,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..9e5e0b093a --- /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'); + +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/accessResources/canAccessAgentResource.js b/api/server/middleware/accessResources/canAccessAgentResource.js index 62d9f248c0..4c00ab4982 100644 --- a/api/server/middleware/accessResources/canAccessAgentResource.js +++ b/api/server/middleware/accessResources/canAccessAgentResource.js @@ -1,6 +1,6 @@ const { ResourceType } = require('librechat-data-provider'); const { canAccessResource } = require('./canAccessResource'); -const { getAgent } = require('~/models/Agent'); +const { getAgent } = require('~/models'); /** * Agent ID resolver function diff --git a/api/server/middleware/accessResources/canAccessAgentResource.spec.js b/api/server/middleware/accessResources/canAccessAgentResource.spec.js index 1106390e72..786636ee74 100644 --- a/api/server/middleware/accessResources/canAccessAgentResource.spec.js +++ b/api/server/middleware/accessResources/canAccessAgentResource.spec.js @@ -3,7 +3,7 @@ const { ResourceType, PrincipalType, PrincipalModel } = require('librechat-data- const { MongoMemoryServer } = require('mongodb-memory-server'); const { canAccessAgentResource } = require('./canAccessAgentResource'); const { User, Role, AclEntry } = require('~/db/models'); -const { createAgent } = require('~/models/Agent'); +const { createAgent } = require('~/models'); describe('canAccessAgentResource middleware', () => { let mongoServer; @@ -373,7 +373,7 @@ describe('canAccessAgentResource middleware', () => { jest.clearAllMocks(); // Update the agent - const { updateAgent } = require('~/models/Agent'); + const { updateAgent } = require('~/models'); await updateAgent({ id: agentId }, { description: 'Updated description' }); // Test edit access diff --git a/api/server/middleware/accessResources/canAccessMCPServerResource.spec.js b/api/server/middleware/accessResources/canAccessMCPServerResource.spec.js index 77508be2d1..6f7e4ab506 100644 --- a/api/server/middleware/accessResources/canAccessMCPServerResource.spec.js +++ b/api/server/middleware/accessResources/canAccessMCPServerResource.spec.js @@ -1,8 +1,9 @@ const mongoose = require('mongoose'); const { ResourceType, PrincipalType, PrincipalModel } = require('librechat-data-provider'); +const { SystemCapabilities } = require('@librechat/data-schemas'); const { MongoMemoryServer } = require('mongodb-memory-server'); const { canAccessMCPServerResource } = require('./canAccessMCPServerResource'); -const { User, Role, AclEntry } = require('~/db/models'); +const { User, Role, AclEntry, SystemGrant } = require('~/db/models'); const { createMCPServer } = require('~/models'); describe('canAccessMCPServerResource middleware', () => { @@ -511,7 +512,7 @@ describe('canAccessMCPServerResource middleware', () => { }); }); - test('should allow admin users to bypass permission checks', async () => { + test('should allow users with MANAGE_MCP_SERVERS capability to bypass permission checks', async () => { const { SystemRoles } = require('librechat-data-provider'); // Create an MCP server owned by another user @@ -531,6 +532,14 @@ describe('canAccessMCPServerResource middleware', () => { author: otherUser._id, }); + // Seed MANAGE_MCP_SERVERS capability for the ADMIN role + await SystemGrant.create({ + principalType: PrincipalType.ROLE, + principalId: SystemRoles.ADMIN, + capability: SystemCapabilities.MANAGE_MCP_SERVERS, + grantedAt: new Date(), + }); + // Set user as admin req.user = { id: testUser._id, role: SystemRoles.ADMIN }; req.params.serverName = mcpServer.serverName; diff --git a/api/server/middleware/accessResources/canAccessPromptGroupResource.js b/api/server/middleware/accessResources/canAccessPromptGroupResource.js index 90aa280772..9da1994a77 100644 --- a/api/server/middleware/accessResources/canAccessPromptGroupResource.js +++ b/api/server/middleware/accessResources/canAccessPromptGroupResource.js @@ -1,6 +1,6 @@ const { ResourceType } = require('librechat-data-provider'); const { canAccessResource } = require('./canAccessResource'); -const { getPromptGroup } = require('~/models/Prompt'); +const { getPromptGroup } = require('~/models'); /** * PromptGroup ID resolver function diff --git a/api/server/middleware/accessResources/canAccessPromptViaGroup.js b/api/server/middleware/accessResources/canAccessPromptViaGroup.js index 0bb0a804a9..534db3d6c6 100644 --- a/api/server/middleware/accessResources/canAccessPromptViaGroup.js +++ b/api/server/middleware/accessResources/canAccessPromptViaGroup.js @@ -1,6 +1,6 @@ const { ResourceType } = require('librechat-data-provider'); const { canAccessResource } = require('./canAccessResource'); -const { getPrompt } = require('~/models/Prompt'); +const { getPrompt } = require('~/models'); /** * Prompt to PromptGroup ID resolver function diff --git a/api/server/middleware/accessResources/canAccessResource.js b/api/server/middleware/accessResources/canAccessResource.js index c8bd15ffc2..2431971b2f 100644 --- a/api/server/middleware/accessResources/canAccessResource.js +++ b/api/server/middleware/accessResources/canAccessResource.js @@ -1,5 +1,5 @@ -const { logger } = require('@librechat/data-schemas'); -const { SystemRoles } = require('librechat-data-provider'); +const { logger, ResourceCapabilityMap } = require('@librechat/data-schemas'); +const { hasCapability } = require('~/server/middleware/roles/capabilities'); const { checkPermission } = require('~/server/services/PermissionService'); /** @@ -71,8 +71,17 @@ const canAccessResource = (options) => { message: 'Authentication required', }); } - // if system admin let through - if (req.user.role === SystemRoles.ADMIN) { + const cap = ResourceCapabilityMap[resourceType]; + let hasCap = false; + try { + hasCap = cap != null && (await hasCapability(req.user, cap)); + } catch (err) { + logger.warn(`[canAccessResource] capability check failed, denying bypass: ${err.message}`); + } + if (hasCap) { + logger.debug( + `[canAccessResource] ${cap} bypass for user ${req.user.id} on ${resourceType} ${rawResourceId}`, + ); return next(); } const userId = req.user.id; diff --git a/api/server/middleware/accessResources/fileAccess.js b/api/server/middleware/accessResources/fileAccess.js index 25d41e7c02..0f77a61175 100644 --- a/api/server/middleware/accessResources/fileAccess.js +++ b/api/server/middleware/accessResources/fileAccess.js @@ -1,8 +1,7 @@ const { logger } = require('@librechat/data-schemas'); const { PermissionBits, hasPermissions, ResourceType } = require('librechat-data-provider'); const { getEffectivePermissions } = require('~/server/services/PermissionService'); -const { getAgents } = require('~/models/Agent'); -const { getFiles } = require('~/models'); +const { getAgents, getFiles } = require('~/models'); /** * Checks if user has access to a file through agent permissions diff --git a/api/server/middleware/accessResources/fileAccess.spec.js b/api/server/middleware/accessResources/fileAccess.spec.js index cc0d57ac48..72896b0629 100644 --- a/api/server/middleware/accessResources/fileAccess.spec.js +++ b/api/server/middleware/accessResources/fileAccess.spec.js @@ -3,8 +3,7 @@ const { ResourceType, PrincipalType, PrincipalModel } = require('librechat-data- const { MongoMemoryServer } = require('mongodb-memory-server'); const { fileAccess } = require('./fileAccess'); const { User, Role, AclEntry } = require('~/db/models'); -const { createAgent } = require('~/models/Agent'); -const { createFile } = require('~/models'); +const { createAgent, createFile } = require('~/models'); describe('fileAccess middleware', () => { let mongoServer; diff --git a/api/server/middleware/assistants/validateAuthor.js b/api/server/middleware/assistants/validateAuthor.js index 03936444e0..024d6abbe3 100644 --- a/api/server/middleware/assistants/validateAuthor.js +++ b/api/server/middleware/assistants/validateAuthor.js @@ -1,5 +1,6 @@ -const { SystemRoles } = require('librechat-data-provider'); -const { getAssistant } = require('~/models/Assistant'); +const { logger, SystemCapabilities } = require('@librechat/data-schemas'); +const { hasCapability } = require('~/server/middleware/roles/capabilities'); +const { getAssistant } = require('~/models'); /** * Checks if the assistant is supported or excluded @@ -12,10 +13,6 @@ const { getAssistant } = require('~/models/Assistant'); * @returns {Promise} */ const validateAuthor = async ({ req, openai, overrideEndpoint, overrideAssistantId }) => { - if (req.user.role === SystemRoles.ADMIN) { - return; - } - const endpoint = overrideEndpoint ?? req.body.endpoint ?? req.query.endpoint; const assistant_id = overrideAssistantId ?? req.params.id ?? req.body.assistant_id ?? req.query.assistant_id; @@ -31,6 +28,18 @@ const validateAuthor = async ({ req, openai, overrideEndpoint, overrideAssistant return; } + let canManageAssistants = false; + try { + canManageAssistants = await hasCapability(req.user, SystemCapabilities.MANAGE_ASSISTANTS); + } catch (err) { + logger.warn(`[validateAuthor] capability check failed, denying bypass: ${err.message}`); + } + + if (canManageAssistants) { + logger.debug(`[validateAuthor] MANAGE_ASSISTANTS bypass for user ${req.user.id}`); + return; + } + const assistantDoc = await getAssistant({ assistant_id, user: req.user.id }); if (assistantDoc) { return; diff --git a/api/server/middleware/canDeleteAccount.js b/api/server/middleware/canDeleteAccount.js index a913495287..3c08745d76 100644 --- a/api/server/middleware/canDeleteAccount.js +++ b/api/server/middleware/canDeleteAccount.js @@ -1,6 +1,6 @@ const { isEnabled } = require('@librechat/api'); -const { logger } = require('@librechat/data-schemas'); -const { SystemRoles } = require('librechat-data-provider'); +const { logger, SystemCapabilities } = require('@librechat/data-schemas'); +const { hasCapability } = require('~/server/middleware/roles/capabilities'); /** * Checks if the user can delete their account @@ -17,12 +17,29 @@ const { SystemRoles } = require('librechat-data-provider'); const canDeleteAccount = async (req, res, next = () => {}) => { const { user } = req; const { ALLOW_ACCOUNT_DELETION = true } = process.env; - if (user?.role === SystemRoles.ADMIN || isEnabled(ALLOW_ACCOUNT_DELETION)) { + if (isEnabled(ALLOW_ACCOUNT_DELETION)) { return next(); - } else { - logger.error(`[User] [Delete Account] [User cannot delete account] [User: ${user?.id}]`); - return res.status(403).send({ message: 'You do not have permission to delete this account' }); } + let hasAdminAccess = false; + if (user) { + try { + const id = user.id ?? user._id?.toString(); + if (id) { + hasAdminAccess = await hasCapability( + { id, role: user.role ?? '', tenantId: user.tenantId }, + SystemCapabilities.ACCESS_ADMIN, + ); + } + } catch (err) { + logger.warn(`[canDeleteAccount] capability check failed, denying: ${err.message}`); + } + } + if (hasAdminAccess) { + logger.debug(`[canDeleteAccount] ACCESS_ADMIN bypass for user ${user.id}`); + return next(); + } + logger.error(`[User] [Delete Account] [User cannot delete account] [User: ${user?.id}]`); + return res.status(403).send({ message: 'You do not have permission to delete this account' }); }; module.exports = canDeleteAccount; diff --git a/api/server/middleware/canDeleteAccount.spec.js b/api/server/middleware/canDeleteAccount.spec.js new file mode 100644 index 0000000000..abb888c4a4 --- /dev/null +++ b/api/server/middleware/canDeleteAccount.spec.js @@ -0,0 +1,180 @@ +const mongoose = require('mongoose'); +const { MongoMemoryServer } = require('mongodb-memory-server'); +const { SystemRoles, PrincipalType } = require('librechat-data-provider'); +const { SystemCapabilities } = require('@librechat/data-schemas'); + +jest.mock('@librechat/data-schemas', () => ({ + ...jest.requireActual('@librechat/data-schemas'), + logger: { error: jest.fn(), warn: jest.fn(), debug: jest.fn(), info: jest.fn() }, +})); + +jest.mock('~/cache', () => ({ + getLogStores: jest.fn(() => ({ + get: jest.fn(), + set: jest.fn(), + })), +})); + +const { User, SystemGrant } = require('~/db/models'); +const canDeleteAccount = require('./canDeleteAccount'); + +let mongoServer; + +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(); + delete process.env.ALLOW_ACCOUNT_DELETION; +}); + +const makeRes = () => { + const send = jest.fn(); + const status = jest.fn().mockReturnValue({ send }); + return { status, send }; +}; + +describe('canDeleteAccount', () => { + describe('ALLOW_ACCOUNT_DELETION=true (default)', () => { + it('calls next without hitting the DB', async () => { + process.env.ALLOW_ACCOUNT_DELETION = 'true'; + const next = jest.fn(); + const req = { user: { id: 'user-1', role: SystemRoles.USER } }; + + await canDeleteAccount(req, makeRes(), next); + + expect(next).toHaveBeenCalled(); + }); + + it('skips capability check entirely when deletion is allowed', async () => { + process.env.ALLOW_ACCOUNT_DELETION = 'true'; + const next = jest.fn(); + const req = { user: { id: 'user-1', role: SystemRoles.USER } }; + + await canDeleteAccount(req, makeRes(), next); + + expect(next).toHaveBeenCalled(); + const grantCount = await SystemGrant.countDocuments(); + expect(grantCount).toBe(0); + }); + }); + + describe('ALLOW_ACCOUNT_DELETION=false', () => { + beforeEach(() => { + process.env.ALLOW_ACCOUNT_DELETION = 'false'; + }); + + it('allows admin with ACCESS_ADMIN grant (real DB check)', async () => { + const admin = await User.create({ + name: 'Admin', + email: 'admin@test.com', + password: 'password123', + provider: 'local', + role: SystemRoles.ADMIN, + }); + + await SystemGrant.create({ + principalType: PrincipalType.ROLE, + principalId: SystemRoles.ADMIN, + capability: SystemCapabilities.ACCESS_ADMIN, + grantedAt: new Date(), + }); + + const next = jest.fn(); + const req = { user: { id: admin._id.toString(), role: SystemRoles.ADMIN } }; + + await canDeleteAccount(req, makeRes(), next); + + expect(next).toHaveBeenCalled(); + }); + + it('blocks regular user without ACCESS_ADMIN grant', async () => { + const user = await User.create({ + name: 'Regular', + email: 'user@test.com', + password: 'password123', + provider: 'local', + role: SystemRoles.USER, + }); + + const next = jest.fn(); + const res = makeRes(); + const req = { user: { id: user._id.toString(), role: SystemRoles.USER } }; + + await canDeleteAccount(req, res, next); + + expect(next).not.toHaveBeenCalled(); + expect(res.status).toHaveBeenCalledWith(403); + }); + + it('blocks admin role WITHOUT the ACCESS_ADMIN grant', async () => { + const admin = await User.create({ + name: 'Admin No Grant', + email: 'admin2@test.com', + password: 'password123', + provider: 'local', + role: SystemRoles.ADMIN, + }); + + const next = jest.fn(); + const res = makeRes(); + const req = { user: { id: admin._id.toString(), role: SystemRoles.ADMIN } }; + + await canDeleteAccount(req, res, next); + + expect(next).not.toHaveBeenCalled(); + expect(res.status).toHaveBeenCalledWith(403); + }); + + it('allows user-level grant (not just role-level)', async () => { + const user = await User.create({ + name: 'Privileged User', + email: 'priv@test.com', + password: 'password123', + provider: 'local', + role: SystemRoles.USER, + }); + + await SystemGrant.create({ + principalType: PrincipalType.USER, + principalId: user._id, + capability: SystemCapabilities.ACCESS_ADMIN, + grantedAt: new Date(), + }); + + const next = jest.fn(); + const req = { user: { id: user._id.toString(), role: SystemRoles.USER } }; + + await canDeleteAccount(req, makeRes(), next); + + expect(next).toHaveBeenCalled(); + }); + + it('blocks when user is undefined — does not throw', async () => { + const next = jest.fn(); + const res = makeRes(); + + await canDeleteAccount({ user: undefined }, res, next); + + expect(next).not.toHaveBeenCalled(); + expect(res.status).toHaveBeenCalledWith(403); + }); + + it('blocks when user is null — does not throw', async () => { + const next = jest.fn(); + const res = makeRes(); + + await canDeleteAccount({ user: null }, res, next); + + expect(next).not.toHaveBeenCalled(); + expect(res.status).toHaveBeenCalledWith(403); + }); + }); +}); diff --git a/api/server/middleware/checkBan.js b/api/server/middleware/checkBan.js index 79804a84e1..5d1b60297f 100644 --- a/api/server/middleware/checkBan.js +++ b/api/server/middleware/checkBan.js @@ -1,16 +1,23 @@ const { Keyv } = require('keyv'); const uap = require('ua-parser-js'); const { logger } = require('@librechat/data-schemas'); -const { isEnabled, keyvMongo } = require('@librechat/api'); const { ViolationTypes } = require('librechat-data-provider'); -const { removePorts } = require('~/server/utils'); -const denyRequest = require('./denyRequest'); +const { isEnabled, keyvMongo, removePorts } = require('@librechat/api'); const { getLogStores } = require('~/cache'); +const denyRequest = require('./denyRequest'); const { findUser } = require('~/models'); const banCache = new Keyv({ store: keyvMongo, namespace: ViolationTypes.BAN, ttl: 0 }); const message = 'Your account has been temporarily banned due to violations of our service.'; +/** @returns {string} Cache key for ban lookups, prefixed for Redis or raw for MongoDB */ +const getBanCacheKey = (prefix, value, useRedis) => { + if (!value) { + return ''; + } + return useRedis ? `ban_cache:${prefix}:${value}` : value; +}; + /** * Respond to the request if the user is banned. * @@ -64,25 +71,16 @@ const checkBan = async (req, res, next = () => {}) => { return next(); } - let cachedIPBan; - let cachedUserBan; + const useRedis = isEnabled(process.env.USE_REDIS); + const ipKey = getBanCacheKey('ip', req.ip, useRedis); + const userKey = getBanCacheKey('user', userId, useRedis); - let ipKey = ''; - let userKey = ''; + const [cachedIPBan, cachedUserBan] = await Promise.all([ + ipKey ? banCache.get(ipKey) : undefined, + userKey ? banCache.get(userKey) : undefined, + ]); - if (req.ip) { - ipKey = isEnabled(process.env.USE_REDIS) ? `ban_cache:ip:${req.ip}` : req.ip; - cachedIPBan = await banCache.get(ipKey); - } - - if (userId) { - userKey = isEnabled(process.env.USE_REDIS) ? `ban_cache:user:${userId}` : userId; - cachedUserBan = await banCache.get(userKey); - } - - const cachedBan = cachedIPBan || cachedUserBan; - - if (cachedBan) { + if (cachedIPBan || cachedUserBan) { req.banned = true; return await banResponse(req, res); } @@ -94,41 +92,47 @@ const checkBan = async (req, res, next = () => {}) => { return next(); } - let ipBan; - let userBan; + const [ipBan, userBan] = await Promise.all([ + req.ip ? banLogs.get(req.ip) : undefined, + userId ? banLogs.get(userId) : undefined, + ]); - if (req.ip) { - ipBan = await banLogs.get(req.ip); - } + const banData = ipBan || userBan; - if (userId) { - userBan = await banLogs.get(userId); - } - - const isBanned = !!(ipBan || userBan); - - if (!isBanned) { + if (!banData) { return next(); } - const timeLeft = Number(isBanned.expiresAt) - Date.now(); - - if (timeLeft <= 0 && ipKey) { - await banLogs.delete(ipKey); + const expiresAt = Number(banData.expiresAt); + if (!banData.expiresAt || isNaN(expiresAt)) { + req.banned = true; + return await banResponse(req, res); } - if (timeLeft <= 0 && userKey) { - await banLogs.delete(userKey); + const timeLeft = expiresAt - Date.now(); + + if (timeLeft <= 0) { + const cleanups = []; + if (ipBan) { + cleanups.push(banLogs.delete(req.ip)); + } + if (userBan) { + cleanups.push(banLogs.delete(userId)); + } + await Promise.all(cleanups); return next(); } + const cacheWrites = []; if (ipKey) { - banCache.set(ipKey, isBanned, timeLeft); + cacheWrites.push(banCache.set(ipKey, banData, timeLeft)); } - if (userKey) { - banCache.set(userKey, isBanned, timeLeft); + cacheWrites.push(banCache.set(userKey, banData, timeLeft)); } + await Promise.all(cacheWrites).catch((err) => + logger.warn('[checkBan] Failed to write ban cache:', err), + ); req.banned = true; return await banResponse(req, res); diff --git a/api/server/middleware/checkInviteUser.js b/api/server/middleware/checkInviteUser.js index 42e1faba5b..22f2824ffc 100644 --- a/api/server/middleware/checkInviteUser.js +++ b/api/server/middleware/checkInviteUser.js @@ -1,5 +1,8 @@ -const { getInvite } = require('~/models/inviteUser'); -const { deleteTokens } = require('~/models'); +const { getInvite: getInviteFn } = require('@librechat/api'); +const { createToken, findToken, deleteTokens } = require('~/models'); + +const getInvite = (encodedToken, email) => + getInviteFn(encodedToken, email, { createToken, findToken }); async function checkInviteUser(req, res, next) { const token = req.body.token; diff --git a/api/server/middleware/checkPeoplePickerAccess.js b/api/server/middleware/checkPeoplePickerAccess.js index 0e604272db..50f137285e 100644 --- a/api/server/middleware/checkPeoplePickerAccess.js +++ b/api/server/middleware/checkPeoplePickerAccess.js @@ -1,14 +1,21 @@ const { logger } = require('@librechat/data-schemas'); const { PrincipalType, PermissionTypes, Permissions } = require('librechat-data-provider'); -const { getRoleByName } = require('~/models/Role'); +const { getRoleByName } = require('~/models'); + +const VALID_PRINCIPAL_TYPES = new Set([ + PrincipalType.USER, + PrincipalType.GROUP, + PrincipalType.ROLE, +]); /** - * Middleware to check if user has permission to access people picker functionality - * Checks specific permission based on the 'type' query parameter: - * - type=user: requires VIEW_USERS permission - * - type=group: requires VIEW_GROUPS permission - * - type=role: requires VIEW_ROLES permission - * - no type (mixed search): requires either VIEW_USERS OR VIEW_GROUPS OR VIEW_ROLES + * Middleware to check if user has permission to access people picker functionality. + * Validates requested principal types via `type` (singular) and `types` (comma-separated or array) + * query parameters against the caller's role permissions: + * - user: requires VIEW_USERS permission + * - group: requires VIEW_GROUPS permission + * - role: requires VIEW_ROLES permission + * - no type filter (mixed search): requires at least one of the above */ const checkPeoplePickerAccess = async (req, res, next) => { try { @@ -28,7 +35,7 @@ const checkPeoplePickerAccess = async (req, res, next) => { }); } - const { type } = req.query; + const { type, types } = req.query; const peoplePickerPerms = role.permissions[PermissionTypes.PEOPLE_PICKER] || {}; const canViewUsers = peoplePickerPerms[Permissions.VIEW_USERS] === true; const canViewGroups = peoplePickerPerms[Permissions.VIEW_GROUPS] === true; @@ -49,15 +56,32 @@ const checkPeoplePickerAccess = async (req, res, next) => { }, }; - const check = permissionChecks[type]; - if (check && !check.hasPermission) { - return res.status(403).json({ - error: 'Forbidden', - message: check.message, - }); + const requestedTypes = new Set(); + + if (type && VALID_PRINCIPAL_TYPES.has(type)) { + requestedTypes.add(type); } - if (!type && !canViewUsers && !canViewGroups && !canViewRoles) { + if (types) { + const typesArray = Array.isArray(types) ? types : types.split(','); + for (const t of typesArray) { + if (VALID_PRINCIPAL_TYPES.has(t)) { + requestedTypes.add(t); + } + } + } + + for (const requested of requestedTypes) { + const check = permissionChecks[requested]; + if (!check.hasPermission) { + return res.status(403).json({ + error: 'Forbidden', + message: check.message, + }); + } + } + + if (requestedTypes.size === 0 && !canViewUsers && !canViewGroups && !canViewRoles) { return res.status(403).json({ error: 'Forbidden', message: 'Insufficient permissions to search for users, groups, or roles', @@ -67,7 +91,7 @@ const checkPeoplePickerAccess = async (req, res, next) => { next(); } catch (error) { logger.error( - `[checkPeoplePickerAccess][${req.user?.id}] checkPeoplePickerAccess error for req.query.type = ${req.query.type}`, + `[checkPeoplePickerAccess][${req.user?.id}] error for type=${req.query.type}, types=${req.query.types}`, error, ); return res.status(500).json({ diff --git a/api/server/middleware/checkPeoplePickerAccess.spec.js b/api/server/middleware/checkPeoplePickerAccess.spec.js index 52bf0e6724..c394bbae65 100644 --- a/api/server/middleware/checkPeoplePickerAccess.spec.js +++ b/api/server/middleware/checkPeoplePickerAccess.spec.js @@ -1,9 +1,9 @@ const { logger } = require('@librechat/data-schemas'); const { PrincipalType, PermissionTypes, Permissions } = require('librechat-data-provider'); const { checkPeoplePickerAccess } = require('./checkPeoplePickerAccess'); -const { getRoleByName } = require('~/models/Role'); +const { getRoleByName } = require('~/models'); -jest.mock('~/models/Role'); +jest.mock('~/models'); jest.mock('@librechat/data-schemas', () => ({ ...jest.requireActual('@librechat/data-schemas'), logger: { @@ -173,6 +173,171 @@ describe('checkPeoplePickerAccess', () => { expect(next).not.toHaveBeenCalled(); }); + it('should deny access when using types param to bypass type-specific check', async () => { + req.query.types = PrincipalType.GROUP; + getRoleByName.mockResolvedValue({ + permissions: { + [PermissionTypes.PEOPLE_PICKER]: { + [Permissions.VIEW_USERS]: true, + [Permissions.VIEW_GROUPS]: false, + [Permissions.VIEW_ROLES]: false, + }, + }, + }); + + await checkPeoplePickerAccess(req, res, next); + + expect(res.status).toHaveBeenCalledWith(403); + expect(res.json).toHaveBeenCalledWith({ + error: 'Forbidden', + message: 'Insufficient permissions to search for groups', + }); + expect(next).not.toHaveBeenCalled(); + }); + + it('should deny access when types contains any unpermitted type', async () => { + req.query.types = `${PrincipalType.USER},${PrincipalType.ROLE}`; + getRoleByName.mockResolvedValue({ + permissions: { + [PermissionTypes.PEOPLE_PICKER]: { + [Permissions.VIEW_USERS]: true, + [Permissions.VIEW_GROUPS]: false, + [Permissions.VIEW_ROLES]: false, + }, + }, + }); + + await checkPeoplePickerAccess(req, res, next); + + expect(res.status).toHaveBeenCalledWith(403); + expect(res.json).toHaveBeenCalledWith({ + error: 'Forbidden', + message: 'Insufficient permissions to search for roles', + }); + expect(next).not.toHaveBeenCalled(); + }); + + it('should allow access when all requested types are permitted', async () => { + req.query.types = `${PrincipalType.USER},${PrincipalType.GROUP}`; + getRoleByName.mockResolvedValue({ + permissions: { + [PermissionTypes.PEOPLE_PICKER]: { + [Permissions.VIEW_USERS]: true, + [Permissions.VIEW_GROUPS]: true, + [Permissions.VIEW_ROLES]: false, + }, + }, + }); + + await checkPeoplePickerAccess(req, res, next); + + expect(next).toHaveBeenCalled(); + expect(res.status).not.toHaveBeenCalled(); + }); + + it('should validate types when provided as array (Express qs parsing)', async () => { + req.query.types = [PrincipalType.GROUP, PrincipalType.ROLE]; + getRoleByName.mockResolvedValue({ + permissions: { + [PermissionTypes.PEOPLE_PICKER]: { + [Permissions.VIEW_USERS]: true, + [Permissions.VIEW_GROUPS]: false, + [Permissions.VIEW_ROLES]: true, + }, + }, + }); + + await checkPeoplePickerAccess(req, res, next); + + expect(res.status).toHaveBeenCalledWith(403); + expect(res.json).toHaveBeenCalledWith({ + error: 'Forbidden', + message: 'Insufficient permissions to search for groups', + }); + expect(next).not.toHaveBeenCalled(); + }); + + it('should enforce permissions for combined type and types params', async () => { + req.query.type = PrincipalType.USER; + req.query.types = PrincipalType.GROUP; + getRoleByName.mockResolvedValue({ + permissions: { + [PermissionTypes.PEOPLE_PICKER]: { + [Permissions.VIEW_USERS]: true, + [Permissions.VIEW_GROUPS]: false, + [Permissions.VIEW_ROLES]: false, + }, + }, + }); + + await checkPeoplePickerAccess(req, res, next); + + expect(res.status).toHaveBeenCalledWith(403); + expect(res.json).toHaveBeenCalledWith({ + error: 'Forbidden', + message: 'Insufficient permissions to search for groups', + }); + expect(next).not.toHaveBeenCalled(); + }); + + it('should treat all-invalid types values as mixed search', async () => { + req.query.types = 'foobar'; + getRoleByName.mockResolvedValue({ + permissions: { + [PermissionTypes.PEOPLE_PICKER]: { + [Permissions.VIEW_USERS]: true, + [Permissions.VIEW_GROUPS]: false, + [Permissions.VIEW_ROLES]: false, + }, + }, + }); + + await checkPeoplePickerAccess(req, res, next); + + expect(next).toHaveBeenCalled(); + expect(res.status).not.toHaveBeenCalled(); + }); + + it('should deny when types is empty string and user has no permissions', async () => { + req.query.types = ''; + getRoleByName.mockResolvedValue({ + permissions: { + [PermissionTypes.PEOPLE_PICKER]: { + [Permissions.VIEW_USERS]: false, + [Permissions.VIEW_GROUPS]: false, + [Permissions.VIEW_ROLES]: false, + }, + }, + }); + + await checkPeoplePickerAccess(req, res, next); + + expect(res.status).toHaveBeenCalledWith(403); + expect(res.json).toHaveBeenCalledWith({ + error: 'Forbidden', + message: 'Insufficient permissions to search for users, groups, or roles', + }); + expect(next).not.toHaveBeenCalled(); + }); + + it('should treat types=public as mixed search since PUBLIC is not a searchable principal type', async () => { + req.query.types = PrincipalType.PUBLIC; + getRoleByName.mockResolvedValue({ + permissions: { + [PermissionTypes.PEOPLE_PICKER]: { + [Permissions.VIEW_USERS]: true, + [Permissions.VIEW_GROUPS]: false, + [Permissions.VIEW_ROLES]: false, + }, + }, + }); + + await checkPeoplePickerAccess(req, res, next); + + expect(next).toHaveBeenCalled(); + expect(res.status).not.toHaveBeenCalled(); + }); + it('should allow mixed search when user has at least one permission', async () => { // No type specified = mixed search req.query.type = undefined; @@ -222,7 +387,7 @@ describe('checkPeoplePickerAccess', () => { await checkPeoplePickerAccess(req, res, next); expect(logger.error).toHaveBeenCalledWith( - '[checkPeoplePickerAccess][user123] checkPeoplePickerAccess error for req.query.type = undefined', + '[checkPeoplePickerAccess][user123] error for type=undefined, types=undefined', error, ); expect(res.status).toHaveBeenCalledWith(500); diff --git a/api/server/middleware/checkSharePublicAccess.js b/api/server/middleware/checkSharePublicAccess.js index 0e95b9f6f8..c7b65a077e 100644 --- a/api/server/middleware/checkSharePublicAccess.js +++ b/api/server/middleware/checkSharePublicAccess.js @@ -1,6 +1,6 @@ const { logger } = require('@librechat/data-schemas'); const { ResourceType, PermissionTypes, Permissions } = require('librechat-data-provider'); -const { getRoleByName } = require('~/models/Role'); +const { getRoleByName } = require('~/models'); /** * Maps resource types to their corresponding permission types diff --git a/api/server/middleware/checkSharePublicAccess.spec.js b/api/server/middleware/checkSharePublicAccess.spec.js index c73e71693b..605de2049e 100644 --- a/api/server/middleware/checkSharePublicAccess.spec.js +++ b/api/server/middleware/checkSharePublicAccess.spec.js @@ -1,8 +1,8 @@ const { ResourceType, PermissionTypes, Permissions } = require('librechat-data-provider'); const { checkSharePublicAccess } = require('./checkSharePublicAccess'); -const { getRoleByName } = require('~/models/Role'); +const { getRoleByName } = require('~/models'); -jest.mock('~/models/Role'); +jest.mock('~/models'); describe('checkSharePublicAccess middleware', () => { let mockReq; diff --git a/api/server/middleware/denyRequest.js b/api/server/middleware/denyRequest.js index 20360519cf..86054d0a23 100644 --- a/api/server/middleware/denyRequest.js +++ b/api/server/middleware/denyRequest.js @@ -43,7 +43,11 @@ const denyRequest = async (req, res, errorMessage) => { if (shouldSaveMessage) { await saveMessage( - req, + { + userId: req?.user?.id, + isTemporary: req?.body?.isTemporary, + interfaceConfig: req?.config?.interfaceConfig, + }, { ...userMessage, user: req.user.id }, { context: `api/server/middleware/denyRequest.js - ${responseText}` }, ); diff --git a/api/server/middleware/error.js b/api/server/middleware/error.js index fef7e60ef7..5fa3562c30 100644 --- a/api/server/middleware/error.js +++ b/api/server/middleware/error.js @@ -2,8 +2,7 @@ const crypto = require('crypto'); const { logger } = require('@librechat/data-schemas'); const { parseConvo } = require('librechat-data-provider'); const { sendEvent, handleError, sanitizeMessageForTransmit } = require('@librechat/api'); -const { saveMessage, getMessages } = require('~/models/Message'); -const { getConvo } = require('~/models/Conversation'); +const { saveMessage, getMessages, getConvo } = require('~/models'); /** * Processes an error with provided options, saves the error message and sends a corresponding SSE response @@ -49,7 +48,11 @@ const sendError = async (req, res, options, callback) => { if (shouldSaveMessage) { await saveMessage( - req, + { + userId: req?.user?.id, + isTemporary: req?.body?.isTemporary, + interfaceConfig: req?.config?.interfaceConfig, + }, { ...errorMessage, user }, { context: 'api/server/utils/streamResponse.js - sendError', diff --git a/api/server/middleware/limiters/forkLimiters.js b/api/server/middleware/limiters/forkLimiters.js index e0aa65700c..6d05cedad5 100644 --- a/api/server/middleware/limiters/forkLimiters.js +++ b/api/server/middleware/limiters/forkLimiters.js @@ -1,6 +1,6 @@ const rateLimit = require('express-rate-limit'); -const { limiterCache } = require('@librechat/api'); const { ViolationTypes } = require('librechat-data-provider'); +const { limiterCache, removePorts } = require('@librechat/api'); const logViolation = require('~/cache/logViolation'); const getEnvironmentVariables = () => { @@ -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' }); }; }; @@ -59,6 +59,7 @@ const createForkLimiters = () => { windowMs: forkIpWindowMs, max: forkIpMax, handler: createForkHandler(), + keyGenerator: removePorts, store: limiterCache('fork_ip_limiter'), }; const userLimiterOptions = { diff --git a/api/server/middleware/limiters/importLimiters.js b/api/server/middleware/limiters/importLimiters.js index f383e99563..22b7013558 100644 --- a/api/server/middleware/limiters/importLimiters.js +++ b/api/server/middleware/limiters/importLimiters.js @@ -1,6 +1,6 @@ const rateLimit = require('express-rate-limit'); -const { limiterCache } = require('@librechat/api'); const { ViolationTypes } = require('librechat-data-provider'); +const { limiterCache, removePorts } = require('@librechat/api'); const logViolation = require('~/cache/logViolation'); const getEnvironmentVariables = () => { @@ -60,6 +60,7 @@ const createImportLimiters = () => { windowMs: importIpWindowMs, max: importIpMax, handler: createImportHandler(), + keyGenerator: removePorts, store: limiterCache('import_ip_limiter'), }; const userLimiterOptions = { @@ -67,7 +68,7 @@ const createImportLimiters = () => { max: importUserMax, handler: createImportHandler(false), keyGenerator: function (req) { - return req.user?.id; // Use the user ID or NULL if not available + return req.user?.id; }, store: limiterCache('import_user_limiter'), }; diff --git a/api/server/middleware/limiters/index.js b/api/server/middleware/limiters/index.js index ab110443dc..a38188d2a6 100644 --- a/api/server/middleware/limiters/index.js +++ b/api/server/middleware/limiters/index.js @@ -8,6 +8,7 @@ const forkLimiters = require('./forkLimiters'); const registerLimiter = require('./registerLimiter'); const toolCallLimiter = require('./toolCallLimiter'); const messageLimiters = require('./messageLimiters'); +const promptUsageLimiter = require('./promptUsageLimiter'); const verifyEmailLimiter = require('./verifyEmailLimiter'); const resetPasswordLimiter = require('./resetPasswordLimiter'); @@ -16,6 +17,7 @@ module.exports = { ...importLimiters, ...messageLimiters, ...forkLimiters, + ...promptUsageLimiter, loginLimiter, registerLimiter, toolCallLimiter, diff --git a/api/server/middleware/limiters/loginLimiter.js b/api/server/middleware/limiters/loginLimiter.js index eef0c56bfc..c178b68a25 100644 --- a/api/server/middleware/limiters/loginLimiter.js +++ b/api/server/middleware/limiters/loginLimiter.js @@ -1,7 +1,6 @@ const rateLimit = require('express-rate-limit'); -const { limiterCache } = require('@librechat/api'); const { ViolationTypes } = require('librechat-data-provider'); -const { removePorts } = require('~/server/utils'); +const { limiterCache, removePorts } = require('@librechat/api'); const { logViolation } = require('~/cache'); const { LOGIN_WINDOW = 5, LOGIN_MAX = 7, LOGIN_VIOLATION_SCORE: score } = process.env; diff --git a/api/server/middleware/limiters/messageLimiters.js b/api/server/middleware/limiters/messageLimiters.js index 50f4dbc644..4f1d72076f 100644 --- a/api/server/middleware/limiters/messageLimiters.js +++ b/api/server/middleware/limiters/messageLimiters.js @@ -1,6 +1,6 @@ const rateLimit = require('express-rate-limit'); -const { limiterCache } = require('@librechat/api'); const { ViolationTypes } = require('librechat-data-provider'); +const { limiterCache, removePorts } = require('@librechat/api'); const denyRequest = require('~/server/middleware/denyRequest'); const { logViolation } = require('~/cache'); @@ -50,6 +50,7 @@ const ipLimiterOptions = { windowMs: ipWindowMs, max: ipMax, handler: createHandler(), + keyGenerator: removePorts, store: limiterCache('message_ip_limiter'), }; @@ -58,7 +59,7 @@ const userLimiterOptions = { max: userMax, handler: createHandler(false), keyGenerator: function (req) { - return req.user?.id; // Use the user ID or NULL if not available + return req.user?.id; }, store: limiterCache('message_user_limiter'), }; diff --git a/api/server/middleware/limiters/promptUsageLimiter.js b/api/server/middleware/limiters/promptUsageLimiter.js new file mode 100644 index 0000000000..38bdeed636 --- /dev/null +++ b/api/server/middleware/limiters/promptUsageLimiter.js @@ -0,0 +1,17 @@ +const rateLimit = require('express-rate-limit'); +const { limiterCache } = require('@librechat/api'); + +const PROMPT_USAGE_WINDOW_MS = 60 * 1000; // 1 minute +const PROMPT_USAGE_MAX = 30; // 30 usage increments per user per minute + +const promptUsageLimiter = rateLimit({ + windowMs: PROMPT_USAGE_WINDOW_MS, + max: PROMPT_USAGE_MAX, + handler: (_req, res) => { + res.status(429).json({ message: 'Too many prompt usage requests. Try again later' }); + }, + keyGenerator: (req) => req.user?.id, + store: limiterCache('prompt_usage_limiter'), +}); + +module.exports = { promptUsageLimiter }; diff --git a/api/server/middleware/limiters/registerLimiter.js b/api/server/middleware/limiters/registerLimiter.js index eeebebdb42..91ea027376 100644 --- a/api/server/middleware/limiters/registerLimiter.js +++ b/api/server/middleware/limiters/registerLimiter.js @@ -1,7 +1,6 @@ const rateLimit = require('express-rate-limit'); -const { limiterCache } = require('@librechat/api'); const { ViolationTypes } = require('librechat-data-provider'); -const { removePorts } = require('~/server/utils'); +const { limiterCache, removePorts } = require('@librechat/api'); const { logViolation } = require('~/cache'); const { REGISTER_WINDOW = 60, REGISTER_MAX = 5, REGISTRATION_VIOLATION_SCORE: score } = process.env; diff --git a/api/server/middleware/limiters/resetPasswordLimiter.js b/api/server/middleware/limiters/resetPasswordLimiter.js index d1dfe52a98..7feca47ca5 100644 --- a/api/server/middleware/limiters/resetPasswordLimiter.js +++ b/api/server/middleware/limiters/resetPasswordLimiter.js @@ -1,7 +1,6 @@ const rateLimit = require('express-rate-limit'); -const { limiterCache } = require('@librechat/api'); const { ViolationTypes } = require('librechat-data-provider'); -const { removePorts } = require('~/server/utils'); +const { limiterCache, removePorts } = require('@librechat/api'); const { logViolation } = require('~/cache'); const { diff --git a/api/server/middleware/limiters/sttLimiters.js b/api/server/middleware/limiters/sttLimiters.js index f2f47cf680..ded9040033 100644 --- a/api/server/middleware/limiters/sttLimiters.js +++ b/api/server/middleware/limiters/sttLimiters.js @@ -1,6 +1,6 @@ const rateLimit = require('express-rate-limit'); -const { limiterCache } = require('@librechat/api'); const { ViolationTypes } = require('librechat-data-provider'); +const { limiterCache, removePorts } = require('@librechat/api'); const logViolation = require('~/cache/logViolation'); const getEnvironmentVariables = () => { @@ -54,6 +54,7 @@ const createSTTLimiters = () => { windowMs: sttIpWindowMs, max: sttIpMax, handler: createSTTHandler(), + keyGenerator: removePorts, store: limiterCache('stt_ip_limiter'), }; @@ -62,7 +63,7 @@ const createSTTLimiters = () => { max: sttUserMax, handler: createSTTHandler(false), keyGenerator: function (req) { - return req.user?.id; // Use the user ID or NULL if not available + return req.user?.id; }, store: limiterCache('stt_user_limiter'), }; diff --git a/api/server/middleware/limiters/ttsLimiters.js b/api/server/middleware/limiters/ttsLimiters.js index 41dd9a6ba5..7ded475230 100644 --- a/api/server/middleware/limiters/ttsLimiters.js +++ b/api/server/middleware/limiters/ttsLimiters.js @@ -1,6 +1,6 @@ const rateLimit = require('express-rate-limit'); -const { limiterCache } = require('@librechat/api'); const { ViolationTypes } = require('librechat-data-provider'); +const { limiterCache, removePorts } = require('@librechat/api'); const logViolation = require('~/cache/logViolation'); const getEnvironmentVariables = () => { @@ -54,6 +54,7 @@ const createTTSLimiters = () => { windowMs: ttsIpWindowMs, max: ttsIpMax, handler: createTTSHandler(), + keyGenerator: removePorts, store: limiterCache('tts_ip_limiter'), }; @@ -61,10 +62,10 @@ const createTTSLimiters = () => { windowMs: ttsUserWindowMs, max: ttsUserMax, handler: createTTSHandler(false), - store: limiterCache('tts_user_limiter'), keyGenerator: function (req) { - return req.user?.id; // Use the user ID or NULL if not available + return req.user?.id; }, + store: limiterCache('tts_user_limiter'), }; const ttsIpLimiter = rateLimit(ipLimiterOptions); diff --git a/api/server/middleware/limiters/uploadLimiters.js b/api/server/middleware/limiters/uploadLimiters.js index df6987877c..8c878cfa86 100644 --- a/api/server/middleware/limiters/uploadLimiters.js +++ b/api/server/middleware/limiters/uploadLimiters.js @@ -1,6 +1,6 @@ const rateLimit = require('express-rate-limit'); -const { limiterCache } = require('@librechat/api'); const { ViolationTypes } = require('librechat-data-provider'); +const { limiterCache, removePorts } = require('@librechat/api'); const logViolation = require('~/cache/logViolation'); const getEnvironmentVariables = () => { @@ -60,6 +60,7 @@ const createFileLimiters = () => { windowMs: fileUploadIpWindowMs, max: fileUploadIpMax, handler: createFileUploadHandler(), + keyGenerator: removePorts, store: limiterCache('file_upload_ip_limiter'), }; @@ -68,7 +69,7 @@ const createFileLimiters = () => { max: fileUploadUserMax, handler: createFileUploadHandler(false), keyGenerator: function (req) { - return req.user?.id; // Use the user ID or NULL if not available + return req.user?.id; }, store: limiterCache('file_upload_user_limiter'), }; diff --git a/api/server/middleware/limiters/verifyEmailLimiter.js b/api/server/middleware/limiters/verifyEmailLimiter.js index 006c4df656..5844686bf0 100644 --- a/api/server/middleware/limiters/verifyEmailLimiter.js +++ b/api/server/middleware/limiters/verifyEmailLimiter.js @@ -1,7 +1,6 @@ const rateLimit = require('express-rate-limit'); -const { limiterCache } = require('@librechat/api'); const { ViolationTypes } = require('librechat-data-provider'); -const { removePorts } = require('~/server/utils'); +const { limiterCache, removePorts } = require('@librechat/api'); const { logViolation } = require('~/cache'); const { diff --git a/api/server/middleware/roles/access.spec.js b/api/server/middleware/roles/access.spec.js index 9de840819d..16fb6df138 100644 --- a/api/server/middleware/roles/access.spec.js +++ b/api/server/middleware/roles/access.spec.js @@ -2,7 +2,7 @@ const mongoose = require('mongoose'); const { MongoMemoryServer } = require('mongodb-memory-server'); const { checkAccess, generateCheckAccess } = require('@librechat/api'); const { PermissionTypes, Permissions } = require('librechat-data-provider'); -const { getRoleByName } = require('~/models/Role'); +const { getRoleByName } = require('~/models'); const { Role } = require('~/db/models'); // Mock the logger from @librechat/data-schemas diff --git a/api/server/middleware/roles/capabilities.js b/api/server/middleware/roles/capabilities.js new file mode 100644 index 0000000000..6f2aa43e96 --- /dev/null +++ b/api/server/middleware/roles/capabilities.js @@ -0,0 +1,14 @@ +const { generateCapabilityCheck, capabilityContextMiddleware } = require('@librechat/api'); +const { getUserPrincipals, hasCapabilityForPrincipals } = require('~/models'); + +const { hasCapability, requireCapability, hasConfigCapability } = generateCapabilityCheck({ + getUserPrincipals, + hasCapabilityForPrincipals, +}); + +module.exports = { + hasCapability, + requireCapability, + hasConfigCapability, + capabilityContextMiddleware, +}; diff --git a/api/server/middleware/roles/index.js b/api/server/middleware/roles/index.js index f01b884e5a..f97d4b72b4 100644 --- a/api/server/middleware/roles/index.js +++ b/api/server/middleware/roles/index.js @@ -1,3 +1,15 @@ +/** + * NOTE: hasCapability, requireCapability, hasConfigCapability, and + * capabilityContextMiddleware are intentionally NOT re-exported here. + * + * capabilities.js depends on ~/models, and the middleware barrel + * (middleware/index.js) is frequently required by modules that are + * themselves loaded while the barrel is still initialising — creating + * a circular-require that silently returns an empty exports object. + * + * Always import capability helpers directly: + * require('~/server/middleware/roles/capabilities') + */ const checkAdmin = require('./admin'); module.exports = { diff --git a/api/server/middleware/validate/convoAccess.js b/api/server/middleware/validate/convoAccess.js index 127bfdc530..ef1eea8f37 100644 --- a/api/server/middleware/validate/convoAccess.js +++ b/api/server/middleware/validate/convoAccess.js @@ -1,8 +1,8 @@ const { isEnabled } = require('@librechat/api'); const { Constants, ViolationTypes, Time } = require('librechat-data-provider'); -const { searchConversation } = require('~/models/Conversation'); const denyRequest = require('~/server/middleware/denyRequest'); const { logViolation, getLogStores } = require('~/cache'); +const { searchConversation } = require('~/models'); const { USE_REDIS, CONVO_ACCESS_VIOLATION_SCORE: score = 0 } = process.env ?? {}; 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..0929e0759d --- /dev/null +++ b/api/server/routes/__test-utils__/convos-route-mocks.js @@ -0,0 +1,98 @@ +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: () => ({ + getConvosByCursor: jest.fn(), + getConvo: jest.fn(), + deleteConvos: jest.fn(), + saveConvo: jest.fn(), + deleteAllSharedLinks: jest.fn(), + deleteConvoSharedLink: jest.fn(), + deleteToolCalls: 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..a75c11ccba --- /dev/null +++ b/api/server/routes/__tests__/convos-duplicate-ratelimit.spec.js @@ -0,0 +1,137 @@ +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', () => ({ + ...require(MOCKS).sharedModels(), + ...require(MOCKS).conversationModel(), + ...require(MOCKS).toolCallModel(), +})); +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..23978f28e9 100644 --- a/api/server/routes/__tests__/convos.spec.js +++ b/api/server/routes/__tests__/convos.spec.js @@ -1,116 +1,33 @@ 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', () => 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; let convosRouter; - const { deleteAllSharedLinks, deleteConvoSharedLink } = require('~/models'); - const { deleteConvos, saveConvo } = require('~/models/Conversation'); - const { deleteToolCalls } = require('~/models/ToolCall'); + const { + deleteAllSharedLinks, + deleteConvoSharedLink, + deleteToolCalls, + deleteConvos, + saveConvo, + } = require('~/models'); beforeAll(() => { convosRouter = require('../convos'); @@ -520,7 +437,7 @@ describe('Convos Routes', () => { expect(response.status).toBe(200); expect(response.body).toEqual(mockArchivedConvo); expect(saveConvo).toHaveBeenCalledWith( - expect.objectContaining({ user: { id: 'test-user-123' } }), + expect.objectContaining({ userId: 'test-user-123' }), { conversationId: mockConversationId, isArchived: true }, { context: `POST /api/convos/archive ${mockConversationId}` }, ); @@ -549,7 +466,7 @@ describe('Convos Routes', () => { expect(response.status).toBe(200); expect(response.body).toEqual(mockUnarchivedConvo); expect(saveConvo).toHaveBeenCalledWith( - expect.objectContaining({ user: { id: 'test-user-123' } }), + expect.objectContaining({ userId: 'test-user-123' }), { conversationId: mockConversationId, isArchived: false }, { context: `POST /api/convos/archive ${mockConversationId}` }, ); 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..714d497719 --- /dev/null +++ b/api/server/routes/__tests__/messages-delete.spec.js @@ -0,0 +1,199 @@ +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(), + getConvosQueried: jest.fn(), + searchMessages: jest.fn(), + getMessagesByCursor: 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('~/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/accessPermissions.test.js b/api/server/routes/accessPermissions.test.js index 81c21c8667..ddbe702f15 100644 --- a/api/server/routes/accessPermissions.test.js +++ b/api/server/routes/accessPermissions.test.js @@ -5,7 +5,7 @@ const { v4: uuidv4 } = require('uuid'); const { createMethods } = require('@librechat/data-schemas'); const { MongoMemoryServer } = require('mongodb-memory-server'); const { ResourceType, PermissionBits } = require('librechat-data-provider'); -const { createAgent } = require('~/models/Agent'); +const { createAgent } = require('~/models'); /** * Mock the PermissionsController to isolate route testing diff --git a/api/server/routes/admin/auth.js b/api/server/routes/admin/auth.js index 291b5eaaf8..530764852b 100644 --- a/api/server/routes/admin/auth.js +++ b/api/server/routes/admin/auth.js @@ -3,23 +3,23 @@ const passport = require('passport'); const { randomState } = require('openid-client'); const { logger } = require('@librechat/data-schemas'); const { CacheKeys } = require('librechat-data-provider'); -const { - requireAdmin, - getAdminPanelUrl, - exchangeAdminCode, - createSetBalanceConfig, -} = require('@librechat/api'); +const { SystemCapabilities } = require('@librechat/data-schemas'); +const { getAdminPanelUrl, exchangeAdminCode, createSetBalanceConfig } = require('@librechat/api'); const { loginController } = require('~/server/controllers/auth/LoginController'); +const { requireCapability } = require('~/server/middleware/roles/capabilities'); const { createOAuthHandler } = require('~/server/controllers/auth/oauth'); +const { findBalanceByUser, upsertBalanceFields } = require('~/models'); const { getAppConfig } = require('~/server/services/Config'); const getLogStores = require('~/cache/getLogStores'); const { getOpenIdConfig } = require('~/strategies'); const middleware = require('~/server/middleware'); -const { Balance } = require('~/db/models'); + +const requireAdminAccess = requireCapability(SystemCapabilities.ACCESS_ADMIN); const setBalanceConfig = createSetBalanceConfig({ getAppConfig, - Balance, + findBalanceByUser, + upsertBalanceFields, }); const router = express.Router(); @@ -30,12 +30,12 @@ router.post( middleware.loginLimiter, middleware.checkBan, middleware.requireLocalAuth, - requireAdmin, + requireAdminAccess, setBalanceConfig, loginController, ); -router.get('/verify', middleware.requireJwtAuth, requireAdmin, (req, res) => { +router.get('/verify', middleware.requireJwtAuth, requireAdminAccess, (req, res) => { const { password: _p, totpSecret: _t, __v, ...user } = req.user; user.id = user._id.toString(); res.status(200).json({ user }); @@ -66,7 +66,7 @@ router.get( failureMessage: true, session: false, }), - requireAdmin, + requireAdminAccess, setBalanceConfig, middleware.checkDomainAllowed, createOAuthHandler(`${getAdminPanelUrl()}/auth/openid/callback`), diff --git a/api/server/routes/agents/actions.js b/api/server/routes/agents/actions.js index 12168ba28a..b3b34f3f1c 100644 --- a/api/server/routes/agents/actions.js +++ b/api/server/routes/agents/actions.js @@ -12,19 +12,21 @@ const { validateActionDomain, validateAndParseOpenAPISpec, } = require('librechat-data-provider'); -const { encryptMetadata, domainParser } = require('~/server/services/ActionService'); +const { + legacyDomainEncode, + encryptMetadata, + domainParser, +} = require('~/server/services/ActionService'); const { findAccessibleResources } = require('~/server/services/PermissionService'); -const { getAgent, updateAgent, getListAgentsByAccess } = require('~/models/Agent'); -const { updateAction, getActions, deleteAction } = require('~/models/Action'); +const db = require('~/models'); const { canAccessAgentResource } = require('~/server/middleware'); -const { getRoleByName } = require('~/models/Role'); const router = express.Router(); const checkAgentCreate = generateCheckAccess({ permissionType: PermissionTypes.AGENTS, permissions: [Permissions.USE, Permissions.CREATE], - getRoleByName, + getRoleByName: db.getRoleByName, }); /** @@ -43,13 +45,15 @@ router.get('/', async (req, res) => { requiredPermissions: PermissionBits.EDIT, }); - const agentsResponse = await getListAgentsByAccess({ + const agentsResponse = await db.getListAgentsByAccess({ accessibleIds: editableAgentObjectIds, }); const editableAgentIds = agentsResponse.data.map((agent) => agent.id); const actions = - editableAgentIds.length > 0 ? await getActions({ agent_id: { $in: editableAgentIds } }) : []; + editableAgentIds.length > 0 + ? await db.getActions({ agent_id: { $in: editableAgentIds } }) + : []; res.json(actions); } catch (error) { @@ -119,20 +123,21 @@ router.post( return res.status(400).json({ message: 'Domain not allowed' }); } - let { domain } = metadata; - domain = await domainParser(domain, true); + const encodedDomain = await domainParser(metadata.domain, true); - if (!domain) { + if (!encodedDomain) { return res.status(400).json({ message: 'No domain provided' }); } + const legacyDomain = legacyDomainEncode(metadata.domain); + const action_id = _action_id ?? nanoid(); const initialPromises = []; // Permissions already validated by middleware - load agent directly - initialPromises.push(getAgent({ id: agent_id })); + initialPromises.push(db.getAgent({ id: agent_id })); if (_action_id) { - initialPromises.push(getActions({ action_id }, true)); + initialPromises.push(db.getActions({ action_id }, true)); } /** @type {[Agent, [Action|undefined]]} */ @@ -143,6 +148,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 }; } @@ -157,17 +165,26 @@ router.post( actions.push(action); } - actions.push(`${domain}${actionDelimiter}${action_id}`); + actions.push(`${encodedDomain}${actionDelimiter}${action_id}`); /** @type {string[]}} */ const { tools: _tools = [] } = agent; + const shouldRemoveAgentTool = (tool) => { + if (!tool) { + return false; + } + return ( + tool.includes(encodedDomain) || tool.includes(legacyDomain) || tool.includes(action_id) + ); + }; + const tools = _tools - .filter((tool) => !(tool && (tool.includes(domain) || tool.includes(action_id)))) - .concat(functions.map((tool) => `${tool.function.name}${actionDelimiter}${domain}`)); + .filter((tool) => !shouldRemoveAgentTool(tool)) + .concat(functions.map((tool) => `${tool.function.name}${actionDelimiter}${encodedDomain}`)); // Force version update since actions are changing - const updatedAgent = await updateAgent( + const updatedAgent = await db.updateAgent( { id: agent_id }, { tools, actions }, { @@ -184,7 +201,7 @@ router.post( } /** @type {[Action]} */ - const updatedAction = await updateAction({ action_id }, actionUpdateData); + const updatedAction = await db.updateAction({ action_id, agent_id }, actionUpdateData); const sensitiveFields = ['api_key', 'oauth_client_id', 'oauth_client_secret']; for (let field of sensitiveFields) { @@ -221,37 +238,43 @@ router.delete( const { agent_id, action_id } = req.params; // Permissions already validated by middleware - load agent directly - const agent = await getAgent({ id: agent_id }); + const agent = await db.getAgent({ id: agent_id }); if (!agent) { return res.status(404).json({ message: 'Agent not found for deleting action' }); } const { tools = [], actions = [] } = agent; - let domain = ''; + let storedDomain = ''; const updatedActions = actions.filter((action) => { if (action.includes(action_id)) { - [domain] = action.split(actionDelimiter); + [storedDomain] = action.split(actionDelimiter); return false; } return true; }); - domain = await domainParser(domain, true); - - if (!domain) { + if (!storedDomain) { return res.status(400).json({ message: 'No domain provided' }); } - const updatedTools = tools.filter((tool) => !(tool && tool.includes(domain))); + const updatedTools = tools.filter( + (tool) => !(tool && (tool.includes(storedDomain) || tool.includes(action_id))), + ); // Force version update since actions are being removed - await updateAgent( + await db.updateAgent( { id: agent_id }, { tools: updatedTools, actions: updatedActions }, { updatingUserId: req.user.id, forceVersion: true }, ); - await deleteAction({ action_id }); + const deleted = await db.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/chat.js b/api/server/routes/agents/chat.js index 37b83f4f54..0543b0b1aa 100644 --- a/api/server/routes/agents/chat.js +++ b/api/server/routes/agents/chat.js @@ -11,7 +11,7 @@ const { const { initializeClient } = require('~/server/services/Endpoints/agents'); const AgentController = require('~/server/controllers/agents/request'); const addTitle = require('~/server/services/Endpoints/agents/title'); -const { getRoleByName } = require('~/models/Role'); +const { getRoleByName } = require('~/models'); const router = express.Router(); diff --git a/api/server/routes/agents/index.js b/api/server/routes/agents/index.js index f8d39cb4d8..86966a3f3e 100644 --- a/api/server/routes/agents/index.js +++ b/api/server/routes/agents/index.js @@ -10,8 +10,8 @@ const { messageUserLimiter, } = require('~/server/middleware'); const { saveMessage } = require('~/models'); -const openai = require('./openai'); const responses = require('./responses'); +const openai = require('./openai'); const { v1 } = require('./v1'); const chat = require('./chat'); @@ -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' }); @@ -253,9 +263,15 @@ router.post('/chat/abort', async (req, res) => { }; try { - await saveMessage(req, responseMessage, { - context: 'api/server/routes/agents/index.js - abort endpoint', - }); + await saveMessage( + { + userId: req?.user?.id, + isTemporary: req?.body?.isTemporary, + interfaceConfig: req?.config?.interfaceConfig, + }, + responseMessage, + { context: 'api/server/routes/agents/index.js - abort endpoint' }, + ); logger.debug(`[AgentStream] Saved partial response for: ${jobStreamId}`); } catch (saveError) { logger.error(`[AgentStream] Failed to save partial response: ${saveError.message}`); diff --git a/api/server/routes/agents/openai.js b/api/server/routes/agents/openai.js index 9a0d9a3564..72e3da6c5a 100644 --- a/api/server/routes/agents/openai.js +++ b/api/server/routes/agents/openai.js @@ -29,26 +29,24 @@ const { GetModelController, } = require('~/server/controllers/agents/openai'); const { getEffectivePermissions } = require('~/server/services/PermissionService'); -const { validateAgentApiKey, findUser } = require('~/models'); const { configMiddleware } = require('~/server/middleware'); -const { getRoleByName } = require('~/models/Role'); -const { getAgent } = require('~/models/Agent'); +const db = require('~/models'); const router = express.Router(); const requireApiKeyAuth = createRequireApiKeyAuth({ - validateAgentApiKey, - findUser, + validateAgentApiKey: db.validateAgentApiKey, + findUser: db.findUser, }); const checkRemoteAgentsFeature = generateCheckAccess({ permissionType: PermissionTypes.REMOTE_AGENTS, permissions: [Permissions.USE], - getRoleByName, + getRoleByName: db.getRoleByName, }); const checkAgentPermission = createCheckRemoteAgentAccess({ - getAgent, + getAgent: db.getAgent, getEffectivePermissions, }); diff --git a/api/server/routes/agents/responses.js b/api/server/routes/agents/responses.js index 431942e921..2c118e0597 100644 --- a/api/server/routes/agents/responses.js +++ b/api/server/routes/agents/responses.js @@ -32,26 +32,24 @@ const { listModels, } = require('~/server/controllers/agents/responses'); const { getEffectivePermissions } = require('~/server/services/PermissionService'); -const { validateAgentApiKey, findUser } = require('~/models'); const { configMiddleware } = require('~/server/middleware'); -const { getRoleByName } = require('~/models/Role'); -const { getAgent } = require('~/models/Agent'); +const db = require('~/models'); const router = express.Router(); const requireApiKeyAuth = createRequireApiKeyAuth({ - validateAgentApiKey, - findUser, + validateAgentApiKey: db.validateAgentApiKey, + findUser: db.findUser, }); const checkRemoteAgentsFeature = generateCheckAccess({ permissionType: PermissionTypes.REMOTE_AGENTS, permissions: [Permissions.USE], - getRoleByName, + getRoleByName: db.getRoleByName, }); const checkAgentPermission = createCheckRemoteAgentAccess({ - getAgent, + getAgent: db.getAgent, getEffectivePermissions, }); diff --git a/api/server/routes/agents/v1.js b/api/server/routes/agents/v1.js index ed989bcf44..c4f90d0bd5 100644 --- a/api/server/routes/agents/v1.js +++ b/api/server/routes/agents/v1.js @@ -3,7 +3,7 @@ const { generateCheckAccess } = require('@librechat/api'); const { PermissionTypes, Permissions, PermissionBits } = require('librechat-data-provider'); const { requireJwtAuth, configMiddleware, canAccessAgentResource } = require('~/server/middleware'); const v1 = require('~/server/controllers/agents/v1'); -const { getRoleByName } = require('~/models/Role'); +const { getRoleByName } = require('~/models'); const actions = require('./actions'); const tools = require('./tools'); @@ -21,15 +21,6 @@ const checkAgentCreate = generateCheckAccess({ getRoleByName, }); -const checkGlobalAgentShare = generateCheckAccess({ - permissionType: PermissionTypes.AGENTS, - permissions: [Permissions.USE, Permissions.CREATE], - bodyProps: { - [Permissions.SHARE]: ['projectIds', 'removeProjectIds'], - }, - getRoleByName, -}); - router.use(requireJwtAuth); /** @@ -99,7 +90,7 @@ router.get( */ router.patch( '/:id', - checkGlobalAgentShare, + checkAgentCreate, canAccessAgentResource({ requiredPermission: PermissionBits.EDIT, resourceIdParam: 'id', @@ -148,7 +139,7 @@ router.delete( */ router.post( '/:id/revert', - checkGlobalAgentShare, + checkAgentCreate, canAccessAgentResource({ requiredPermission: PermissionBits.EDIT, resourceIdParam: 'id', diff --git a/api/server/routes/apiKeys.js b/api/server/routes/apiKeys.js index 29dcc326f5..ee11a8b0dd 100644 --- a/api/server/routes/apiKeys.js +++ b/api/server/routes/apiKeys.js @@ -6,9 +6,9 @@ const { createAgentApiKey, deleteAgentApiKey, listAgentApiKeys, + getRoleByName, } = require('~/models'); const { requireJwtAuth } = require('~/server/middleware'); -const { getRoleByName } = require('~/models/Role'); const router = express.Router(); diff --git a/api/server/routes/assistants/actions.js b/api/server/routes/assistants/actions.js index 57975d32a7..977d3f92a7 100644 --- a/api/server/routes/assistants/actions.js +++ b/api/server/routes/assistants/actions.js @@ -3,10 +3,13 @@ const { nanoid } = require('nanoid'); const { logger } = require('@librechat/data-schemas'); const { isActionDomainAllowed } = require('@librechat/api'); const { actionDelimiter, EModelEndpoint, removeNullishValues } = require('librechat-data-provider'); -const { encryptMetadata, domainParser } = require('~/server/services/ActionService'); +const { + legacyDomainEncode, + encryptMetadata, + domainParser, +} = require('~/server/services/ActionService'); const { getOpenAIClient } = require('~/server/controllers/assistants/helpers'); -const { updateAction, getActions, deleteAction } = require('~/models/Action'); -const { updateAssistantDoc, getAssistant } = require('~/models/Assistant'); +const db = require('~/models'); const router = express.Router(); @@ -39,27 +42,31 @@ router.post('/:assistant_id', async (req, res) => { return res.status(400).json({ message: 'Domain not allowed' }); } - let { domain } = metadata; - domain = await domainParser(domain, true); + const encodedDomain = await domainParser(metadata.domain, true); - if (!domain) { + if (!encodedDomain) { return res.status(400).json({ message: 'No domain provided' }); } + const legacyDomain = legacyDomainEncode(metadata.domain); + const action_id = _action_id ?? nanoid(); const initialPromises = []; const { openai } = await getOpenAIClient({ req, res }); - initialPromises.push(getAssistant({ assistant_id })); + initialPromises.push(db.getAssistant({ assistant_id })); initialPromises.push(openai.beta.assistants.retrieve(assistant_id)); - !!_action_id && initialPromises.push(getActions({ action_id }, true)); + !!_action_id && initialPromises.push(db.getActions({ action_id }, true)); /** @type {[AssistantDocument, Assistant, [Action|undefined]]} */ const [assistant_data, assistant, actions_result] = await Promise.all(initialPromises); 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 }; } @@ -78,25 +85,29 @@ router.post('/:assistant_id', async (req, res) => { actions.push(action); } - actions.push(`${domain}${actionDelimiter}${action_id}`); + actions.push(`${encodedDomain}${actionDelimiter}${action_id}`); /** @type {{ tools: FunctionTool[] | { type: 'code_interpreter'|'retrieval'}[]}} */ const { tools: _tools = [] } = assistant; + const shouldRemoveAssistantTool = (tool) => { + if (!tool.function) { + return false; + } + const name = tool.function.name; + return ( + name.includes(encodedDomain) || name.includes(legacyDomain) || name.includes(action_id) + ); + }; + const tools = _tools - .filter( - (tool) => - !( - tool.function && - (tool.function.name.includes(domain) || tool.function.name.includes(action_id)) - ), - ) + .filter((tool) => !shouldRemoveAssistantTool(tool)) .concat( functions.map((tool) => ({ ...tool, function: { ...tool.function, - name: `${tool.function.name}${actionDelimiter}${domain}`, + name: `${tool.function.name}${actionDelimiter}${encodedDomain}`, }, })), ); @@ -109,7 +120,7 @@ router.post('/:assistant_id', async (req, res) => { if (!assistant_data) { assistantUpdateData.user = req.user.id; } - promises.push(updateAssistantDoc({ assistant_id }, assistantUpdateData)); + promises.push(db.updateAssistantDoc({ assistant_id }, assistantUpdateData)); // Only update user field for new actions const actionUpdateData = { metadata, assistant_id }; @@ -117,7 +128,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(db.updateAction({ action_id, assistant_id }, actionUpdateData)); /** @type {[AssistantDocument, Action]} */ let [assistantDocument, updatedAction] = await Promise.all(promises); @@ -159,7 +170,7 @@ router.delete('/:assistant_id/:action_id/:model', async (req, res) => { const { openai } = await getOpenAIClient({ req, res }); const initialPromises = []; - initialPromises.push(getAssistant({ assistant_id })); + initialPromises.push(db.getAssistant({ assistant_id })); initialPromises.push(openai.beta.assistants.retrieve(assistant_id)); /** @type {[AssistantDocument, Assistant]} */ @@ -168,23 +179,25 @@ router.delete('/:assistant_id/:action_id/:model', async (req, res) => { const { actions = [] } = assistant_data ?? {}; const { tools = [] } = assistant ?? {}; - let domain = ''; + let storedDomain = ''; const updatedActions = actions.filter((action) => { if (action.includes(action_id)) { - [domain] = action.split(actionDelimiter); + [storedDomain] = action.split(actionDelimiter); return false; } return true; }); - domain = await domainParser(domain, true); - - if (!domain) { + if (!storedDomain) { return res.status(400).json({ message: 'No domain provided' }); } const updatedTools = tools.filter( - (tool) => !(tool.function && tool.function.name.includes(domain)), + (tool) => + !( + tool.function && + (tool.function.name.includes(storedDomain) || tool.function.name.includes(action_id)) + ), ); await openai.beta.assistants.update(assistant_id, { tools: updatedTools }); @@ -195,10 +208,16 @@ router.delete('/:assistant_id/:action_id/:model', async (req, res) => { if (!assistant_data) { assistantUpdateData.user = req.user.id; } - promises.push(updateAssistantDoc({ assistant_id }, assistantUpdateData)); - promises.push(deleteAction({ action_id })); + promises.push(db.updateAssistantDoc({ assistant_id }, assistantUpdateData)); + promises.push(db.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..c660e6f99d 100644 --- a/api/server/routes/auth.js +++ b/api/server/routes/auth.js @@ -17,13 +17,14 @@ const { const { verify2FAWithTempToken } = require('~/server/controllers/auth/TwoFactorAuthController'); const { logoutController } = require('~/server/controllers/auth/LogoutController'); const { loginController } = require('~/server/controllers/auth/LoginController'); +const { findBalanceByUser, upsertBalanceFields } = require('~/models'); const { getAppConfig } = require('~/server/services/Config'); const middleware = require('~/server/middleware'); -const { Balance } = require('~/db/models'); const setBalanceConfig = createSetBalanceConfig({ getAppConfig, - Balance, + findBalanceByUser, + upsertBalanceFields, }); const router = express.Router(); @@ -63,7 +64,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/banner.js b/api/server/routes/banner.js index cf7eafd017..ad949fd2ca 100644 --- a/api/server/routes/banner.js +++ b/api/server/routes/banner.js @@ -1,13 +1,15 @@ const express = require('express'); - -const { getBanner } = require('~/models/Banner'); +const { logger } = require('@librechat/data-schemas'); const optionalJwtAuth = require('~/server/middleware/optionalJwtAuth'); +const { getBanner } = require('~/models'); + const router = express.Router(); router.get('/', optionalJwtAuth, async (req, res) => { try { res.status(200).send(await getBanner(req.user)); } catch (error) { + logger.error('[getBanner] Error getting banner', error); res.status(500).json({ message: 'Error getting banner' }); } }); diff --git a/api/server/routes/categories.js b/api/server/routes/categories.js index da1828b3ce..612bc37860 100644 --- a/api/server/routes/categories.js +++ b/api/server/routes/categories.js @@ -1,7 +1,7 @@ const express = require('express'); const router = express.Router(); const { requireJwtAuth } = require('~/server/middleware'); -const { getCategories } = require('~/models/Categories'); +const { getCategories } = require('~/models'); router.get('/', requireJwtAuth, async (req, res) => { try { diff --git a/api/server/routes/config.js b/api/server/routes/config.js index a2dc5b79d2..bf60f57e08 100644 --- a/api/server/routes/config.js +++ b/api/server/routes/config.js @@ -1,10 +1,9 @@ const express = require('express'); const { logger } = require('@librechat/data-schemas'); const { isEnabled, getBalanceConfig } = require('@librechat/api'); -const { Constants, CacheKeys, defaultSocialLogins } = require('librechat-data-provider'); +const { CacheKeys, defaultSocialLogins } = require('librechat-data-provider'); const { getLdapConfig } = require('~/server/services/Config/ldap'); const { getAppConfig } = require('~/server/services/Config/app'); -const { getProjectByName } = require('~/models/Project'); const { getLogStores } = require('~/cache'); const router = express.Router(); @@ -16,9 +15,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); @@ -37,8 +34,6 @@ router.get('/', async function (req, res) { return today.getMonth() === 1 && today.getDate() === 11; }; - const instanceProject = await getProjectByName(Constants.GLOBAL_PROJECT_NAME, '_id'); - const ldap = getLdapConfig(); try { @@ -101,7 +96,6 @@ router.get('/', async function (req, res) { sharedLinksEnabled, publicSharedLinksEnabled, analyticsGtmId: process.env.ANALYTICS_GTM_ID, - instanceProjectId: instanceProject._id.toString(), bundlerURL: process.env.SANDPACK_BUNDLER_URL, staticBundlerURL: process.env.SANDPACK_STATIC_BUNDLER_URL, sharePointFilePickerEnabled, diff --git a/api/server/routes/convos.js b/api/server/routes/convos.js index bb9c4ebea9..1964075ed3 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 { @@ -10,14 +10,12 @@ const { createForkLimiters, configMiddleware, } = require('~/server/middleware'); -const { getConvosByCursor, deleteConvos, getConvo, saveConvo } = require('~/models/Conversation'); const { forkConversation, duplicateConversation } = require('~/server/utils/import/fork'); const { storage, importFileFilter } = require('~/server/routes/files/multer'); -const { deleteAllSharedLinks, deleteConvoSharedLink } = require('~/models'); const requireJwtAuth = require('~/server/middleware/requireJwtAuth'); const { importConversations } = require('~/server/utils/import'); -const { deleteToolCalls } = require('~/models/ToolCall'); const getLogStores = require('~/cache/getLogStores'); +const db = require('~/models'); const assistantClients = { [EModelEndpoint.azureAssistants]: require('~/server/services/Endpoints/azureAssistants'), @@ -41,7 +39,7 @@ router.get('/', async (req, res) => { } try { - const result = await getConvosByCursor(req.user.id, { + const result = await db.getConvosByCursor(req.user.id, { cursor, limit, isArchived, @@ -59,7 +57,7 @@ router.get('/', async (req, res) => { router.get('/:conversationId', async (req, res) => { const { conversationId } = req.params; - const convo = await getConvo(req.user.id, conversationId); + const convo = await db.getConvo(req.user.id, conversationId); if (convo) { res.status(200).json(convo); @@ -128,10 +126,10 @@ router.delete('/', async (req, res) => { } try { - const dbResponse = await deleteConvos(req.user.id, filter); + const dbResponse = await db.deleteConvos(req.user.id, filter); if (filter.conversationId) { - await deleteToolCalls(req.user.id, filter.conversationId); - await deleteConvoSharedLink(req.user.id, filter.conversationId); + await db.deleteToolCalls(req.user.id, filter.conversationId); + await db.deleteConvoSharedLink(req.user.id, filter.conversationId); } res.status(201).json(dbResponse); } catch (error) { @@ -142,9 +140,9 @@ router.delete('/', async (req, res) => { router.delete('/all', async (req, res) => { try { - const dbResponse = await deleteConvos(req.user.id, {}); - await deleteToolCalls(req.user.id); - await deleteAllSharedLinks(req.user.id); + const dbResponse = await db.deleteConvos(req.user.id, {}); + await db.deleteToolCalls(req.user.id); + await db.deleteAllSharedLinks(req.user.id); res.status(201).json(dbResponse); } catch (error) { logger.error('Error clearing conversations', error); @@ -171,8 +169,12 @@ router.post('/archive', validateConvoAccess, async (req, res) => { } try { - const dbResponse = await saveConvo( - req, + const dbResponse = await db.saveConvo( + { + userId: req?.user?.id, + isTemporary: req?.body?.isTemporary, + interfaceConfig: req?.config?.interfaceConfig, + }, { conversationId, isArchived }, { context: `POST /api/convos/archive ${conversationId}` }, ); @@ -211,8 +213,12 @@ router.post('/update', validateConvoAccess, async (req, res) => { const sanitizedTitle = title.trim().slice(0, MAX_CONVO_TITLE_LENGTH); try { - const dbResponse = await saveConvo( - req, + const dbResponse = await db.saveConvo( + { + userId: req?.user?.id, + isTemporary: req?.body?.isTemporary, + interfaceConfig: req?.config?.interfaceConfig, + }, { conversationId, title: sanitizedTitle }, { context: `POST /api/convos/update ${conversationId}` }, ); @@ -224,8 +230,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 +263,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 +305,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.agents.test.js b/api/server/routes/files/files.agents.test.js index 7c21e95234..cb0e4ff3d2 100644 --- a/api/server/routes/files/files.agents.test.js +++ b/api/server/routes/files/files.agents.test.js @@ -2,16 +2,15 @@ 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 { createMethods, SystemCapabilities } = require('@librechat/data-schemas'); const { SystemRoles, AccessRoleIds, ResourceType, PrincipalType, } = require('librechat-data-provider'); -const { createAgent } = require('~/models/Agent'); -const { createFile } = require('~/models'); +const { createAgent, createFile } = require('~/models'); // Only mock the external dependencies that we don't want to test jest.mock('~/server/services/Files/process', () => ({ @@ -39,7 +38,16 @@ jest.mock('~/server/services/Tools/credentials', () => ({ loadAuthValues: jest.fn(), })); -jest.mock('~/server/services/Files/S3/crud', () => ({ +jest.mock('sharp', () => + jest.fn(() => ({ + metadata: jest.fn().mockResolvedValue({}), + toFormat: jest.fn().mockReturnThis(), + toBuffer: jest.fn().mockResolvedValue(Buffer.alloc(0)), + })), +); + +jest.mock('@librechat/api', () => ({ + ...jest.requireActual('@librechat/api'), refreshS3FileUrls: jest.fn(), })); @@ -83,6 +91,7 @@ describe('File Routes - Agent Files Endpoint', () => { let AclEntry; // eslint-disable-next-line no-unused-vars let AccessRole; + let SystemGrant; let modelsToCleanup = []; beforeAll(async () => { @@ -109,6 +118,7 @@ describe('File Routes - Agent Files Endpoint', () => { AclEntry = models.AclEntry; User = models.User; AccessRole = models.AccessRole; + SystemGrant = models.SystemGrant; // Seed default roles using our methods await methods.seedDefaultRoles(); @@ -533,7 +543,7 @@ describe('File Routes - Agent Files Endpoint', () => { expect(processAgentFileUpload).not.toHaveBeenCalled(); }); - it('should allow file upload for admin user regardless of agent ownership', async () => { + it('should allow file upload for user with MANAGE_AGENTS capability regardless of agent ownership', async () => { // Create an agent owned by authorId await createAgent({ id: agentCustomId, @@ -543,6 +553,14 @@ describe('File Routes - Agent Files Endpoint', () => { author: authorId, }); + // Seed MANAGE_AGENTS capability for the ADMIN role + await SystemGrant.create({ + principalType: PrincipalType.ROLE, + principalId: SystemRoles.ADMIN, + capability: SystemCapabilities.MANAGE_AGENTS, + grantedAt: new Date(), + }); + // Create app with admin user (otherUserId as admin) const testApp = createAppWithUser(otherUserId, SystemRoles.ADMIN); diff --git a/api/server/routes/files/files.js b/api/server/routes/files/files.js index 5de2ddb379..eb13ecdc31 100644 --- a/api/server/routes/files/files.js +++ b/api/server/routes/files/files.js @@ -1,13 +1,17 @@ const fs = require('fs').promises; const express = require('express'); const { EnvVar } = require('@librechat/agents'); -const { logger } = require('@librechat/data-schemas'); +const { logger, SystemCapabilities } = require('@librechat/data-schemas'); +const { + refreshS3FileUrls, + resolveUploadErrorMessage, + verifyAgentUploadPermission, +} = require('@librechat/api'); const { Time, isUUID, CacheKeys, FileSources, - SystemRoles, ResourceType, EModelEndpoint, PermissionBits, @@ -23,29 +27,27 @@ const { const { fileAccess } = require('~/server/middleware/accessResources/fileAccess'); const { getStrategyFunctions } = require('~/server/services/Files/strategies'); const { getOpenAIClient } = require('~/server/controllers/assistants/helpers'); +const { hasCapability } = require('~/server/middleware/roles/capabilities'); const { checkPermission } = require('~/server/services/PermissionService'); const { loadAuthValues } = require('~/server/services/Tools/credentials'); -const { refreshS3FileUrls } = require('~/server/services/Files/S3/crud'); const { hasAccessToFilesViaAgent } = require('~/server/services/Files'); -const { getFiles, batchUpdateFiles } = require('~/models'); const { cleanFileName } = require('~/server/utils/files'); -const { getAssistant } = require('~/models/Assistant'); -const { getAgent } = require('~/models/Agent'); const { getLogStores } = require('~/cache'); const { Readable } = require('stream'); +const db = require('~/models'); const router = express.Router(); router.get('/', async (req, res) => { try { const appConfig = req.config; - const files = await getFiles({ user: req.user.id }); + const files = await db.getFiles({ user: req.user.id }); if (appConfig.fileStrategy === FileSources.s3) { try { const cache = getLogStores(CacheKeys.S3_EXPIRY_INTERVAL); const alreadyChecked = await cache.get(req.user.id); if (!alreadyChecked) { - await refreshS3FileUrls(files, batchUpdateFiles); + await refreshS3FileUrls(files, db.batchUpdateFiles); await cache.set(req.user.id, true, Time.THIRTY_MINUTES); } } catch (error) { @@ -74,7 +76,7 @@ router.get('/agent/:agent_id', async (req, res) => { return res.status(400).json({ error: 'Agent ID is required' }); } - const agent = await getAgent({ id: agent_id }); + const agent = await db.getAgent({ id: agent_id }); if (!agent) { return res.status(200).json([]); } @@ -106,7 +108,7 @@ router.get('/agent/:agent_id', async (req, res) => { return res.status(200).json([]); } - const files = await getFiles({ file_id: { $in: agentFileIds } }, null, { text: 0 }); + const files = await db.getFiles({ file_id: { $in: agentFileIds } }, null, { text: 0 }); res.status(200).json(files); } catch (error) { @@ -151,7 +153,7 @@ router.delete('/', async (req, res) => { } const fileIds = files.map((file) => file.file_id); - const dbFiles = await getFiles({ file_id: { $in: fileIds } }); + const dbFiles = await db.getFiles({ file_id: { $in: fileIds } }); const ownedFiles = []; const nonOwnedFiles = []; @@ -209,7 +211,7 @@ router.delete('/', async (req, res) => { /* Handle agent unlinking even if no valid files to delete */ if (req.body.agent_id && req.body.tool_resource && dbFiles.length === 0) { - const agent = await getAgent({ + const agent = await db.getAgent({ id: req.body.agent_id, }); @@ -223,7 +225,7 @@ router.delete('/', async (req, res) => { /* Handle assistant unlinking even if no valid files to delete */ if (req.body.assistant_id && req.body.tool_resource && dbFiles.length === 0) { - const assistant = await getAssistant({ + const assistant = await db.getAssistant({ id: req.body.assistant_id, }); @@ -381,67 +383,31 @@ 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; + let skipUploadAuth = false; + try { + skipUploadAuth = await hasCapability(req.user, SystemCapabilities.MANAGE_AGENTS); + } catch (err) { + logger.warn(`[/files] capability check failed, denying bypass: ${err.message}`); + } - /** 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', - }); - } - } + if (!skipUploadAuth) { + const denied = await verifyAgentUploadPermission({ + req, + res, + metadata, + getAgent: db.getAgent, + checkPermission, + }); + if (denied) { + return; } } return await processAgentFileUpload({ req, res, metadata }); } catch (error) { - let message = 'Error processing file'; + const message = resolveUploadErrorMessage(error); logger.error('[/files] Error processing file:', error); - if (error.message?.includes('file_ids')) { - message += ': ' + error.message; - } - - if ( - error.message?.includes('Invalid file format') || - error.message?.includes('No OCR result') || - error.message?.includes('exceeds token limit') - ) { - message = error.message; - } - try { await fs.unlink(req.file.path); cleanup = false; diff --git a/api/server/routes/files/files.test.js b/api/server/routes/files/files.test.js index 1d548b44be..37cbf68b93 100644 --- a/api/server/routes/files/files.test.js +++ b/api/server/routes/files/files.test.js @@ -10,8 +10,7 @@ const { AccessRoleIds, PrincipalType, } = require('librechat-data-provider'); -const { createAgent } = require('~/models/Agent'); -const { createFile } = require('~/models'); +const { createAgent, createFile } = require('~/models'); // Only mock the external dependencies that we don't want to test jest.mock('~/server/services/Files/process', () => ({ @@ -33,7 +32,16 @@ jest.mock('~/server/services/Tools/credentials', () => ({ loadAuthValues: jest.fn(), })); -jest.mock('~/server/services/Files/S3/crud', () => ({ +jest.mock('sharp', () => + jest.fn(() => ({ + metadata: jest.fn().mockResolvedValue({}), + toFormat: jest.fn().mockReturnThis(), + toBuffer: jest.fn().mockResolvedValue(Buffer.alloc(0)), + })), +); + +jest.mock('@librechat/api', () => ({ + ...jest.requireActual('@librechat/api'), refreshS3FileUrls: jest.fn(), })); 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..f855a436d4 --- /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'); + +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..353557dc4f 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, resolveUploadErrorMessage } = 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 db = require('~/models'); 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: db.getAgent, + checkPermission, + }); + if (denied) { + return; + } return await processAgentFileUpload({ req, res, metadata }); } @@ -30,15 +43,7 @@ router.post('/', async (req, res) => { // TODO: delete remote file if it exists logger.error('[/files/images] Error processing file:', error); - let message = 'Error processing file'; - - if ( - error.message?.includes('Invalid file format') || - error.message?.includes('No OCR result') || - error.message?.includes('exceeds token limit') - ) { - message = error.message; - } + const message = resolveUploadErrorMessage(error); try { const filepath = path.join( diff --git a/api/server/routes/mcp.js b/api/server/routes/mcp.js index 2db8c2c462..d6d7ed5ea0 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, @@ -37,18 +38,28 @@ const { } = require('~/config'); const { getMCPSetupData, getServerConnectionStatus } = require('~/server/services/MCP'); const { requireJwtAuth, canAccessMCPServerResource } = require('~/server/middleware'); -const { findToken, updateToken, createToken, deleteTokens } = require('~/models'); const { getUserPluginAuthValue } = require('~/server/services/PluginService'); const { updateMCPServerTools } = require('~/server/services/Config/mcp'); const { reinitMCPServer } = require('~/server/services/Tools/mcp'); -const { findPluginAuthsByKeys } = require('~/models'); -const { getRoleByName } = require('~/models/Role'); const { getLogStores } = require('~/cache'); +const db = require('~/models'); const router = Router(); const OAUTH_CSRF_COOKIE_PATH = '/api/mcp'; +const checkMCPUsePermissions = generateCheckAccess({ + permissionType: PermissionTypes.MCP_SERVERS, + permissions: [Permissions.USE], + getRoleByName: db.getRoleByName, +}); + +const checkMCPCreate = generateCheckAccess({ + permissionType: PermissionTypes.MCP_SERVERS, + permissions: [Permissions.USE, Permissions.CREATE], + getRoleByName: db.getRoleByName, +}); + /** * Get all MCP tools available to the user * Returns only MCP tools, completely decoupled from regular LibreChat tools @@ -91,7 +102,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 +116,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 +159,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); @@ -206,9 +244,9 @@ router.get('/:serverName/oauth/callback', async (req, res) => { userId: flowState.userId, serverName, tokens, - createToken, - updateToken, - findToken, + createToken: db.createToken, + updateToken: db.updateToken, + findToken: db.findToken, clientInfo: flowState.clientInfo, metadata: flowState.metadata, }); @@ -246,10 +284,10 @@ router.get('/:serverName/oauth/callback', async (req, res) => { serverName, flowManager, tokenMethods: { - findToken, - updateToken, - createToken, - deleteTokens, + findToken: db.findToken, + updateToken: db.updateToken, + createToken: db.createToken, + deleteTokens: db.deleteTokens, }, }); @@ -281,7 +319,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 +480,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: db.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 +655,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 +712,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/memories.js b/api/server/routes/memories.js index 58955d8ec4..e71e94f457 100644 --- a/api/server/routes/memories.js +++ b/api/server/routes/memories.js @@ -4,12 +4,12 @@ const { PermissionTypes, Permissions } = require('librechat-data-provider'); const { getAllUserMemories, toggleUserMemories, + getRoleByName, createMemory, deleteMemory, setMemory, } = require('~/models'); const { requireJwtAuth, configMiddleware } = require('~/server/middleware'); -const { getRoleByName } = require('~/models/Role'); const router = express.Router(); diff --git a/api/server/routes/messages.js b/api/server/routes/messages.js index c208e9c406..21b2b23fea 100644 --- a/api/server/routes/messages.js +++ b/api/server/routes/messages.js @@ -3,18 +3,9 @@ const { v4: uuidv4 } = require('uuid'); const { logger } = require('@librechat/data-schemas'); const { ContentTypes } = require('librechat-data-provider'); const { unescapeLaTeX, countTokens } = require('@librechat/api'); -const { - saveConvo, - getMessage, - saveMessage, - getMessages, - updateMessage, - deleteMessages, -} = require('~/models'); const { findAllArtifacts, replaceArtifactContent } = require('~/server/services/Artifacts/update'); const { requireJwtAuth, validateMessageReq } = require('~/server/middleware'); -const { getConvosQueried } = require('~/models/Conversation'); -const { Message } = require('~/db/models'); +const db = require('~/models'); const router = express.Router(); router.use(requireJwtAuth); @@ -40,34 +31,19 @@ router.get('/', async (req, res) => { const sortOrder = sortDirection === 'asc' ? 1 : -1; if (conversationId && messageId) { - const message = await Message.findOne({ - conversationId, - messageId, - user: user, - }).lean(); - response = { messages: message ? [message] : [], nextCursor: null }; + const messages = await db.getMessages({ conversationId, messageId, user }); + response = { messages: messages?.length ? [messages[0]] : [], nextCursor: null }; } else if (conversationId) { - const filter = { conversationId, user: user }; - if (cursor) { - filter[sortField] = sortOrder === 1 ? { $gt: cursor } : { $lt: cursor }; - } - const messages = await Message.find(filter) - .sort({ [sortField]: sortOrder }) - .limit(pageSize + 1) - .lean(); - let nextCursor = null; - if (messages.length > pageSize) { - messages.pop(); // Remove extra item used to detect next page - // Create cursor from the last RETURNED item (not the popped one) - nextCursor = messages[messages.length - 1][sortField]; - } - response = { messages, nextCursor }; + response = await db.getMessagesByCursor( + { conversationId, user }, + { sortField, sortOrder, limit: pageSize, cursor }, + ); } else if (search) { - const searchResults = await Message.meiliSearch(search, { filter: `user = "${user}"` }, true); + const searchResults = await db.searchMessages(search, { filter: `user = "${user}"` }, true); const messages = searchResults.hits || []; - const result = await getConvosQueried(req.user.id, messages, cursor); + const result = await db.getConvosQueried(req.user.id, messages, cursor); const messageIds = []; const cleanedMessages = []; @@ -79,7 +55,7 @@ router.get('/', async (req, res) => { } } - const dbMessages = await getMessages({ + const dbMessages = await db.getMessages({ user, messageId: { $in: messageIds }, }); @@ -136,7 +112,7 @@ router.post('/branch', async (req, res) => { return res.status(400).json({ error: 'messageId and agentId are required' }); } - const sourceMessage = await getMessage({ user: userId, messageId }); + const sourceMessage = await db.getMessage({ user: userId, messageId }); if (!sourceMessage) { return res.status(404).json({ error: 'Source message not found' }); } @@ -187,9 +163,15 @@ router.post('/branch', async (req, res) => { user: userId, }; - const savedMessage = await saveMessage(req, newMessage, { - context: 'POST /api/messages/branch', - }); + const savedMessage = await db.saveMessage( + { + userId: req?.user?.id, + isTemporary: req?.body?.isTemporary, + interfaceConfig: req?.config?.interfaceConfig, + }, + newMessage, + { context: 'POST /api/messages/branch' }, + ); if (!savedMessage) { return res.status(500).json({ error: 'Failed to save branch message' }); @@ -211,7 +193,7 @@ router.post('/artifact/:messageId', async (req, res) => { return res.status(400).json({ error: 'Invalid request parameters' }); } - const message = await getMessage({ user: req.user.id, messageId }); + const message = await db.getMessage({ user: req.user.id, messageId }); if (!message) { return res.status(404).json({ error: 'Message not found' }); } @@ -256,8 +238,12 @@ router.post('/artifact/:messageId', async (req, res) => { return res.status(400).json({ error: 'Original content not found in target artifact' }); } - const savedMessage = await saveMessage( - req, + const savedMessage = await db.saveMessage( + { + userId: req?.user?.id, + isTemporary: req?.body?.isTemporary, + interfaceConfig: req?.config?.interfaceConfig, + }, { messageId, conversationId: message.conversationId, @@ -283,7 +269,7 @@ router.post('/artifact/:messageId', async (req, res) => { router.get('/:conversationId', validateMessageReq, async (req, res) => { try { const { conversationId } = req.params; - const messages = await getMessages({ conversationId }, '-_id -__v -user'); + const messages = await db.getMessages({ conversationId }, '-_id -__v -user'); res.status(200).json(messages); } catch (error) { logger.error('Error fetching messages:', error); @@ -294,15 +280,20 @@ router.get('/:conversationId', validateMessageReq, async (req, res) => { router.post('/:conversationId', validateMessageReq, async (req, res) => { try { const message = req.body; - const savedMessage = await saveMessage( - req, + const reqCtx = { + userId: req?.user?.id, + isTemporary: req?.body?.isTemporary, + interfaceConfig: req?.config?.interfaceConfig, + }; + const savedMessage = await db.saveMessage( + reqCtx, { ...message, user: req.user.id }, { context: 'POST /api/messages/:conversationId' }, ); if (!savedMessage) { return res.status(400).json({ error: 'Message not saved' }); } - await saveConvo(req, savedMessage, { context: 'POST /api/messages/:conversationId' }); + await db.saveConvo(reqCtx, savedMessage, { context: 'POST /api/messages/:conversationId' }); res.status(201).json(savedMessage); } catch (error) { logger.error('Error saving message:', error); @@ -313,7 +304,7 @@ router.post('/:conversationId', validateMessageReq, async (req, res) => { router.get('/:conversationId/:messageId', validateMessageReq, async (req, res) => { try { const { conversationId, messageId } = req.params; - const message = await getMessages({ conversationId, messageId }, '-_id -__v -user'); + const message = await db.getMessages({ conversationId, messageId }, '-_id -__v -user'); if (!message) { return res.status(404).json({ error: 'Message not found' }); } @@ -331,7 +322,7 @@ router.put('/:conversationId/:messageId', validateMessageReq, async (req, res) = if (index === undefined) { const tokenCount = await countTokens(text, model); - const result = await updateMessage(req, { messageId, text, tokenCount }); + const result = await db.updateMessage(req?.user?.id, { messageId, text, tokenCount }); return res.status(200).json(result); } @@ -339,7 +330,9 @@ router.put('/:conversationId/:messageId', validateMessageReq, async (req, res) = return res.status(400).json({ error: 'Invalid index' }); } - const message = (await getMessages({ conversationId, messageId }, 'content tokenCount'))?.[0]; + const message = ( + await db.getMessages({ conversationId, messageId }, 'content tokenCount') + )?.[0]; if (!message) { return res.status(404).json({ error: 'Message not found' }); } @@ -369,7 +362,11 @@ router.put('/:conversationId/:messageId', validateMessageReq, async (req, res) = tokenCount = Math.max(0, tokenCount - oldTokenCount) + newTokenCount; } - const result = await updateMessage(req, { messageId, content: updatedContent, tokenCount }); + const result = await db.updateMessage(req?.user?.id, { + messageId, + content: updatedContent, + tokenCount, + }); return res.status(200).json(result); } catch (error) { logger.error('Error updating message:', error); @@ -382,8 +379,8 @@ router.put('/:conversationId/:messageId/feedback', validateMessageReq, async (re const { conversationId, messageId } = req.params; const { feedback } = req.body; - const updatedMessage = await updateMessage( - req, + const updatedMessage = await db.updateMessage( + req?.user?.id, { messageId, feedback: feedback || null, @@ -404,8 +401,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 db.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/oauth.js b/api/server/routes/oauth.js index f4bb5b6026..5302158031 100644 --- a/api/server/routes/oauth.js +++ b/api/server/routes/oauth.js @@ -7,12 +7,13 @@ const { ErrorTypes } = require('librechat-data-provider'); const { createSetBalanceConfig } = require('@librechat/api'); const { checkDomainAllowed, loginLimiter, logHeaders } = require('~/server/middleware'); const { createOAuthHandler } = require('~/server/controllers/auth/oauth'); +const { findBalanceByUser, upsertBalanceFields } = require('~/models'); const { getAppConfig } = require('~/server/services/Config'); -const { Balance } = require('~/db/models'); const setBalanceConfig = createSetBalanceConfig({ getAppConfig, - Balance, + findBalanceByUser, + upsertBalanceFields, }); const router = express.Router(); diff --git a/api/server/routes/prompts.js b/api/server/routes/prompts.js index 037bf04813..5fcf51ba73 100644 --- a/api/server/routes/prompts.js +++ b/api/server/routes/prompts.js @@ -1,5 +1,6 @@ const express = require('express'); -const { logger } = require('@librechat/data-schemas'); +const { ObjectId } = require('mongodb'); +const { logger, isValidObjectIdString } = require('@librechat/data-schemas'); const { generateCheckAccess, markPublicPromptGroups, @@ -11,28 +12,32 @@ const { } = require('@librechat/api'); const { Permissions, - SystemRoles, ResourceType, AccessRoleIds, PrincipalType, PermissionBits, PermissionTypes, } = require('librechat-data-provider'); +const { SystemCapabilities } = require('@librechat/data-schemas'); const { getListPromptGroupsByAccess, + getOwnedPromptGroupIds, + incrementPromptGroupUsage, makePromptProduction, updatePromptGroup, deletePromptGroup, createPromptGroup, getPromptGroup, + getRoleByName, deletePrompt, getPrompts, savePrompt, getPrompt, -} = require('~/models/Prompt'); +} = require('~/models'); const { canAccessPromptGroupResource, canAccessPromptViaGroup, + promptUsageLimiter, requireJwtAuth, } = require('~/server/middleware'); const { @@ -41,7 +46,7 @@ const { findAccessibleResources, grantPermission, } = require('~/server/services/PermissionService'); -const { getRoleByName } = require('~/models/Role'); +const { hasCapability } = require('~/server/middleware/roles/capabilities'); const router = express.Router(); @@ -56,18 +61,15 @@ const checkPromptCreate = generateCheckAccess({ getRoleByName, }); +router.use(requireJwtAuth); +router.use(checkPromptAccess); + const checkGlobalPromptShare = generateCheckAccess({ permissionType: PermissionTypes.PROMPTS, permissions: [Permissions.USE, Permissions.CREATE], - bodyProps: { - [Permissions.SHARE]: ['projectIds', 'removeProjectIds'], - }, getRoleByName, }); -router.use(requireJwtAuth); -router.use(checkPromptAccess); - /** * Route to get single prompt group by its ID * GET /groups/:groupId @@ -102,11 +104,10 @@ router.get( router.get('/all', async (req, res) => { try { const userId = req.user.id; - const { name, category, ...otherFilters } = req.query; + const { name, category } = req.query; const { filter, searchShared, searchSharedOnly } = buildPromptGroupFilter({ name, category, - ...otherFilters, }); let accessibleIds = await findAccessibleResources({ @@ -116,16 +117,20 @@ router.get('/all', async (req, res) => { requiredPermissions: PermissionBits.VIEW, }); - const publiclyAccessibleIds = await findPubliclyAccessibleResources({ - resourceType: ResourceType.PROMPTGROUP, - requiredPermissions: PermissionBits.VIEW, - }); + const [publiclyAccessibleIds, ownedPromptGroupIds] = await Promise.all([ + findPubliclyAccessibleResources({ + resourceType: ResourceType.PROMPTGROUP, + requiredPermissions: PermissionBits.VIEW, + }), + getOwnedPromptGroupIds(userId), + ]); const filteredAccessibleIds = await filterAccessibleIdsBySharedLogic({ accessibleIds, searchShared, searchSharedOnly, publicPromptGroupIds: publiclyAccessibleIds, + ownedPromptGroupIds, }); const result = await getListPromptGroupsByAccess({ @@ -157,12 +162,11 @@ router.get('/all', async (req, res) => { router.get('/groups', async (req, res) => { try { const userId = req.user.id; - const { pageSize, limit, cursor, name, category, ...otherFilters } = req.query; + const { pageSize, limit, cursor, name, category } = req.query; const { filter, searchShared, searchSharedOnly } = buildPromptGroupFilter({ name, category, - ...otherFilters, }); let actualLimit = limit; @@ -186,16 +190,20 @@ router.get('/groups', async (req, res) => { requiredPermissions: PermissionBits.VIEW, }); - const publiclyAccessibleIds = await findPubliclyAccessibleResources({ - resourceType: ResourceType.PROMPTGROUP, - requiredPermissions: PermissionBits.VIEW, - }); + const [publiclyAccessibleIds, ownedPromptGroupIds] = await Promise.all([ + findPubliclyAccessibleResources({ + resourceType: ResourceType.PROMPTGROUP, + requiredPermissions: PermissionBits.VIEW, + }), + getOwnedPromptGroupIds(userId), + ]); const filteredAccessibleIds = await filterAccessibleIdsBySharedLogic({ accessibleIds, searchShared, searchSharedOnly, publicPromptGroupIds: publiclyAccessibleIds, + ownedPromptGroupIds, }); // Cursor-based pagination only @@ -299,6 +307,16 @@ const addPromptToGroup = async (req, res) => { return res.status(400).send({ error: 'Prompt is required' }); } + if (typeof prompt.prompt !== 'string' || !prompt.prompt.trim()) { + return res + .status(400) + .send({ error: 'Prompt text is required and must be a non-empty string' }); + } + + if (prompt.type !== 'text' && prompt.type !== 'chat') { + return res.status(400).send({ error: 'Prompt type must be "text" or "chat"' }); + } + // Ensure the prompt is associated with the correct group prompt.groupId = groupId; @@ -329,6 +347,37 @@ router.post( addPromptToGroup, ); +/** + * Records a prompt group usage (increments numberOfGenerations) + * POST /groups/:groupId/use + */ +router.post( + '/groups/:groupId/use', + promptUsageLimiter, + canAccessPromptGroupResource({ + requiredPermission: PermissionBits.VIEW, + }), + async (req, res) => { + try { + const { groupId } = req.params; + if (!isValidObjectIdString(groupId)) { + return res.status(400).send({ error: 'Invalid groupId' }); + } + const result = await incrementPromptGroupUsage(groupId); + res.status(200).send(result); + } catch (error) { + logger.error('[recordPromptUsage]', error); + if (error.message === 'Invalid groupId') { + return res.status(400).send({ error: 'Invalid groupId' }); + } + if (error.message === 'Prompt group not found') { + return res.status(404).send({ error: 'Prompt group not found' }); + } + res.status(500).send({ error: 'Error recording prompt usage' }); + } + }, +); + /** * Updates a prompt group * @param {object} req @@ -340,11 +389,8 @@ router.post( const patchPromptGroup = async (req, res) => { try { const { groupId } = req.params; - const author = req.user.id; - const filter = { _id: groupId, author }; - if (req.user.role === SystemRoles.ADMIN) { - delete filter.author; - } + // Don't pass author - permissions are now checked by middleware + const filter = { _id: groupId }; const validationResult = safeValidatePromptGroupUpdate(req.body); if (!validationResult.success) { @@ -410,6 +456,10 @@ router.get('/', async (req, res) => { // If requesting prompts for a specific group, check permissions if (groupId) { + if (!isValidObjectIdString(groupId)) { + return res.status(400).send({ error: 'Invalid groupId' }); + } + const permissions = await getEffectivePermissions({ userId: req.user.id, role: req.user.role, @@ -424,13 +474,20 @@ router.get('/', async (req, res) => { } // If user has access, fetch all prompts in the group (not just their own) - const prompts = await getPrompts({ groupId }); + const prompts = await getPrompts({ groupId: new ObjectId(groupId) }); return res.status(200).send(prompts); } // If no groupId, return user's own prompts const query = { author }; - if (req.user.role === SystemRoles.ADMIN) { + let canReadPrompts = false; + try { + canReadPrompts = await hasCapability(req.user, SystemCapabilities.READ_PROMPTS); + } catch (err) { + logger.warn(`[GET /prompts] capability check failed, denying bypass: ${err.message}`); + } + if (canReadPrompts) { + logger.debug(`[GET /prompts] READ_PROMPTS bypass for user ${req.user.id}`); delete query.author; } const prompts = await getPrompts(query); @@ -454,8 +511,10 @@ const deletePromptController = async (req, res) => { try { const { promptId } = req.params; const { groupId } = req.query; - const author = req.user.id; - const query = { promptId, groupId, author, role: req.user.role }; + if (!groupId || !isValidObjectIdString(groupId)) { + return res.status(400).send({ error: 'Invalid or missing groupId' }); + } + const query = { promptId, groupId }; const result = await deletePrompt(query); res.status(200).send(result); } catch (error) { @@ -473,8 +532,8 @@ const deletePromptController = async (req, res) => { const deletePromptGroupController = async (req, res) => { try { const { groupId: _id } = req.params; - // Don't pass author - permissions are now checked by middleware - const message = await deletePromptGroup({ _id, role: req.user.role }); + // Don't pass author or role - permissions are checked by ACL middleware + const message = await deletePromptGroup({ _id }); res.send(message); } catch (error) { logger.error('Error deleting prompt group', error); diff --git a/api/server/routes/prompts.test.js b/api/server/routes/prompts.test.js index caeb90ddfb..c979023ffc 100644 --- a/api/server/routes/prompts.test.js +++ b/api/server/routes/prompts.test.js @@ -10,18 +10,33 @@ const { PrincipalType, PermissionBits, } = require('librechat-data-provider'); +const { SystemCapabilities } = require('@librechat/data-schemas'); // Mock modules before importing jest.mock('~/server/services/Config', () => ({ getCachedTools: jest.fn().mockResolvedValue({}), })); -jest.mock('~/models/Role', () => ({ - getRoleByName: jest.fn(), -})); +jest.mock('~/models', () => { + const mongoose = require('mongoose'); + const { createMethods } = require('@librechat/data-schemas'); + const methods = createMethods(mongoose, { + removeAllPermissions: async ({ resourceType, resourceId }) => { + const AclEntry = mongoose.models.AclEntry; + if (AclEntry) { + await AclEntry.deleteMany({ resourceType, resourceId }); + } + }, + }); + return { + ...methods, + getRoleByName: jest.fn(), + }; +}); jest.mock('~/server/middleware', () => ({ requireJwtAuth: (req, res, next) => next(), + promptUsageLimiter: (req, res, next) => next(), canAccessPromptViaGroup: jest.requireActual('~/server/middleware').canAccessPromptViaGroup, canAccessPromptGroupResource: jest.requireActual('~/server/middleware').canAccessPromptGroupResource, @@ -30,7 +45,7 @@ jest.mock('~/server/middleware', () => ({ let app; let mongoServer; let promptRoutes; -let Prompt, PromptGroup, AclEntry, AccessRole, User; +let Prompt, PromptGroup, AclEntry, AccessRole, User, SystemGrant; let testUsers, testRoles; let grantPermission; let currentTestUser; // Track current user for middleware @@ -52,6 +67,7 @@ beforeAll(async () => { AclEntry = dbModels.AclEntry; AccessRole = dbModels.AccessRole; User = dbModels.User; + SystemGrant = dbModels.SystemGrant; // Import permission service const permissionService = require('~/server/services/PermissionService'); @@ -152,8 +168,24 @@ async function setupTestData() { }), }; + // Seed capabilities for the ADMIN role + await SystemGrant.create([ + { + principalType: PrincipalType.ROLE, + principalId: SystemRoles.ADMIN, + capability: SystemCapabilities.MANAGE_PROMPTS, + grantedAt: new Date(), + }, + { + principalType: PrincipalType.ROLE, + principalId: SystemRoles.ADMIN, + capability: SystemCapabilities.READ_PROMPTS, + grantedAt: new Date(), + }, + ]); + // Mock getRoleByName - const { getRoleByName } = require('~/models/Role'); + const { getRoleByName } = require('~/models'); getRoleByName.mockImplementation((roleName) => { switch (roleName) { case SystemRoles.USER: diff --git a/api/server/routes/roles.js b/api/server/routes/roles.js index 12e18c7624..25ee47854d 100644 --- a/api/server/routes/roles.js +++ b/api/server/routes/roles.js @@ -1,4 +1,5 @@ const express = require('express'); +const { logger, SystemCapabilities } = require('@librechat/data-schemas'); const { SystemRoles, roleDefaults, @@ -11,11 +12,13 @@ const { peoplePickerPermissionsSchema, remoteAgentsPermissionsSchema, } = require('librechat-data-provider'); -const { checkAdmin, requireJwtAuth } = require('~/server/middleware'); -const { updateRoleByName, getRoleByName } = require('~/models/Role'); +const { hasCapability, requireCapability } = require('~/server/middleware/roles/capabilities'); +const { updateRoleByName, getRoleByName } = require('~/models'); +const { requireJwtAuth } = require('~/server/middleware'); const router = express.Router(); router.use(requireJwtAuth); +const manageRoles = requireCapability(SystemCapabilities.MANAGE_ROLES); /** * Permission configuration mapping @@ -111,14 +114,17 @@ router.get('/:roleName', async (req, res) => { // TODO: TEMP, use a better parsing for roleName const roleName = _r.toUpperCase(); - if ( - (req.user.role !== SystemRoles.ADMIN && roleName === SystemRoles.ADMIN) || - (req.user.role !== SystemRoles.ADMIN && !roleDefaults[roleName]) - ) { - return res.status(403).send({ message: 'Unauthorized' }); - } - try { + let hasReadRoles = false; + try { + hasReadRoles = await hasCapability(req.user, SystemCapabilities.READ_ROLES); + } catch (err) { + logger.warn(`[GET /roles/:roleName] capability check failed: ${err.message}`); + } + if (!hasReadRoles && (roleName === SystemRoles.ADMIN || !roleDefaults[roleName])) { + return res.status(403).send({ message: 'Unauthorized' }); + } + const role = await getRoleByName(roleName, '-_id -__v'); if (!role) { return res.status(404).send({ message: 'Role not found' }); @@ -126,7 +132,8 @@ router.get('/:roleName', async (req, res) => { res.status(200).send(role); } catch (error) { - return res.status(500).send({ message: 'Failed to retrieve role', error: error.message }); + logger.error('[GET /roles/:roleName] Error:', error); + return res.status(500).send({ message: 'Failed to retrieve role' }); } }); @@ -134,42 +141,42 @@ router.get('/:roleName', async (req, res) => { * PUT /api/roles/:roleName/prompts * Update prompt permissions for a specific role */ -router.put('/:roleName/prompts', checkAdmin, createPermissionUpdateHandler('prompts')); +router.put('/:roleName/prompts', manageRoles, createPermissionUpdateHandler('prompts')); /** * PUT /api/roles/:roleName/agents * Update agent permissions for a specific role */ -router.put('/:roleName/agents', checkAdmin, createPermissionUpdateHandler('agents')); +router.put('/:roleName/agents', manageRoles, createPermissionUpdateHandler('agents')); /** * PUT /api/roles/:roleName/memories * Update memory permissions for a specific role */ -router.put('/:roleName/memories', checkAdmin, createPermissionUpdateHandler('memories')); +router.put('/:roleName/memories', manageRoles, createPermissionUpdateHandler('memories')); /** * PUT /api/roles/:roleName/people-picker * Update people picker permissions for a specific role */ -router.put('/:roleName/people-picker', checkAdmin, createPermissionUpdateHandler('people-picker')); +router.put('/:roleName/people-picker', manageRoles, createPermissionUpdateHandler('people-picker')); /** * PUT /api/roles/:roleName/mcp-servers * Update MCP servers permissions for a specific role */ -router.put('/:roleName/mcp-servers', checkAdmin, createPermissionUpdateHandler('mcp-servers')); +router.put('/:roleName/mcp-servers', manageRoles, createPermissionUpdateHandler('mcp-servers')); /** * PUT /api/roles/:roleName/marketplace * Update marketplace permissions for a specific role */ -router.put('/:roleName/marketplace', checkAdmin, createPermissionUpdateHandler('marketplace')); +router.put('/:roleName/marketplace', manageRoles, createPermissionUpdateHandler('marketplace')); /** * PUT /api/roles/:roleName/remote-agents * Update remote agents (API) permissions for a specific role */ -router.put('/:roleName/remote-agents', checkAdmin, createPermissionUpdateHandler('remote-agents')); +router.put('/:roleName/remote-agents', manageRoles, createPermissionUpdateHandler('remote-agents')); module.exports = router; 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/routes/tags.js b/api/server/routes/tags.js index 0a4ee5084c..a1fa1f77bb 100644 --- a/api/server/routes/tags.js +++ b/api/server/routes/tags.js @@ -8,9 +8,9 @@ const { createConversationTag, deleteConversationTag, getConversationTags, -} = require('~/models/ConversationTag'); + getRoleByName, +} = require('~/models'); const { requireJwtAuth } = require('~/server/middleware'); -const { getRoleByName } = require('~/models/Role'); const router = express.Router(); diff --git a/api/server/services/ActionService.js b/api/server/services/ActionService.js index 5e96726a46..c8ed7bebc4 100644 --- a/api/server/services/ActionService.js +++ b/api/server/services/ActionService.js @@ -20,14 +20,20 @@ const { isImageVisionTool, actionDomainSeparator, } = require('librechat-data-provider'); -const { findToken, updateToken, createToken } = require('~/models'); -const { getActions, deleteActions } = require('~/models/Action'); -const { deleteAssistant } = require('~/models/Assistant'); +const { + findToken, + updateToken, + createToken, + getActions, + deleteActions, + deleteAssistant, +} = require('~/models'); const { getFlowStateManager } = require('~/config'); const { getLogStores } = require('~/cache'); const JWT_SECRET = process.env.JWT_SECRET; const toolNameRegex = /^[a-zA-Z0-9_-]+$/; +const protocolRegex = /^https?:\/\//; const replaceSeparatorRegex = new RegExp(actionDomainSeparator, 'g'); /** @@ -48,7 +54,11 @@ const validateAndUpdateTool = async ({ req, tool, assistant_id }) => { actions = await getActions({ assistant_id, user: req.user.id }, true); const matchingActions = actions.filter((action) => { const metadata = action.metadata; - return metadata && metadata.domain === domain; + if (!metadata) { + return false; + } + const strippedMetaDomain = stripProtocol(metadata.domain); + return strippedMetaDomain === domain || metadata.domain === domain; }); const action = matchingActions[0]; if (!action) { @@ -66,10 +76,36 @@ const validateAndUpdateTool = async ({ req, tool, assistant_id }) => { return tool; }; +/** @param {string} domain */ +function stripProtocol(domain) { + const stripped = domain.replace(protocolRegex, ''); + const pathIdx = stripped.indexOf('/'); + return pathIdx === -1 ? stripped : stripped.substring(0, pathIdx); +} + +/** + * Encodes a domain using the legacy scheme (full URL including protocol). + * Used for backward-compatible matching against agents saved before the collision fix. + * @param {string} domain + * @returns {string} + */ +function legacyDomainEncode(domain) { + if (!domain) { + return ''; + } + if (domain.length <= Constants.ENCODED_DOMAIN_LENGTH) { + return domain.replace(/\./g, actionDomainSeparator); + } + const modifiedDomain = Buffer.from(domain).toString('base64'); + return modifiedDomain.substring(0, Constants.ENCODED_DOMAIN_LENGTH); +} + /** * Encodes or decodes a domain name to/from base64, or replacing periods with a custom separator. * * Necessary due to `[a-zA-Z0-9_-]*` Regex Validation, limited to a 64-character maximum. + * Strips protocol prefix before encoding to prevent base64 collisions + * (all `https://` URLs share the same 10-char base64 prefix). * * @param {string} domain - The domain name to encode/decode. * @param {boolean} inverse - False to decode from base64, true to encode to base64. @@ -79,23 +115,27 @@ async function domainParser(domain, inverse = false) { if (!domain) { return; } - const domainsCache = getLogStores(CacheKeys.ENCODED_DOMAINS); - const cachedDomain = await domainsCache.get(domain); - if (inverse && cachedDomain) { - return domain; - } - if (inverse && domain.length <= Constants.ENCODED_DOMAIN_LENGTH) { - return domain.replace(/\./g, actionDomainSeparator); - } + const domainsCache = getLogStores(CacheKeys.ENCODED_DOMAINS); if (inverse) { - const modifiedDomain = Buffer.from(domain).toString('base64'); + const hostname = stripProtocol(domain); + const cachedDomain = await domainsCache.get(hostname); + if (cachedDomain) { + return hostname; + } + + if (hostname.length <= Constants.ENCODED_DOMAIN_LENGTH) { + return hostname.replace(/\./g, actionDomainSeparator); + } + + const modifiedDomain = Buffer.from(hostname).toString('base64'); const key = modifiedDomain.substring(0, Constants.ENCODED_DOMAIN_LENGTH); await domainsCache.set(key, modifiedDomain); return key; } + const cachedDomain = await domainsCache.get(domain); if (!cachedDomain) { return domain.replace(replaceSeparatorRegex, '.'); } @@ -456,6 +496,7 @@ const deleteAssistantActions = async ({ req, assistant_id }) => { module.exports = { deleteAssistantActions, validateAndUpdateTool, + legacyDomainEncode, createActionTool, encryptMetadata, decryptMetadata, diff --git a/api/server/services/ActionService.spec.js b/api/server/services/ActionService.spec.js index c60aef7ad1..52419975f7 100644 --- a/api/server/services/ActionService.spec.js +++ b/api/server/services/ActionService.spec.js @@ -1,175 +1,539 @@ -const { Constants, actionDomainSeparator } = require('librechat-data-provider'); -const { domainParser } = require('./ActionService'); +const { Constants, actionDelimiter, actionDomainSeparator } = require('librechat-data-provider'); +const { domainParser, legacyDomainEncode, validateAndUpdateTool } = require('./ActionService'); jest.mock('keyv'); -const globalCache = {}; +jest.mock('~/models', () => ({ + getActions: jest.fn(), + deleteActions: jest.fn(), +})); + +const { getActions } = require('~/models'); + +let mockDomainCache = {}; jest.mock('~/cache/getLogStores', () => { - return jest.fn().mockImplementation(() => { - const EventEmitter = require('events'); - const { CacheKeys } = require('librechat-data-provider'); + return jest.fn().mockImplementation(() => ({ + get: async (key) => mockDomainCache[key] ?? null, + set: async (key, value) => { + mockDomainCache[key] = value; + return true; + }, + })); +}); - class KeyvMongo extends EventEmitter { - constructor(url = 'mongodb://127.0.0.1:27017', options) { - super(); - this.ttlSupport = false; - url = url ?? {}; - if (typeof url === 'string') { - url = { url }; - } - if (url.uri) { - url = { url: url.uri, ...url }; - } - this.opts = { - url, - collection: 'keyv', - ...url, - ...options, - }; - } +beforeEach(() => { + mockDomainCache = {}; + getActions.mockReset(); +}); - get = async (key) => { - return new Promise((resolve) => { - resolve(globalCache[key] || null); - }); - }; +const SEP = actionDomainSeparator; +const DELIM = actionDelimiter; +const MAX = Constants.ENCODED_DOMAIN_LENGTH; +const domainSepRegex = new RegExp(SEP, 'g'); - set = async (key, value) => { - return new Promise((resolve) => { - globalCache[key] = value; - resolve(true); - }); - }; - } +describe('domainParser', () => { + describe('nullish input', () => { + it.each([null, undefined, ''])('returns undefined for %j', async (input) => { + expect(await domainParser(input, true)).toBeUndefined(); + expect(await domainParser(input, false)).toBeUndefined(); + }); + }); - return new KeyvMongo('', { - namespace: CacheKeys.ENCODED_DOMAINS, - ttl: 0, + describe('short-path encoding (hostname ≤ threshold)', () => { + it.each([ + ['examp.com', `examp${SEP}com`], + ['swapi.tech', `swapi${SEP}tech`], + ['a.b', `a${SEP}b`], + ])('replaces dots in %s → %s', async (domain, expected) => { + expect(await domainParser(domain, true)).toBe(expected); + }); + + it('handles domain exactly at threshold length', async () => { + const domain = 'a'.repeat(MAX - 4) + '.com'; + expect(domain).toHaveLength(MAX); + const result = await domainParser(domain, true); + expect(result).toBe(domain.replace(/\./g, SEP)); + }); + }); + + describe('base64-path encoding (hostname > threshold)', () => { + it('produces a key of exactly ENCODED_DOMAIN_LENGTH chars', async () => { + const result = await domainParser('api.example.com', true); + expect(result).toHaveLength(MAX); + }); + + it('encodes hostname, not full URL', async () => { + const hostname = 'api.example.com'; + const expectedKey = Buffer.from(hostname).toString('base64').substring(0, MAX); + expect(await domainParser(hostname, true)).toBe(expectedKey); + }); + + it('populates decode cache for round-trip', async () => { + const hostname = 'longdomainname.com'; + const key = await domainParser(hostname, true); + + expect(mockDomainCache[key]).toBe(Buffer.from(hostname).toString('base64')); + expect(await domainParser(key, false)).toBe(hostname); + }); + }); + + describe('protocol stripping', () => { + it('https:// URL and bare hostname produce identical encoding', async () => { + const encoded = await domainParser('https://swapi.tech', true); + expect(encoded).toBe(await domainParser('swapi.tech', true)); + expect(encoded).toBe(`swapi${SEP}tech`); + }); + + it('http:// URL and bare hostname produce identical encoding', async () => { + const encoded = await domainParser('http://api.example.com', true); + expect(encoded).toBe(await domainParser('api.example.com', true)); + }); + + it('different https:// domains produce unique keys', async () => { + const keys = await Promise.all([ + domainParser('https://api.example.com', true), + domainParser('https://api.weather.com', true), + domainParser('https://data.github.com', true), + ]); + const unique = new Set(keys); + expect(unique.size).toBe(keys.length); + }); + + it('long hostname after stripping still uses base64 path', async () => { + const result = await domainParser('https://api.example.com', true); + expect(result).toHaveLength(MAX); + expect(result).not.toContain(SEP); + }); + + it('short hostname after stripping uses dot-replacement path', async () => { + const result = await domainParser('https://a.b.c', true); + expect(result).toBe(`a${SEP}b${SEP}c`); + }); + + it('strips path and query from full URL before encoding', async () => { + const result = await domainParser('https://api.example.com/v1/endpoint?foo=bar', true); + expect(result).toBe(await domainParser('api.example.com', true)); + }); + }); + + describe('unicode domains', () => { + it('encodes unicode hostname via base64 path', async () => { + const domain = 'täst.example.com'; + const result = await domainParser(domain, true); + expect(result).toHaveLength(MAX); + expect(result).toBe(Buffer.from(domain).toString('base64').substring(0, MAX)); + }); + + it('round-trips unicode hostname through encode then decode', async () => { + const domain = 'täst.example.com'; + const key = await domainParser(domain, true); + expect(await domainParser(key, false)).toBe(domain); + }); + + it('strips protocol before encoding unicode hostname', async () => { + const withProto = 'https://täst.example.com'; + const bare = 'täst.example.com'; + expect(await domainParser(withProto, true)).toBe(await domainParser(bare, true)); + }); + }); + + describe('decode path', () => { + it('short-path encoded domain decodes via separator replacement', async () => { + expect(await domainParser(`examp${SEP}com`, false)).toBe('examp.com'); + }); + + it('base64-path encoded domain decodes via cache lookup', async () => { + const hostname = 'api.example.com'; + const key = await domainParser(hostname, true); + expect(await domainParser(key, false)).toBe(hostname); + }); + + it('returns input unchanged for unknown non-separator strings', async () => { + expect(await domainParser('not_base64_encoded', false)).toBe('not_base64_encoded'); + }); + + it('returns a string without throwing for corrupt cache entries', async () => { + mockDomainCache['corrupt_key'] = '!!!'; + const result = await domainParser('corrupt_key', false); + expect(typeof result).toBe('string'); }); }); }); -describe('domainParser', () => { - const TLD = '.com'; - - // Non-azure request - it('does not return domain as is if not azure', async () => { - const domain = `example.com${actionDomainSeparator}test${actionDomainSeparator}`; - const result1 = await domainParser(domain, false); - const result2 = await domainParser(domain, true); - expect(result1).not.toEqual(domain); - expect(result2).not.toEqual(domain); +describe('legacyDomainEncode', () => { + it.each(['', null, undefined])('returns empty string for %j', (input) => { + expect(legacyDomainEncode(input)).toBe(''); }); - // Test for Empty or Null Inputs - it('returns undefined for null domain input', async () => { - const result = await domainParser(null, true); - expect(result).toBeUndefined(); + it('is synchronous (returns a string, not a Promise)', () => { + const result = legacyDomainEncode('examp.com'); + expect(result).toBe(`examp${SEP}com`); + expect(result).not.toBeInstanceOf(Promise); }); - it('returns undefined for empty domain input', async () => { - const result = await domainParser('', true); - expect(result).toBeUndefined(); + it('uses dot-replacement for short domains', () => { + expect(legacyDomainEncode('examp.com')).toBe(`examp${SEP}com`); }); - // Verify Correct Caching Behavior - it('caches encoded domain correctly', async () => { - const domain = 'longdomainname.com'; - const encodedDomain = Buffer.from(domain) - .toString('base64') - .substring(0, Constants.ENCODED_DOMAIN_LENGTH); - - await domainParser(domain, true); - - const cachedValue = await globalCache[encodedDomain]; - expect(cachedValue).toEqual(Buffer.from(domain).toString('base64')); + it('uses base64 prefix of full input for long domains', () => { + const domain = 'https://swapi.tech'; + const expected = Buffer.from(domain).toString('base64').substring(0, MAX); + expect(legacyDomainEncode(domain)).toBe(expected); }); - // Test for Edge Cases Around Length Threshold - it('encodes domain exactly at threshold without modification', async () => { - const domain = 'a'.repeat(Constants.ENCODED_DOMAIN_LENGTH - TLD.length) + TLD; - const expected = domain.replace(/\./g, actionDomainSeparator); - const result = await domainParser(domain, true); - expect(result).toEqual(expected); + it('all https:// URLs collide to the same key', () => { + const results = [ + legacyDomainEncode('https://api.example.com'), + legacyDomainEncode('https://api.weather.com'), + legacyDomainEncode('https://totally.different.host'), + ]; + expect(new Set(results).size).toBe(1); }); - it('encodes domain just below threshold without modification', async () => { - const domain = 'a'.repeat(Constants.ENCODED_DOMAIN_LENGTH - 1 - TLD.length) + TLD; - const expected = domain.replace(/\./g, actionDomainSeparator); - const result = await domainParser(domain, true); - expect(result).toEqual(expected); + it('matches what old domainParser would have produced', () => { + const domain = 'https://api.example.com'; + const legacy = legacyDomainEncode(domain); + expect(legacy).toBe(Buffer.from(domain).toString('base64').substring(0, MAX)); }); - // Test for Unicode Domain Names - it('handles unicode characters in domain names correctly when encoding', async () => { - const unicodeDomain = 'täst.example.com'; - const encodedDomain = Buffer.from(unicodeDomain) - .toString('base64') - .substring(0, Constants.ENCODED_DOMAIN_LENGTH); - const result = await domainParser(unicodeDomain, true); - expect(result).toEqual(encodedDomain); - }); - - it('decodes unicode domain names correctly', async () => { - const unicodeDomain = 'täst.example.com'; - const encodedDomain = Buffer.from(unicodeDomain).toString('base64'); - globalCache[encodedDomain.substring(0, Constants.ENCODED_DOMAIN_LENGTH)] = encodedDomain; // Simulate caching - - const result = await domainParser( - encodedDomain.substring(0, Constants.ENCODED_DOMAIN_LENGTH), - false, - ); - expect(result).toEqual(unicodeDomain); - }); - - // Core Functionality Tests - it('returns domain with replaced separators if no cached domain exists', async () => { - const domain = 'example.com'; - const withSeparator = domain.replace(/\./g, actionDomainSeparator); - const result = await domainParser(withSeparator, false); - expect(result).toEqual(domain); - }); - - it('returns domain with replaced separators when inverse is false and under encoding length', async () => { - const domain = 'examp.com'; - const withSeparator = domain.replace(/\./g, actionDomainSeparator); - const result = await domainParser(withSeparator, false); - expect(result).toEqual(domain); - }); - - it('replaces periods with actionDomainSeparator when inverse is true and under encoding length', async () => { - const domain = 'examp.com'; - const expected = domain.replace(/\./g, actionDomainSeparator); - const result = await domainParser(domain, true); - expect(result).toEqual(expected); - }); - - it('encodes domain when length is above threshold and inverse is true', async () => { - const domain = 'a'.repeat(Constants.ENCODED_DOMAIN_LENGTH + 1).concat('.com'); - const result = await domainParser(domain, true); - expect(result).not.toEqual(domain); - expect(result.length).toBeLessThanOrEqual(Constants.ENCODED_DOMAIN_LENGTH); - }); - - it('returns encoded value if no encoded value is cached, and inverse is false', async () => { - const originalDomain = 'example.com'; - const encodedDomain = Buffer.from( - originalDomain.replace(/\./g, actionDomainSeparator), - ).toString('base64'); - const result = await domainParser(encodedDomain, false); - expect(result).toEqual(encodedDomain); - }); - - it('decodes encoded value if cached and encoded value is provided, and inverse is false', async () => { - const originalDomain = 'example.com'; - const encodedDomain = await domainParser(originalDomain, true); - const result = await domainParser(encodedDomain, false); - expect(result).toEqual(originalDomain); - }); - - it('handles invalid base64 encoded values gracefully', async () => { - const invalidBase64Domain = 'not_base64_encoded'; - const result = await domainParser(invalidBase64Domain, false); - expect(result).toEqual(invalidBase64Domain); + it('produces same result as new domainParser for short bare hostnames', async () => { + const domain = 'swapi.tech'; + expect(legacyDomainEncode(domain)).toBe(await domainParser(domain, true)); + }); +}); + +describe('validateAndUpdateTool', () => { + const mockReq = { user: { id: 'user123' } }; + + it('returns tool unchanged when name passes tool-name regex', async () => { + const tool = { function: { name: 'getPeople_action_swapi---tech' } }; + const result = await validateAndUpdateTool({ + req: mockReq, + tool, + assistant_id: 'asst_1', + }); + expect(result).toEqual(tool); + expect(getActions).not.toHaveBeenCalled(); + }); + + it('matches action when metadata.domain has https:// prefix and tool domain is bare hostname', async () => { + getActions.mockResolvedValue([{ metadata: { domain: 'https://api.example.com' } }]); + + const tool = { function: { name: `getPeople${DELIM}api.example.com` } }; + const result = await validateAndUpdateTool({ + req: mockReq, + tool, + assistant_id: 'asst_1', + }); + + expect(result).not.toBeNull(); + expect(result.function.name).toMatch(/^getPeople_action_/); + expect(result.function.name).not.toContain('.'); + }); + + it('matches action when metadata.domain has no protocol', async () => { + getActions.mockResolvedValue([{ metadata: { domain: 'api.example.com' } }]); + + const tool = { function: { name: `getPeople${DELIM}api.example.com` } }; + const result = await validateAndUpdateTool({ + req: mockReq, + tool, + assistant_id: 'asst_1', + }); + + expect(result).not.toBeNull(); + expect(result.function.name).toMatch(/^getPeople_action_/); + }); + + it('returns null when no action matches the domain', async () => { + getActions.mockResolvedValue([{ metadata: { domain: 'https://other.domain.com' } }]); + + const tool = { function: { name: `getPeople${DELIM}api.example.com` } }; + const result = await validateAndUpdateTool({ + req: mockReq, + tool, + assistant_id: 'asst_1', + }); + + expect(result).toBeNull(); + }); + + it('returns null when action has no metadata', async () => { + getActions.mockResolvedValue([{ metadata: null }]); + + const tool = { function: { name: `getPeople${DELIM}api.example.com` } }; + const result = await validateAndUpdateTool({ + req: mockReq, + tool, + assistant_id: 'asst_1', + }); + + expect(result).toBeNull(); + }); +}); + +describe('backward-compatible tool name matching', () => { + function normalizeToolName(name) { + return name.replace(domainSepRegex, '_'); + } + + function buildToolName(functionName, encodedDomain) { + return `${functionName}${DELIM}${encodedDomain}`; + } + + describe('definition-phase matching', () => { + it('new encoding matches agent tools stored with new encoding', async () => { + const metadataDomain = 'https://swapi.tech'; + const encoded = await domainParser(metadataDomain, true); + const normalized = normalizeToolName(encoded); + + const storedTool = buildToolName('getPeople', encoded); + const defToolName = `getPeople${DELIM}${normalized}`; + + expect(normalizeToolName(storedTool)).toBe(defToolName); + }); + + it('legacy encoding matches agent tools stored with legacy encoding', async () => { + const metadataDomain = 'https://swapi.tech'; + const legacy = legacyDomainEncode(metadataDomain); + const legacyNormalized = normalizeToolName(legacy); + + const storedTool = buildToolName('getPeople', legacy); + const legacyDefName = `getPeople${DELIM}${legacyNormalized}`; + + expect(normalizeToolName(storedTool)).toBe(legacyDefName); + }); + + it('new definition matches old stored tools via legacy fallback', async () => { + const metadataDomain = 'https://swapi.tech'; + const newDomain = await domainParser(metadataDomain, true); + const legacyDomain = legacyDomainEncode(metadataDomain); + const newNorm = normalizeToolName(newDomain); + const legacyNorm = normalizeToolName(legacyDomain); + + const oldStoredTool = buildToolName('getPeople', legacyDomain); + const newToolName = `getPeople${DELIM}${newNorm}`; + const legacyToolName = `getPeople${DELIM}${legacyNorm}`; + + const storedNormalized = normalizeToolName(oldStoredTool); + const hasMatch = storedNormalized === newToolName || storedNormalized === legacyToolName; + expect(hasMatch).toBe(true); + }); + + it('pre-normalized Set eliminates per-tool normalization', async () => { + const metadataDomain = 'https://api.example.com'; + const domain = await domainParser(metadataDomain, true); + const legacyDomain = legacyDomainEncode(metadataDomain); + const normalizedDomain = normalizeToolName(domain); + const legacyNormalized = normalizeToolName(legacyDomain); + + const storedTools = [ + buildToolName('getWeather', legacyDomain), + buildToolName('getForecast', domain), + ]; + + const preNormalized = new Set(storedTools.map((t) => normalizeToolName(t))); + + const toolName = `getWeather${DELIM}${normalizedDomain}`; + const legacyToolName = `getWeather${DELIM}${legacyNormalized}`; + expect(preNormalized.has(toolName) || preNormalized.has(legacyToolName)).toBe(true); + }); + }); + + describe('execution-phase tool lookup', () => { + it('model-called tool name resolves via normalizedToDomain map (new encoding)', async () => { + const metadataDomain = 'https://api.example.com'; + const domain = await domainParser(metadataDomain, true); + const normalized = normalizeToolName(domain); + + const normalizedToDomain = new Map(); + normalizedToDomain.set(normalized, domain); + + const modelToolName = `getWeather${DELIM}${normalized}`; + + let matched = ''; + for (const [norm, canonical] of normalizedToDomain.entries()) { + if (modelToolName.includes(norm)) { + matched = canonical; + break; + } + } + + expect(matched).toBe(domain); + + const functionName = modelToolName.replace(`${DELIM}${normalizeToolName(matched)}`, ''); + expect(functionName).toBe('getWeather'); + }); + + it('model-called tool name resolves via legacy entry in normalizedToDomain map', async () => { + const metadataDomain = 'https://api.example.com'; + const domain = await domainParser(metadataDomain, true); + const legacyDomain = legacyDomainEncode(metadataDomain); + const legacyNorm = normalizeToolName(legacyDomain); + + const normalizedToDomain = new Map(); + normalizedToDomain.set(normalizeToolName(domain), domain); + normalizedToDomain.set(legacyNorm, domain); + + const legacyModelToolName = `getWeather${DELIM}${legacyNorm}`; + + let matched = ''; + for (const [norm, canonical] of normalizedToDomain.entries()) { + if (legacyModelToolName.includes(norm)) { + matched = canonical; + break; + } + } + + expect(matched).toBe(domain); + }); + + it('legacy guard skips duplicate map entry for short bare hostnames', async () => { + const domain = 'swapi.tech'; + const newEncoding = await domainParser(domain, true); + const legacyEncoding = legacyDomainEncode(domain); + + expect(newEncoding).toBe(legacyEncoding); + + const normalizedToDomain = new Map(); + normalizedToDomain.set(newEncoding, newEncoding); + if (legacyEncoding !== newEncoding) { + normalizedToDomain.set(legacyEncoding, newEncoding); + } + expect(normalizedToDomain.size).toBe(1); + }); + }); + + describe('processRequiredActions matching (assistants path)', () => { + it('legacy tool from OpenAI matches via normalizedToDomain with both encodings', async () => { + const metadataDomain = 'https://swapi.tech'; + const domain = await domainParser(metadataDomain, true); + const legacyDomain = legacyDomainEncode(metadataDomain); + + const normalizedToDomain = new Map(); + normalizedToDomain.set(domain, domain); + if (legacyDomain !== domain) { + normalizedToDomain.set(legacyDomain, domain); + } + + const legacyToolName = buildToolName('getPeople', legacyDomain); + + let currentDomain = ''; + let matchedKey = ''; + for (const [key, canonical] of normalizedToDomain.entries()) { + if (legacyToolName.includes(key)) { + currentDomain = canonical; + matchedKey = key; + break; + } + } + + expect(currentDomain).toBe(domain); + expect(matchedKey).toBe(legacyDomain); + + const functionName = legacyToolName.replace(`${DELIM}${matchedKey}`, ''); + expect(functionName).toBe('getPeople'); + }); + + it('new tool name matches via the canonical domain key', async () => { + const metadataDomain = 'https://swapi.tech'; + const domain = await domainParser(metadataDomain, true); + const legacyDomain = legacyDomainEncode(metadataDomain); + + const normalizedToDomain = new Map(); + normalizedToDomain.set(domain, domain); + if (legacyDomain !== domain) { + normalizedToDomain.set(legacyDomain, domain); + } + + const newToolName = buildToolName('getPeople', domain); + + let currentDomain = ''; + let matchedKey = ''; + for (const [key, canonical] of normalizedToDomain.entries()) { + if (newToolName.includes(key)) { + currentDomain = canonical; + matchedKey = key; + break; + } + } + + expect(currentDomain).toBe(domain); + expect(matchedKey).toBe(domain); + + const functionName = newToolName.replace(`${DELIM}${matchedKey}`, ''); + expect(functionName).toBe('getPeople'); + }); + }); + + describe('save-route cleanup', () => { + it('tool filter removes tools matching new encoding', async () => { + const metadataDomain = 'https://swapi.tech'; + const domain = await domainParser(metadataDomain, true); + const legacyDomain = legacyDomainEncode(metadataDomain); + + const tools = [ + buildToolName('getPeople', domain), + buildToolName('unrelated', 'other---domain'), + ]; + + const filtered = tools.filter((t) => !t.includes(domain) && !t.includes(legacyDomain)); + + expect(filtered).toEqual([buildToolName('unrelated', 'other---domain')]); + }); + + it('tool filter removes tools matching legacy encoding', async () => { + const metadataDomain = 'https://swapi.tech'; + const domain = await domainParser(metadataDomain, true); + const legacyDomain = legacyDomainEncode(metadataDomain); + + const tools = [ + buildToolName('getPeople', legacyDomain), + buildToolName('unrelated', 'other---domain'), + ]; + + const filtered = tools.filter((t) => !t.includes(domain) && !t.includes(legacyDomain)); + + expect(filtered).toEqual([buildToolName('unrelated', 'other---domain')]); + }); + }); + + describe('delete-route domain extraction', () => { + it('domain extracted from actions array is usable as-is for tool filtering', async () => { + const metadataDomain = 'https://api.example.com'; + const domain = await domainParser(metadataDomain, true); + const actionId = 'abc123'; + const actionEntry = `${domain}${DELIM}${actionId}`; + + const [storedDomain] = actionEntry.split(DELIM); + expect(storedDomain).toBe(domain); + + const tools = [buildToolName('getWeather', domain), buildToolName('getPeople', 'other')]; + + const filtered = tools.filter((t) => !t.includes(storedDomain)); + expect(filtered).toEqual([buildToolName('getPeople', 'other')]); + }); + }); + + describe('multi-action agents (collision scenario)', () => { + it('two https:// actions now produce distinct tool names', async () => { + const domain1 = await domainParser('https://api.weather.com', true); + const domain2 = await domainParser('https://api.spacex.com', true); + + const tool1 = buildToolName('getData', domain1); + const tool2 = buildToolName('getData', domain2); + + expect(tool1).not.toBe(tool2); + }); + + it('two https:// actions used to collide in legacy encoding', () => { + const legacy1 = legacyDomainEncode('https://api.weather.com'); + const legacy2 = legacyDomainEncode('https://api.spacex.com'); + + const tool1 = buildToolName('getData', legacy1); + const tool2 = buildToolName('getData', legacy2); + + expect(tool1).toBe(tool2); + }); }); }); diff --git a/api/server/services/Endpoints/agents/addedConvo.js b/api/server/services/Endpoints/agents/addedConvo.js index 25b1327991..7561053f8f 100644 --- a/api/server/services/Endpoints/agents/addedConvo.js +++ b/api/server/services/Endpoints/agents/addedConvo.js @@ -1,12 +1,16 @@ const { logger } = require('@librechat/data-schemas'); -const { initializeAgent, validateAgentModel } = require('@librechat/api'); -const { loadAddedAgent, setGetAgent, ADDED_AGENT_ID } = require('~/models/loadAddedAgent'); -const { getConvoFiles } = require('~/models/Conversation'); -const { getAgent } = require('~/models/Agent'); +const { + ADDED_AGENT_ID, + initializeAgent, + validateAgentModel, + loadAddedAgent: loadAddedAgentFn, +} = require('@librechat/api'); +const { filterFilesByAgentAccess } = require('~/server/services/Files/permissions'); +const { getMCPServerTools } = require('~/server/services/Config'); const db = require('~/models'); -// Initialize the getAgent dependency -setGetAgent(getAgent); +const loadAddedAgent = (params) => + loadAddedAgentFn(params, { getAgent: db.getAgent, getMCPServerTools }); /** * Process addedConvo for parallel agent execution. @@ -99,15 +103,16 @@ const processAddedConvo = async ({ allowedProviders, }, { - getConvoFiles, getFiles: db.getFiles, getUserKey: db.getUserKey, getMessages: db.getMessages, + getConvoFiles: db.getConvoFiles, updateFilesUsage: db.updateFilesUsage, getUserCodeFiles: db.getUserCodeFiles, getUserKeyValues: db.getUserKeyValues, getToolFilesByIds: db.getToolFilesByIds, getCodeGeneratedFiles: db.getCodeGeneratedFiles, + filterFilesByAgentAccess, }, ); diff --git a/api/server/services/Endpoints/agents/build.js b/api/server/services/Endpoints/agents/build.js index a95640e528..19ae3ab7e8 100644 --- a/api/server/services/Endpoints/agents/build.js +++ b/api/server/services/Endpoints/agents/build.js @@ -1,6 +1,10 @@ const { logger } = require('@librechat/data-schemas'); +const { loadAgent: loadAgentFn } = require('@librechat/api'); const { isAgentsEndpoint, removeNullishValues, Constants } = require('librechat-data-provider'); -const { loadAgent } = require('~/models/Agent'); +const { getMCPServerTools } = require('~/server/services/Config'); +const db = require('~/models'); + +const loadAgent = (params) => loadAgentFn(params, { getAgent: db.getAgent, getMCPServerTools }); const buildOptions = (req, endpoint, parsedBody, endpointType) => { const { spec, iconURL, agent_id, ...model_parameters } = parsedBody; diff --git a/api/server/services/Endpoints/agents/initialize.js b/api/server/services/Endpoints/agents/initialize.js index e71270ef85..69767e191c 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,11 +22,11 @@ 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'); -const { getAgent } = require('~/models/Agent'); const { logViolation } = require('~/cache'); const db = require('~/models'); @@ -80,6 +82,14 @@ function createToolLoader(signal, streamId = null, definitionsOnly = false) { }; } +/** + * Initializes the AgentClient for a given request/response cycle. + * @param {Object} params + * @param {Express.Request} params.req + * @param {Express.Response} params.res + * @param {AbortSignal} params.signal + * @param {Object} params.endpointOption + */ const initializeClient = async ({ req, res, signal, endpointOption }) => { if (!endpointOption) { throw new Error('Endpoint option not provided'); @@ -125,6 +135,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`); @@ -133,9 +144,13 @@ const initializeClient = async ({ req, res, signal, endpointOption }) => { toolEndCallback, }; + const summarizationOptions = + appConfig?.summarization?.enabled === false ? { enabled: false } : { enabled: true }; + const eventHandlers = getDefaultHandlers({ res, toolExecuteOptions, + summarizationOptions, aggregateContent, toolEndCallback, collectedUsage, @@ -191,15 +206,16 @@ const initializeClient = async ({ req, res, signal, endpointOption }) => { isInitialAgent: true, }, { - getConvoFiles, getFiles: db.getFiles, getUserKey: db.getUserKey, getMessages: db.getMessages, + getConvoFiles: db.getConvoFiles, updateFilesUsage: db.updateFilesUsage, getUserKeyValues: db.getUserKeyValues, getUserCodeFiles: db.getUserCodeFiles, getToolFilesByIds: db.getToolFilesByIds, getCodeGeneratedFiles: db.getCodeGeneratedFiles, + filterFilesByAgentAccess, }, ); @@ -211,6 +227,7 @@ const initializeClient = async ({ req, res, signal, endpointOption }) => { toolRegistry: primaryConfig.toolRegistry, userMCPAuthMap: primaryConfig.userMCPAuthMap, tool_resources: primaryConfig.tool_resources, + actionsEnabled: primaryConfig.actionsEnabled, }); const agent_ids = primaryConfig.agent_ids; @@ -220,7 +237,7 @@ const initializeClient = async ({ req, res, signal, endpointOption }) => { const skippedAgentIds = new Set(); async function processAgent(agentId) { - const agent = await getAgent({ id: agentId }); + const agent = await db.getAgent({ id: agentId }); if (!agent) { logger.warn( `[processAgent] Handoff agent ${agentId} not found, skipping (orphaned reference)`, @@ -229,6 +246,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, @@ -254,15 +287,16 @@ const initializeClient = async ({ req, res, signal, endpointOption }) => { allowedProviders, }, { - getConvoFiles, getFiles: db.getFiles, getUserKey: db.getUserKey, getMessages: db.getMessages, + getConvoFiles: db.getConvoFiles, updateFilesUsage: db.updateFilesUsage, getUserKeyValues: db.getUserKeyValues, getUserCodeFiles: db.getUserCodeFiles, getToolFilesByIds: db.getToolFilesByIds, getCodeGeneratedFiles: db.getCodeGeneratedFiles, + filterFilesByAgentAccess, }, ); @@ -278,6 +312,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); @@ -351,6 +386,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..8027744965 --- /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 { User, AclEntry } = require('~/db/models'); +const { createAgent } = require('~/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/Endpoints/agents/title.js b/api/server/services/Endpoints/agents/title.js index e31cdeea11..b7e1a54e06 100644 --- a/api/server/services/Endpoints/agents/title.js +++ b/api/server/services/Endpoints/agents/title.js @@ -66,7 +66,11 @@ const addTitle = async (req, { text, response, client }) => { await titleCache.set(key, title, 120000); await saveConvo( - req, + { + userId: req?.user?.id, + isTemporary: req?.body?.isTemporary, + interfaceConfig: req?.config?.interfaceConfig, + }, { conversationId: response.conversationId, title, diff --git a/api/server/services/Endpoints/assistants/build.js b/api/server/services/Endpoints/assistants/build.js index 00a2abf606..85f7090211 100644 --- a/api/server/services/Endpoints/assistants/build.js +++ b/api/server/services/Endpoints/assistants/build.js @@ -1,6 +1,6 @@ const { removeNullishValues } = require('librechat-data-provider'); const generateArtifactsPrompt = require('~/app/clients/prompts/artifacts'); -const { getAssistant } = require('~/models/Assistant'); +const { getAssistant } = require('~/models'); const buildOptions = async (endpoint, parsedBody) => { const { promptPrefix, assistant_id, iconURL, greeting, spec, artifacts, ...modelOptions } = diff --git a/api/server/services/Endpoints/assistants/title.js b/api/server/services/Endpoints/assistants/title.js index 1fae68cf54..b31289eb60 100644 --- a/api/server/services/Endpoints/assistants/title.js +++ b/api/server/services/Endpoints/assistants/title.js @@ -1,9 +1,9 @@ const { isEnabled, sanitizeTitle } = require('@librechat/api'); const { logger } = require('@librechat/data-schemas'); const { CacheKeys } = require('librechat-data-provider'); -const { saveConvo } = require('~/models/Conversation'); const getLogStores = require('~/cache/getLogStores'); const initializeClient = require('./initalize'); +const { saveConvo } = require('~/models'); /** * Generates a conversation title using OpenAI SDK @@ -63,8 +63,13 @@ const addTitle = async (req, { text, responseText, conversationId }) => { const title = await generateTitle({ openai, text, responseText }); await titleCache.set(key, title, 120000); + const reqCtx = { + userId: req?.user?.id, + isTemporary: req?.body?.isTemporary, + interfaceConfig: req?.config?.interfaceConfig, + }; await saveConvo( - req, + reqCtx, { conversationId, title, @@ -76,7 +81,11 @@ const addTitle = async (req, { text, responseText, conversationId }) => { const fallbackTitle = text.length > 40 ? text.substring(0, 37) + '...' : text; await titleCache.set(key, fallbackTitle, 120000); await saveConvo( - req, + { + userId: req?.user?.id, + isTemporary: req?.body?.isTemporary, + interfaceConfig: req?.config?.interfaceConfig, + }, { conversationId, title: fallbackTitle, diff --git a/api/server/services/Endpoints/azureAssistants/build.js b/api/server/services/Endpoints/azureAssistants/build.js index 53b1dbeb68..315447ed7f 100644 --- a/api/server/services/Endpoints/azureAssistants/build.js +++ b/api/server/services/Endpoints/azureAssistants/build.js @@ -1,6 +1,6 @@ const { removeNullishValues } = require('librechat-data-provider'); const generateArtifactsPrompt = require('~/app/clients/prompts/artifacts'); -const { getAssistant } = require('~/models/Assistant'); +const { getAssistant } = require('~/models'); const buildOptions = async (endpoint, parsedBody) => { const { promptPrefix, assistant_id, iconURL, greeting, spec, artifacts, ...modelOptions } = diff --git a/api/server/services/Endpoints/index.js b/api/server/services/Endpoints/index.js deleted file mode 100644 index 3cabfe1c58..0000000000 --- a/api/server/services/Endpoints/index.js +++ /dev/null @@ -1,77 +0,0 @@ -const { Providers } = require('@librechat/agents'); -const { EModelEndpoint } = require('librechat-data-provider'); -const { getCustomEndpointConfig } = require('@librechat/api'); -const initAnthropic = require('~/server/services/Endpoints/anthropic/initialize'); -const getBedrockOptions = require('~/server/services/Endpoints/bedrock/options'); -const initOpenAI = require('~/server/services/Endpoints/openAI/initialize'); -const initCustom = require('~/server/services/Endpoints/custom/initialize'); -const initGoogle = require('~/server/services/Endpoints/google/initialize'); - -/** Check if the provider is a known custom provider - * @param {string | undefined} [provider] - The provider string - * @returns {boolean} - True if the provider is a known custom provider, false otherwise - */ -function isKnownCustomProvider(provider) { - return [Providers.XAI, Providers.DEEPSEEK, Providers.OPENROUTER, Providers.MOONSHOT].includes( - provider?.toLowerCase() || '', - ); -} - -const providerConfigMap = { - [Providers.XAI]: initCustom, - [Providers.DEEPSEEK]: initCustom, - [Providers.MOONSHOT]: initCustom, - [Providers.OPENROUTER]: initCustom, - [EModelEndpoint.openAI]: initOpenAI, - [EModelEndpoint.google]: initGoogle, - [EModelEndpoint.azureOpenAI]: initOpenAI, - [EModelEndpoint.anthropic]: initAnthropic, - [EModelEndpoint.bedrock]: getBedrockOptions, -}; - -/** - * Get the provider configuration and override endpoint based on the provider string - * @param {Object} params - * @param {string} params.provider - The provider string - * @param {AppConfig} params.appConfig - The application configuration - * @returns {{ - * getOptions: (typeof providerConfigMap)[keyof typeof providerConfigMap], - * overrideProvider: string, - * customEndpointConfig?: TEndpoint - * }} - */ -function getProviderConfig({ provider, appConfig }) { - let getOptions = providerConfigMap[provider]; - let overrideProvider = provider; - /** @type {TEndpoint | undefined} */ - let customEndpointConfig; - - if (!getOptions && providerConfigMap[provider.toLowerCase()] != null) { - overrideProvider = provider.toLowerCase(); - getOptions = providerConfigMap[overrideProvider]; - } else if (!getOptions) { - customEndpointConfig = getCustomEndpointConfig({ endpoint: provider, appConfig }); - if (!customEndpointConfig) { - throw new Error(`Provider ${provider} not supported`); - } - getOptions = initCustom; - overrideProvider = Providers.OPENAI; - } - - if (isKnownCustomProvider(overrideProvider) && !customEndpointConfig) { - customEndpointConfig = getCustomEndpointConfig({ endpoint: provider, appConfig }); - if (!customEndpointConfig) { - throw new Error(`Provider ${provider} not supported`); - } - } - - return { - getOptions, - overrideProvider, - customEndpointConfig, - }; -} - -module.exports = { - getProviderConfig, -}; diff --git a/api/server/services/Files/Audio/streamAudio.js b/api/server/services/Files/Audio/streamAudio.js index a1d7c7a649..c28a96edff 100644 --- a/api/server/services/Files/Audio/streamAudio.js +++ b/api/server/services/Files/Audio/streamAudio.js @@ -5,8 +5,8 @@ const { parseTextParts, findLastSeparatorIndex, } = require('librechat-data-provider'); -const { getMessage } = require('~/models/Message'); const { getLogStores } = require('~/cache'); +const { getMessage } = require('~/models'); /** * @param {string[]} voiceIds - Array of voice IDs diff --git a/api/server/services/Files/Audio/streamAudio.spec.js b/api/server/services/Files/Audio/streamAudio.spec.js index e76c0849c7..977d8730aa 100644 --- a/api/server/services/Files/Audio/streamAudio.spec.js +++ b/api/server/services/Files/Audio/streamAudio.spec.js @@ -3,7 +3,7 @@ const { createChunkProcessor, splitTextIntoChunks } = require('./streamAudio'); jest.mock('keyv'); const globalCache = {}; -jest.mock('~/models/Message', () => { +jest.mock('~/models', () => { return { getMessage: jest.fn().mockImplementation((messageId) => { return globalCache[messageId] || null; diff --git a/api/server/services/Files/Citations/index.js b/api/server/services/Files/Citations/index.js index 7cb2ee6de0..008e21d7c4 100644 --- a/api/server/services/Files/Citations/index.js +++ b/api/server/services/Files/Citations/index.js @@ -8,8 +8,7 @@ const { EModelEndpoint, PermissionTypes, } = require('librechat-data-provider'); -const { getRoleByName } = require('~/models/Role'); -const { Files } = require('~/models'); +const { getRoleByName, getFiles } = require('~/models'); /** * Process file search results from tool calls @@ -127,7 +126,7 @@ async function enhanceSourcesWithMetadata(sources, appConfig) { let fileMetadataMap = {}; try { - const files = await Files.find({ file_id: { $in: fileIds } }); + const files = await getFiles({ file_id: { $in: fileIds } }); fileMetadataMap = files.reduce((map, file) => { map[file.file_id] = file; return map; 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..0b8548445d --- /dev/null +++ b/api/server/services/Files/Code/__tests__/process-traversal.spec.js @@ -0,0 +1,130 @@ +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(); + +const mockAxios = jest.fn().mockResolvedValue({ + data: Buffer.from('file-content'), +}); +mockAxios.post = jest.fn(); + +jest.mock('@librechat/api', () => { + const http = require('http'); + const https = require('https'); + return { + logAxiosError: jest.fn(), + getBasePath: jest.fn(() => ''), + sanitizeFilename: mockSanitizeFilename, + createAxiosInstance: jest.fn(() => mockAxios), + codeServerHttpAgent: new http.Agent({ keepAlive: false }), + codeServerHttpsAgent: new https.Agent({ keepAlive: false }), + }; +}); + +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' }), +})); + +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/crud.js b/api/server/services/Files/Code/crud.js index 4781219fcf..945aec787b 100644 --- a/api/server/services/Files/Code/crud.js +++ b/api/server/services/Files/Code/crud.js @@ -1,6 +1,11 @@ const FormData = require('form-data'); const { getCodeBaseURL } = require('@librechat/agents'); -const { createAxiosInstance, logAxiosError } = require('@librechat/api'); +const { + logAxiosError, + createAxiosInstance, + codeServerHttpAgent, + codeServerHttpsAgent, +} = require('@librechat/api'); const axios = createAxiosInstance(); @@ -25,6 +30,8 @@ async function getCodeOutputDownloadStream(fileIdentifier, apiKey) { 'User-Agent': 'LibreChat/1.0', 'X-API-Key': apiKey, }, + httpAgent: codeServerHttpAgent, + httpsAgent: codeServerHttpsAgent, timeout: 15000, }; @@ -69,6 +76,9 @@ async function uploadCodeEnvFile({ req, stream, filename, apiKey, entity_id = '' 'User-Id': req.user.id, 'X-API-Key': apiKey, }, + httpAgent: codeServerHttpAgent, + httpsAgent: codeServerHttpsAgent, + timeout: 120000, maxContentLength: MAX_FILE_SIZE, maxBodyLength: MAX_FILE_SIZE, }; diff --git a/api/server/services/Files/Code/crud.spec.js b/api/server/services/Files/Code/crud.spec.js new file mode 100644 index 0000000000..261f0f052b --- /dev/null +++ b/api/server/services/Files/Code/crud.spec.js @@ -0,0 +1,149 @@ +const http = require('http'); +const https = require('https'); +const { Readable } = require('stream'); + +const mockAxios = jest.fn(); +mockAxios.post = jest.fn(); + +jest.mock('@librechat/agents', () => ({ + getCodeBaseURL: jest.fn(() => 'https://code-api.example.com'), +})); + +jest.mock('@librechat/api', () => { + const http = require('http'); + const https = require('https'); + return { + logAxiosError: jest.fn(({ message }) => message), + createAxiosInstance: jest.fn(() => mockAxios), + codeServerHttpAgent: new http.Agent({ keepAlive: false }), + codeServerHttpsAgent: new https.Agent({ keepAlive: false }), + }; +}); + +const { codeServerHttpAgent, codeServerHttpsAgent } = require('@librechat/api'); +const { getCodeOutputDownloadStream, uploadCodeEnvFile } = require('./crud'); + +describe('Code CRUD', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('getCodeOutputDownloadStream', () => { + it('should pass dedicated keepAlive:false agents to axios', async () => { + const mockResponse = { data: Readable.from(['chunk']) }; + mockAxios.mockResolvedValue(mockResponse); + + await getCodeOutputDownloadStream('session-1/file-1', 'test-key'); + + const callConfig = mockAxios.mock.calls[0][0]; + expect(callConfig.httpAgent).toBe(codeServerHttpAgent); + expect(callConfig.httpsAgent).toBe(codeServerHttpsAgent); + expect(callConfig.httpAgent).toBeInstanceOf(http.Agent); + expect(callConfig.httpsAgent).toBeInstanceOf(https.Agent); + expect(callConfig.httpAgent.keepAlive).toBe(false); + expect(callConfig.httpsAgent.keepAlive).toBe(false); + }); + + it('should request stream response from the correct URL', async () => { + mockAxios.mockResolvedValue({ data: Readable.from(['chunk']) }); + + await getCodeOutputDownloadStream('session-1/file-1', 'test-key'); + + const callConfig = mockAxios.mock.calls[0][0]; + expect(callConfig.url).toBe('https://code-api.example.com/download/session-1/file-1'); + expect(callConfig.responseType).toBe('stream'); + expect(callConfig.timeout).toBe(15000); + expect(callConfig.headers['X-API-Key']).toBe('test-key'); + }); + + it('should throw on network error', async () => { + mockAxios.mockRejectedValue(new Error('ECONNREFUSED')); + + await expect(getCodeOutputDownloadStream('s/f', 'key')).rejects.toThrow(); + }); + }); + + describe('uploadCodeEnvFile', () => { + const baseUploadParams = { + req: { user: { id: 'user-123' } }, + stream: Readable.from(['file-content']), + filename: 'data.csv', + apiKey: 'test-key', + }; + + it('should pass dedicated keepAlive:false agents to axios', async () => { + mockAxios.post.mockResolvedValue({ + data: { + message: 'success', + session_id: 'sess-1', + files: [{ fileId: 'fid-1', filename: 'data.csv' }], + }, + }); + + await uploadCodeEnvFile(baseUploadParams); + + const callConfig = mockAxios.post.mock.calls[0][2]; + expect(callConfig.httpAgent).toBe(codeServerHttpAgent); + expect(callConfig.httpsAgent).toBe(codeServerHttpsAgent); + expect(callConfig.httpAgent).toBeInstanceOf(http.Agent); + expect(callConfig.httpsAgent).toBeInstanceOf(https.Agent); + expect(callConfig.httpAgent.keepAlive).toBe(false); + expect(callConfig.httpsAgent.keepAlive).toBe(false); + }); + + it('should set a timeout on upload requests', async () => { + mockAxios.post.mockResolvedValue({ + data: { + message: 'success', + session_id: 'sess-1', + files: [{ fileId: 'fid-1', filename: 'data.csv' }], + }, + }); + + await uploadCodeEnvFile(baseUploadParams); + + const callConfig = mockAxios.post.mock.calls[0][2]; + expect(callConfig.timeout).toBe(120000); + }); + + it('should return fileIdentifier on success', async () => { + mockAxios.post.mockResolvedValue({ + data: { + message: 'success', + session_id: 'sess-1', + files: [{ fileId: 'fid-1', filename: 'data.csv' }], + }, + }); + + const result = await uploadCodeEnvFile(baseUploadParams); + expect(result).toBe('sess-1/fid-1'); + }); + + it('should append entity_id query param when provided', async () => { + mockAxios.post.mockResolvedValue({ + data: { + message: 'success', + session_id: 'sess-1', + files: [{ fileId: 'fid-1', filename: 'data.csv' }], + }, + }); + + const result = await uploadCodeEnvFile({ ...baseUploadParams, entity_id: 'agent-42' }); + expect(result).toBe('sess-1/fid-1?entity_id=agent-42'); + }); + + it('should throw when server returns non-success message', async () => { + mockAxios.post.mockResolvedValue({ + data: { message: 'quota_exceeded', session_id: 's', files: [] }, + }); + + await expect(uploadCodeEnvFile(baseUploadParams)).rejects.toThrow('quota_exceeded'); + }); + + it('should throw on network error', async () => { + mockAxios.post.mockRejectedValue(new Error('ECONNREFUSED')); + + await expect(uploadCodeEnvFile(baseUploadParams)).rejects.toThrow(); + }); + }); +}); diff --git a/api/server/services/Files/Code/process.js b/api/server/services/Files/Code/process.js index 3f0bfcfc87..7cdebeb202 100644 --- a/api/server/services/Files/Code/process.js +++ b/api/server/services/Files/Code/process.js @@ -1,9 +1,15 @@ const path = require('path'); 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 { + getBasePath, + logAxiosError, + sanitizeFilename, + createAxiosInstance, + codeServerHttpAgent, + codeServerHttpsAgent, +} = require('@librechat/api'); const { Tools, megabyte, @@ -23,6 +29,8 @@ const { getStrategyFunctions } = require('~/server/services/Files/strategies'); const { convertImage } = require('~/server/services/Files/images/convert'); const { determineFileType } = require('~/server/utils'); +const axios = createAxiosInstance(); + /** * Creates a fallback download URL response when file cannot be processed locally. * Used when: file exceeds size limit, storage strategy unavailable, or download error occurs. @@ -102,6 +110,8 @@ const processCodeOutput = async ({ 'User-Agent': 'LibreChat/1.0', 'X-API-Key': apiKey, }, + httpAgent: codeServerHttpAgent, + httpsAgent: codeServerHttpsAgent, timeout: 15000, }); @@ -146,6 +156,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 +173,7 @@ const processCodeOutput = async ({ file_id, messageId, usage, - filename: name, + filename: safeName, conversationId, user: req.user.id, type: `image/${appConfig.imageOutputType}`, @@ -200,7 +217,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 +230,7 @@ const processCodeOutput = async ({ filepath, messageId, object: 'file', - filename: name, + filename: safeName, type: mimeType, conversationId, user: req.user.id, @@ -229,6 +246,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, @@ -288,6 +310,8 @@ async function getSessionInfo(fileIdentifier, apiKey) { 'User-Agent': 'LibreChat/1.0', 'X-API-Key': apiKey, }, + httpAgent: codeServerHttpAgent, + httpsAgent: codeServerHttpsAgent, timeout: 5000, }); @@ -436,5 +460,6 @@ const primeFiles = async (options, apiKey) => { module.exports = { primeFiles, + getSessionInfo, processCodeOutput, }; diff --git a/api/server/services/Files/Code/process.spec.js b/api/server/services/Files/Code/process.spec.js index f01a623f90..a805ee2bcc 100644 --- a/api/server/services/Files/Code/process.spec.js +++ b/api/server/services/Files/Code/process.spec.js @@ -36,11 +36,24 @@ jest.mock('uuid', () => ({ v4: jest.fn(() => 'mock-uuid-1234'), })); -// Mock axios -jest.mock('axios'); -const axios = require('axios'); +// Mock axios — process.js now uses createAxiosInstance() from @librechat/api +const mockAxios = jest.fn(); +mockAxios.post = jest.fn(); +mockAxios.isAxiosError = jest.fn(() => false); + +jest.mock('@librechat/api', () => { + const http = require('http'); + const https = require('https'); + return { + logAxiosError: jest.fn(), + getBasePath: jest.fn(() => ''), + sanitizeFilename: jest.fn((name) => name), + createAxiosInstance: jest.fn(() => mockAxios), + codeServerHttpAgent: new http.Agent({ keepAlive: false }), + codeServerHttpsAgent: new https.Agent({ keepAlive: false }), + }; +}); -// Mock logger jest.mock('@librechat/data-schemas', () => ({ logger: { warn: jest.fn(), @@ -49,17 +62,10 @@ jest.mock('@librechat/data-schemas', () => ({ }, })); -// Mock getCodeBaseURL jest.mock('@librechat/agents', () => ({ getCodeBaseURL: jest.fn(() => 'https://code-api.example.com'), })); -// Mock logAxiosError and getBasePath -jest.mock('@librechat/api', () => ({ - logAxiosError: jest.fn(), - getBasePath: jest.fn(() => ''), -})); - // Mock models const mockClaimCodeFile = jest.fn(); jest.mock('~/models', () => ({ @@ -89,14 +95,16 @@ jest.mock('~/server/utils', () => ({ determineFileType: jest.fn(), })); +const http = require('http'); +const https = require('https'); const { createFile, getFiles } = require('~/models'); const { getStrategyFunctions } = require('~/server/services/Files/strategies'); const { convertImage } = require('~/server/services/Files/images/convert'); const { determineFileType } = require('~/server/utils'); const { logger } = require('@librechat/data-schemas'); +const { codeServerHttpAgent, codeServerHttpsAgent } = require('@librechat/api'); -// Import after mocks -const { processCodeOutput } = require('./process'); +const { processCodeOutput, getSessionInfo } = require('./process'); describe('Code Process', () => { const mockReq = { @@ -144,7 +152,7 @@ describe('Code Process', () => { }); const smallBuffer = Buffer.alloc(100); - axios.mockResolvedValue({ data: smallBuffer }); + mockAxios.mockResolvedValue({ data: smallBuffer }); const result = await processCodeOutput(baseParams); @@ -167,7 +175,7 @@ describe('Code Process', () => { }); const smallBuffer = Buffer.alloc(100); - axios.mockResolvedValue({ data: smallBuffer }); + mockAxios.mockResolvedValue({ data: smallBuffer }); const result = await processCodeOutput(baseParams); @@ -181,7 +189,7 @@ describe('Code Process', () => { it('should process image files using convertImage', async () => { const imageParams = { ...baseParams, name: 'chart.png' }; const imageBuffer = Buffer.alloc(500); - axios.mockResolvedValue({ data: imageBuffer }); + mockAxios.mockResolvedValue({ data: imageBuffer }); const convertedFile = { filepath: '/uploads/converted-image.webp', @@ -211,7 +219,7 @@ describe('Code Process', () => { }); const imageBuffer = Buffer.alloc(500); - axios.mockResolvedValue({ data: imageBuffer }); + mockAxios.mockResolvedValue({ data: imageBuffer }); convertImage.mockResolvedValue({ filepath: '/images/user-123/existing-img-id.webp' }); const result = await processCodeOutput(imageParams); @@ -234,7 +242,7 @@ describe('Code Process', () => { describe('non-image file processing', () => { it('should process non-image files using saveBuffer', async () => { const smallBuffer = Buffer.alloc(100); - axios.mockResolvedValue({ data: smallBuffer }); + mockAxios.mockResolvedValue({ data: smallBuffer }); const mockSaveBuffer = jest.fn().mockResolvedValue('/uploads/saved-file.txt'); getStrategyFunctions.mockReturnValue({ saveBuffer: mockSaveBuffer }); @@ -255,7 +263,7 @@ describe('Code Process', () => { it('should detect MIME type from buffer', async () => { const smallBuffer = Buffer.alloc(100); - axios.mockResolvedValue({ data: smallBuffer }); + mockAxios.mockResolvedValue({ data: smallBuffer }); determineFileType.mockResolvedValue({ mime: 'application/pdf' }); const result = await processCodeOutput({ ...baseParams, name: 'document.pdf' }); @@ -266,7 +274,7 @@ describe('Code Process', () => { it('should fallback to application/octet-stream for unknown types', async () => { const smallBuffer = Buffer.alloc(100); - axios.mockResolvedValue({ data: smallBuffer }); + mockAxios.mockResolvedValue({ data: smallBuffer }); determineFileType.mockResolvedValue(null); const result = await processCodeOutput({ ...baseParams, name: 'unknown.xyz' }); @@ -281,7 +289,7 @@ describe('Code Process', () => { fileSizeLimitConfig.value = 1000; // 1KB limit const largeBuffer = Buffer.alloc(5000); // 5KB - exceeds 1KB limit - axios.mockResolvedValue({ data: largeBuffer }); + mockAxios.mockResolvedValue({ data: largeBuffer }); const result = await processCodeOutput(baseParams); @@ -299,7 +307,7 @@ describe('Code Process', () => { describe('fallback behavior', () => { it('should fallback to download URL when saveBuffer is not available', async () => { const smallBuffer = Buffer.alloc(100); - axios.mockResolvedValue({ data: smallBuffer }); + mockAxios.mockResolvedValue({ data: smallBuffer }); getStrategyFunctions.mockReturnValue({ saveBuffer: null }); const result = await processCodeOutput(baseParams); @@ -312,7 +320,7 @@ describe('Code Process', () => { }); it('should fallback to download URL on axios error', async () => { - axios.mockRejectedValue(new Error('Network error')); + mockAxios.mockRejectedValue(new Error('Network error')); const result = await processCodeOutput(baseParams); @@ -326,7 +334,7 @@ describe('Code Process', () => { describe('usage counter increment', () => { it('should set usage to 1 for new files', async () => { const smallBuffer = Buffer.alloc(100); - axios.mockResolvedValue({ data: smallBuffer }); + mockAxios.mockResolvedValue({ data: smallBuffer }); const result = await processCodeOutput(baseParams); @@ -340,7 +348,7 @@ describe('Code Process', () => { createdAt: '2024-01-01', }); const smallBuffer = Buffer.alloc(100); - axios.mockResolvedValue({ data: smallBuffer }); + mockAxios.mockResolvedValue({ data: smallBuffer }); const result = await processCodeOutput(baseParams); @@ -353,7 +361,7 @@ describe('Code Process', () => { createdAt: '2024-01-01', }); const smallBuffer = Buffer.alloc(100); - axios.mockResolvedValue({ data: smallBuffer }); + mockAxios.mockResolvedValue({ data: smallBuffer }); const result = await processCodeOutput(baseParams); @@ -364,7 +372,7 @@ describe('Code Process', () => { describe('metadata and file properties', () => { it('should include fileIdentifier in metadata', async () => { const smallBuffer = Buffer.alloc(100); - axios.mockResolvedValue({ data: smallBuffer }); + mockAxios.mockResolvedValue({ data: smallBuffer }); const result = await processCodeOutput(baseParams); @@ -375,7 +383,7 @@ describe('Code Process', () => { it('should set correct context for code-generated files', async () => { const smallBuffer = Buffer.alloc(100); - axios.mockResolvedValue({ data: smallBuffer }); + mockAxios.mockResolvedValue({ data: smallBuffer }); const result = await processCodeOutput(baseParams); @@ -384,7 +392,7 @@ describe('Code Process', () => { it('should include toolCallId and messageId in result', async () => { const smallBuffer = Buffer.alloc(100); - axios.mockResolvedValue({ data: smallBuffer }); + mockAxios.mockResolvedValue({ data: smallBuffer }); const result = await processCodeOutput(baseParams); @@ -394,7 +402,7 @@ describe('Code Process', () => { it('should call createFile with upsert enabled', async () => { const smallBuffer = Buffer.alloc(100); - axios.mockResolvedValue({ data: smallBuffer }); + mockAxios.mockResolvedValue({ data: smallBuffer }); await processCodeOutput(baseParams); @@ -407,5 +415,36 @@ describe('Code Process', () => { ); }); }); + + describe('socket pool isolation', () => { + it('should pass dedicated keepAlive:false agents to axios for processCodeOutput', async () => { + const smallBuffer = Buffer.alloc(100); + mockAxios.mockResolvedValue({ data: smallBuffer }); + + await processCodeOutput(baseParams); + + const callConfig = mockAxios.mock.calls[0][0]; + expect(callConfig.httpAgent).toBe(codeServerHttpAgent); + expect(callConfig.httpsAgent).toBe(codeServerHttpsAgent); + expect(callConfig.httpAgent).toBeInstanceOf(http.Agent); + expect(callConfig.httpsAgent).toBeInstanceOf(https.Agent); + expect(callConfig.httpAgent.keepAlive).toBe(false); + expect(callConfig.httpsAgent.keepAlive).toBe(false); + }); + + it('should pass dedicated keepAlive:false agents to axios for getSessionInfo', async () => { + mockAxios.mockResolvedValue({ + data: [{ name: 'sess/fid', lastModified: new Date().toISOString() }], + }); + + await getSessionInfo('sess/fid', 'api-key'); + + const callConfig = mockAxios.mock.calls[0][0]; + expect(callConfig.httpAgent).toBe(codeServerHttpAgent); + expect(callConfig.httpsAgent).toBe(codeServerHttpsAgent); + expect(callConfig.httpAgent.keepAlive).toBe(false); + expect(callConfig.httpsAgent.keepAlive).toBe(false); + }); + }); }); }); 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 deleted file mode 100644 index c821c0696c..0000000000 --- a/api/server/services/Files/S3/crud.js +++ /dev/null @@ -1,556 +0,0 @@ -const fs = require('fs'); -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, isEnabled } = require('@librechat/api'); -const { - PutObjectCommand, - GetObjectCommand, - HeadObjectCommand, - DeleteObjectCommand, -} = require('@aws-sdk/client-s3'); - -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; - -if (process.env.S3_URL_EXPIRY_SECONDS !== undefined) { - const parsed = parseInt(process.env.S3_URL_EXPIRY_SECONDS, 10); - - if (!isNaN(parsed) && parsed > 0) { - s3UrlExpirySeconds = Math.min(parsed, 7 * 24 * 60 * 60); - } else { - logger.warn( - `[S3] Invalid S3_URL_EXPIRY_SECONDS value: "${process.env.S3_URL_EXPIRY_SECONDS}". Using 2-minute expiry.`, - ); - } -} - -if (process.env.S3_REFRESH_EXPIRY_MS !== null && process.env.S3_REFRESH_EXPIRY_MS) { - const parsed = parseInt(process.env.S3_REFRESH_EXPIRY_MS, 10); - - if (!isNaN(parsed) && parsed > 0) { - s3RefreshExpiryMs = parsed; - logger.info(`[S3] Using custom refresh expiry time: ${s3RefreshExpiryMs}ms`); - } else { - logger.warn( - `[S3] Invalid S3_REFRESH_EXPIRY_MS value: "${process.env.S3_REFRESH_EXPIRY_MS}". Using default refresh logic.`, - ); - } -} - -/** - * Constructs the S3 key based on the base path, user ID, and file name. - */ -const getS3Key = (basePath, userId, fileName) => `${basePath}/${userId}/${fileName}`; - -/** - * Uploads a buffer to S3 and returns a signed URL. - * - * @param {Object} params - * @param {string} params.userId - The user's unique identifier. - * @param {Buffer} params.buffer - The buffer containing file data. - * @param {string} params.fileName - The file name to use in S3. - * @param {string} [params.basePath='images'] - The base path in the bucket. - * @returns {Promise} Signed URL of the uploaded file. - */ -async function saveBufferToS3({ userId, buffer, fileName, basePath = defaultBasePath }) { - const key = getS3Key(basePath, userId, fileName); - const params = { Bucket: bucketName, Key: key, Body: buffer }; - - try { - const s3 = initializeS3(); - await s3.send(new PutObjectCommand(params)); - return await getS3URL({ userId, fileName, basePath }); - } catch (error) { - logger.error('[saveBufferToS3] Error uploading buffer to S3:', error.message); - throw error; - } -} - -/** - * Retrieves a URL for a file stored in S3. - * Returns a signed URL with expiration time or a proxy URL based on config - * - * @param {Object} params - * @param {string} params.userId - The user's unique identifier. - * @param {string} params.fileName - The file name in S3. - * @param {string} [params.basePath='images'] - The base path in the bucket. - * @param {string} [params.customFilename] - Custom filename for Content-Disposition header (overrides extracted filename). - * @param {string} [params.contentType] - Custom content type for the response. - * @returns {Promise} A URL to access the S3 object - */ -async function getS3URL({ - userId, - fileName, - basePath = defaultBasePath, - customFilename = null, - contentType = null, -}) { - const key = getS3Key(basePath, userId, fileName); - const params = { Bucket: bucketName, Key: key }; - - // Add response headers if specified - if (customFilename) { - params.ResponseContentDisposition = `attachment; filename="${customFilename}"`; - } - - if (contentType) { - params.ResponseContentType = contentType; - } - - try { - const s3 = initializeS3(); - return await getSignedUrl(s3, new GetObjectCommand(params), { expiresIn: s3UrlExpirySeconds }); - } catch (error) { - logger.error('[getS3URL] Error getting signed URL from S3:', error.message); - throw error; - } -} - -/** - * Saves a file from a given URL to S3. - * - * @param {Object} params - * @param {string} params.userId - The user's unique identifier. - * @param {string} params.URL - The source URL of the file. - * @param {string} params.fileName - The file name to use in S3. - * @param {string} [params.basePath='images'] - The base path in the bucket. - * @returns {Promise} Signed URL of the uploaded file. - */ -async function saveURLToS3({ userId, URL, fileName, basePath = defaultBasePath }) { - try { - const response = await fetch(URL); - const buffer = await response.buffer(); - // Optionally you can call getBufferMetadata(buffer) if needed. - return await saveBufferToS3({ userId, buffer, fileName, basePath }); - } catch (error) { - logger.error('[saveURLToS3] Error uploading file from URL to S3:', error.message); - throw error; - } -} - -/** - * Deletes a file from S3. - * - * @param {Object} params - * @param {ServerRequest} params.req - * @param {MongoFile} params.file - The file object to delete. - * @returns {Promise} - */ -async function deleteFileFromS3(req, file) { - await deleteRagFile({ userId: req.user.id, file }); - - const key = extractKeyFromS3Url(file.filepath); - const params = { Bucket: bucketName, Key: key }; - if (!key.includes(req.user.id)) { - const message = `[deleteFileFromS3] User ID mismatch: ${req.user.id} vs ${key}`; - logger.error(message); - throw new Error(message); - } - - try { - const s3 = initializeS3(); - - try { - const headCommand = new HeadObjectCommand(params); - await s3.send(headCommand); - logger.debug('[deleteFileFromS3] File exists, proceeding with deletion'); - } catch (headErr) { - if (headErr.name === 'NotFound') { - logger.warn(`[deleteFileFromS3] File does not exist: ${key}`); - return; - } - } - - const deleteResult = await s3.send(new DeleteObjectCommand(params)); - logger.debug('[deleteFileFromS3] Delete command response:', JSON.stringify(deleteResult)); - try { - await s3.send(new HeadObjectCommand(params)); - logger.error('[deleteFileFromS3] File still exists after deletion!'); - } catch (verifyErr) { - if (verifyErr.name === 'NotFound') { - logger.debug(`[deleteFileFromS3] Verified file is deleted: ${key}`); - } else { - logger.error('[deleteFileFromS3] Error verifying deletion:', verifyErr); - } - } - - logger.debug('[deleteFileFromS3] S3 File deletion completed'); - } catch (error) { - logger.error(`[deleteFileFromS3] Error deleting file from S3: ${error.message}`); - logger.error(error.stack); - - // If the file is not found, we can safely return. - if (error.code === 'NoSuchKey') { - return; - } - throw error; - } -} - -/** - * Uploads a local file to S3 by streaming it directly without loading into memory. - * - * @param {Object} params - * @param {import('express').Request} params.req - The Express request (must include user). - * @param {Express.Multer.File} params.file - The file object from Multer. - * @param {string} params.file_id - Unique file identifier. - * @param {string} [params.basePath='images'] - The base path in the bucket. - * @returns {Promise<{ filepath: string, bytes: number }>} - */ -async function uploadFileToS3({ req, file, file_id, basePath = defaultBasePath }) { - try { - const inputFilePath = file.path; - const userId = req.user.id; - const fileName = `${file_id}__${file.originalname}`; - const key = getS3Key(basePath, userId, fileName); - - const stats = await fs.promises.stat(inputFilePath); - const bytes = stats.size; - const fileStream = fs.createReadStream(inputFilePath); - - const s3 = initializeS3(); - const uploadParams = { - Bucket: bucketName, - Key: key, - Body: fileStream, - }; - - await s3.send(new PutObjectCommand(uploadParams)); - const fileURL = await getS3URL({ userId, fileName, basePath }); - return { filepath: fileURL, bytes }; - } catch (error) { - logger.error('[uploadFileToS3] Error streaming file to S3:', error); - try { - if (file && file.path) { - await fs.promises.unlink(file.path); - } - } catch (unlinkError) { - logger.error( - '[uploadFileToS3] Error deleting temporary file, likely already deleted:', - unlinkError.message, - ); - } - throw error; - } -} - -/** - * Extracts the S3 key from a URL or returns the key if already properly formatted - * - * @param {string} fileUrlOrKey - The file URL or key - * @returns {string} The S3 key - */ -function extractKeyFromS3Url(fileUrlOrKey) { - if (!fileUrlOrKey) { - throw new Error('Invalid input: URL or key is empty'); - } - - try { - const url = new URL(fileUrlOrKey); - 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; - } - - const key = fileUrlOrKey.startsWith('/') ? fileUrlOrKey.substring(1) : fileUrlOrKey; - logger.debug( - `[extractKeyFromS3Url] FALLBACK. fileUrlOrKey: ${fileUrlOrKey}, Extracted key: ${key}`, - ); - return key; - } -} - -/** - * Retrieves a readable stream for a file stored in S3. - * - * @param {ServerRequest} req - Server request object. - * @param {string} filePath - The S3 key of the file. - * @returns {Promise} - */ -async function getS3FileStream(_req, filePath) { - try { - const Key = extractKeyFromS3Url(filePath); - const params = { Bucket: bucketName, Key }; - const s3 = initializeS3(); - const data = await s3.send(new GetObjectCommand(params)); - return data.Body; // Returns a Node.js ReadableStream. - } catch (error) { - logger.error('[getS3FileStream] Error retrieving S3 file stream:', error); - throw error; - } -} - -/** - * Determines if a signed S3 URL is close to expiration - * - * @param {string} signedUrl - The signed S3 URL - * @param {number} bufferSeconds - Buffer time in seconds - * @returns {boolean} True if the URL needs refreshing - */ -function needsRefresh(signedUrl, bufferSeconds) { - try { - // Parse the URL - const url = new URL(signedUrl); - - // Check if it has the signature parameters that indicate it's a signed URL - // X-Amz-Signature is the most reliable indicator for AWS signed URLs - if (!url.searchParams.has('X-Amz-Signature')) { - // Not a signed URL, so no expiration to check (or it's already a proxy URL) - return false; - } - - // Extract the expiration time from the URL - const expiresParam = url.searchParams.get('X-Amz-Expires'); - const dateParam = url.searchParams.get('X-Amz-Date'); - - if (!expiresParam || !dateParam) { - // Missing expiration information, assume it needs refresh to be safe - return true; - } - - // Parse the AWS date format (YYYYMMDDTHHMMSSZ) - const year = dateParam.substring(0, 4); - const month = dateParam.substring(4, 6); - const day = dateParam.substring(6, 8); - const hour = dateParam.substring(9, 11); - const minute = dateParam.substring(11, 13); - const second = dateParam.substring(13, 15); - - const dateObj = new Date(`${year}-${month}-${day}T${hour}:${minute}:${second}Z`); - const expiresAtDate = new Date(dateObj.getTime() + parseInt(expiresParam) * 1000); - - // Check if it's close to expiration - const now = new Date(); - - // If S3_REFRESH_EXPIRY_MS is set, use it to determine if URL is expired - if (s3RefreshExpiryMs !== null) { - const urlCreationTime = dateObj.getTime(); - const urlAge = now.getTime() - urlCreationTime; - return urlAge >= s3RefreshExpiryMs; - } - - // Otherwise use the default buffer-based logic - const bufferTime = new Date(now.getTime() + bufferSeconds * 1000); - return expiresAtDate <= bufferTime; - } catch (error) { - logger.error('Error checking URL expiration:', error); - // If we can't determine, assume it needs refresh to be safe - return true; - } -} - -/** - * Generates a new URL for an expired S3 URL - * @param {string} currentURL - The current file URL - * @returns {Promise} - */ -async function getNewS3URL(currentURL) { - try { - const s3Key = extractKeyFromS3Url(currentURL); - if (!s3Key) { - return; - } - const keyParts = s3Key.split('/'); - if (keyParts.length < 3) { - return; - } - - const basePath = keyParts[0]; - const userId = keyParts[1]; - const fileName = keyParts.slice(2).join('/'); - - return await getS3URL({ - userId, - fileName, - basePath, - }); - } catch (error) { - logger.error('Error getting new S3 URL:', error); - } -} - -/** - * Refreshes S3 URLs for an array of files if they're expired or close to expiring - * - * @param {MongoFile[]} files - Array of file documents - * @param {(files: MongoFile[]) => Promise} batchUpdateFiles - Function to update files in the database - * @param {number} [bufferSeconds=3600] - Buffer time in seconds to check for expiration - * @returns {Promise} The files with refreshed URLs if needed - */ -async function refreshS3FileUrls(files, batchUpdateFiles, bufferSeconds = 3600) { - if (!files || !Array.isArray(files) || files.length === 0) { - return files; - } - - const filesToUpdate = []; - - for (let i = 0; i < files.length; i++) { - const file = files[i]; - if (!file?.file_id) { - continue; - } - if (file.source !== FileSources.s3) { - continue; - } - if (!file.filepath) { - continue; - } - if (!needsRefresh(file.filepath, bufferSeconds)) { - continue; - } - try { - const newURL = await getNewS3URL(file.filepath); - if (!newURL) { - continue; - } - filesToUpdate.push({ - file_id: file.file_id, - filepath: newURL, - }); - files[i].filepath = newURL; - } catch (error) { - logger.error(`Error refreshing S3 URL for file ${file.file_id}:`, error); - } - } - - if (filesToUpdate.length > 0) { - await batchUpdateFiles(filesToUpdate); - } - - return files; -} - -/** - * Refreshes a single S3 URL if it's expired or close to expiring - * - * @param {{ filepath: string, source: string }} fileObj - Simple file object containing filepath and source - * @param {number} [bufferSeconds=3600] - Buffer time in seconds to check for expiration - * @returns {Promise} The refreshed URL or the original URL if no refresh needed - */ -async function refreshS3Url(fileObj, bufferSeconds = 3600) { - if (!fileObj || fileObj.source !== FileSources.s3 || !fileObj.filepath) { - return fileObj?.filepath || ''; - } - - if (!needsRefresh(fileObj.filepath, bufferSeconds)) { - return fileObj.filepath; - } - - try { - const s3Key = extractKeyFromS3Url(fileObj.filepath); - if (!s3Key) { - logger.warn(`Unable to extract S3 key from URL: ${fileObj.filepath}`); - return fileObj.filepath; - } - - const keyParts = s3Key.split('/'); - if (keyParts.length < 3) { - logger.warn(`Invalid S3 key format: ${s3Key}`); - return fileObj.filepath; - } - - const basePath = keyParts[0]; - const userId = keyParts[1]; - const fileName = keyParts.slice(2).join('/'); - - const newUrl = await getS3URL({ - userId, - fileName, - basePath, - }); - - logger.debug(`Refreshed S3 URL for key: ${s3Key}`); - return newUrl; - } catch (error) { - logger.error(`Error refreshing S3 URL: ${error.message}`); - return fileObj.filepath; - } -} - -module.exports = { - saveBufferToS3, - saveURLToS3, - getS3URL, - deleteFileFromS3, - uploadFileToS3, - getS3FileStream, - refreshS3FileUrls, - refreshS3Url, - needsRefresh, - getNewS3URL, - extractKeyFromS3Url, -}; diff --git a/api/server/services/Files/S3/images.js b/api/server/services/Files/S3/images.js deleted file mode 100644 index 9bdae940c3..0000000000 --- a/api/server/services/Files/S3/images.js +++ /dev/null @@ -1,129 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const sharp = require('sharp'); -const { logger } = require('@librechat/data-schemas'); -const { resizeImageBuffer } = require('../images/resize'); -const { updateUser, updateFile } = require('~/models'); -const { saveBufferToS3 } = require('./crud'); - -const defaultBasePath = 'images'; - -/** - * Resizes, converts, and uploads an image file to S3. - * - * @param {Object} params - * @param {import('express').Request} params.req - Express request (expects `user` and `appConfig.imageOutputType`). - * @param {Express.Multer.File} params.file - File object from Multer. - * @param {string} params.file_id - Unique file identifier. - * @param {any} params.endpoint - Endpoint identifier used in image processing. - * @param {string} [params.resolution='high'] - Desired image resolution. - * @param {string} [params.basePath='images'] - Base path in the bucket. - * @returns {Promise<{ filepath: string, bytes: number, width: number, height: number }>} - */ -async function uploadImageToS3({ - req, - file, - file_id, - endpoint, - resolution = 'high', - basePath = defaultBasePath, -}) { - try { - const appConfig = req.config; - const inputFilePath = file.path; - const inputBuffer = await fs.promises.readFile(inputFilePath); - const { - buffer: resizedBuffer, - width, - height, - } = await resizeImageBuffer(inputBuffer, resolution, endpoint); - const extension = path.extname(inputFilePath); - const userId = req.user.id; - - let processedBuffer; - let fileName = `${file_id}__${path.basename(inputFilePath)}`; - const targetExtension = `.${appConfig.imageOutputType}`; - - if (extension.toLowerCase() === targetExtension) { - processedBuffer = resizedBuffer; - } else { - processedBuffer = await sharp(resizedBuffer).toFormat(appConfig.imageOutputType).toBuffer(); - fileName = fileName.replace(new RegExp(path.extname(fileName) + '$'), targetExtension); - if (!path.extname(fileName)) { - fileName += targetExtension; - } - } - - const downloadURL = await saveBufferToS3({ - userId, - buffer: processedBuffer, - fileName, - basePath, - }); - await fs.promises.unlink(inputFilePath); - const bytes = Buffer.byteLength(processedBuffer); - return { filepath: downloadURL, bytes, width, height }; - } catch (error) { - logger.error('[uploadImageToS3] Error uploading image to S3:', error.message); - throw error; - } -} - -/** - * Updates a file record and returns its signed URL. - * - * @param {import('express').Request} req - Express request. - * @param {Object} file - File metadata. - * @returns {Promise<[Promise, string]>} - */ -async function prepareImageURLS3(req, file) { - try { - const updatePromise = updateFile({ file_id: file.file_id }); - return Promise.all([updatePromise, file.filepath]); - } catch (error) { - logger.error('[prepareImageURLS3] Error preparing image URL:', error.message); - throw error; - } -} - -/** - * Processes a user's avatar image by uploading it to S3 and updating the user's avatar URL if required. - * - * @param {Object} params - * @param {Buffer} params.buffer - Avatar image buffer. - * @param {string} params.userId - User's unique identifier. - * @param {string} params.manual - 'true' or 'false' flag for manual update. - * @param {string} [params.agentId] - Optional agent ID if this is an agent avatar. - * @param {string} [params.basePath='images'] - Base path in the bucket. - * @returns {Promise} Signed URL of the uploaded avatar. - */ -async function processS3Avatar({ buffer, userId, manual, agentId, basePath = defaultBasePath }) { - try { - const metadata = await sharp(buffer).metadata(); - const extension = metadata.format === 'gif' ? 'gif' : 'png'; - const timestamp = new Date().getTime(); - - /** Unique filename with timestamp and optional agent ID */ - const fileName = agentId - ? `agent-${agentId}-avatar-${timestamp}.${extension}` - : `avatar-${timestamp}.${extension}`; - - const downloadURL = await saveBufferToS3({ userId, buffer, fileName, basePath }); - - // Only update user record if this is a user avatar (manual === 'true') - if (manual === 'true' && !agentId) { - await updateUser(userId, { avatar: downloadURL }); - } - - return downloadURL; - } catch (error) { - logger.error('[processS3Avatar] Error processing S3 avatar:', error.message); - throw error; - } -} - -module.exports = { - uploadImageToS3, - prepareImageURLS3, - processS3Avatar, -}; diff --git a/api/server/services/Files/S3/index.js b/api/server/services/Files/S3/index.js deleted file mode 100644 index 21e2f2ba7d..0000000000 --- a/api/server/services/Files/S3/index.js +++ /dev/null @@ -1,7 +0,0 @@ -const crud = require('./crud'); -const images = require('./images'); - -module.exports = { - ...crud, - ...images, -}; diff --git a/api/server/services/Files/permissions.js b/api/server/services/Files/permissions.js index d909afe25a..ffa8e74799 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'); +const { getAgent } = require('~/models'); /** - * 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..c926e83464 --- /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', () => ({ + 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'); +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 d01128927a..f7d7731975 100644 --- a/api/server/services/Files/process.js +++ b/api/server/services/Files/process.js @@ -27,16 +27,15 @@ const { resizeImageBuffer, } = require('~/server/services/Files/images'); const { addResourceFileId, deleteResourceFileId } = require('~/server/controllers/assistants/v2'); -const { addAgentResourceFile, removeAgentResourceFiles } = require('~/models/Agent'); const { getOpenAIClient } = require('~/server/controllers/assistants/helpers'); const { loadAuthValues } = require('~/server/services/Tools/credentials'); -const { createFile, updateFileUsage, deleteFiles } = require('~/models'); const { getFileStrategy } = require('~/server/utils/getFileStrategy'); const { checkCapability } = require('~/server/services/Config'); const { LB_QueueAsyncCall } = require('~/server/utils/queue'); const { getStrategyFunctions } = require('./strategies'); const { determineFileType } = require('~/server/utils'); const { STTService } = require('./Audio/STTService'); +const db = require('~/models'); /** * Creates a modular file upload wrapper that ensures filename sanitization @@ -211,7 +210,7 @@ const processDeleteRequest = async ({ req, files }) => { if (agentFiles.length > 0) { promises.push( - removeAgentResourceFiles({ + db.removeAgentResourceFiles({ agent_id: req.body.agent_id, files: agentFiles, }), @@ -219,7 +218,7 @@ const processDeleteRequest = async ({ req, files }) => { } await Promise.allSettled(promises); - await deleteFiles(resolvedFileIds); + await db.deleteFiles(resolvedFileIds); }; /** @@ -251,7 +250,7 @@ const processFileURL = async ({ fileStrategy, userId, URL, fileName, basePath, c dimensions = {}, } = (await saveURL({ userId, URL, fileName, basePath })) || {}; const filepath = await getFileURL({ fileName: `${userId}/${fileName}`, basePath }); - return await createFile( + return await db.createFile( { user: userId, file_id: v4(), @@ -297,7 +296,7 @@ const processImageFile = async ({ req, res, metadata, returnFile = false }) => { endpoint, }); - const result = await createFile( + const result = await db.createFile( { user: req.user.id, file_id, @@ -349,7 +348,7 @@ const uploadImageBuffer = async ({ req, context, metadata = {}, resize = true }) } const fileName = `${file_id}-${filename}`; const filepath = await saveBuffer({ userId: req.user.id, fileName, buffer }); - return await createFile( + return await db.createFile( { user: req.user.id, file_id, @@ -435,7 +434,7 @@ const processFileUpload = async ({ req, res, metadata }) => { filepath = result.filepath; } - const result = await createFile( + const result = await db.createFile( { user: req.user.id, file_id: id ?? file_id, @@ -545,14 +544,14 @@ const processAgentFileUpload = async ({ req, res, metadata }) => { }); if (!messageAttachment && tool_resource) { - await addAgentResourceFile({ - req, + await db.addAgentResourceFile({ file_id, agent_id, tool_resource, + updatingUserId: req?.user?.id, }); } - const result = await createFile(fileInfo, true); + const result = await db.createFile(fileInfo, true); return res .status(200) .json({ message: 'Agent file uploaded and processed successfully', ...result }); @@ -685,11 +684,11 @@ const processAgentFileUpload = async ({ req, res, metadata }) => { let filepath = _filepath; if (!messageAttachment && tool_resource) { - await addAgentResourceFile({ - req, + await db.addAgentResourceFile({ file_id, agent_id, tool_resource, + updatingUserId: req?.user?.id, }); } @@ -720,7 +719,7 @@ const processAgentFileUpload = async ({ req, res, metadata }) => { width, }); - const result = await createFile(fileInfo, true); + const result = await db.createFile(fileInfo, true); res.status(200).json({ message: 'Agent file uploaded and processed successfully', ...result }); }; @@ -766,10 +765,10 @@ const processOpenAIFile = async ({ }; if (saveFile) { - await createFile(file, true); + await db.createFile(file, true); } else if (updateUsage) { try { - await updateFileUsage({ file_id }); + await db.updateFileUsage({ file_id }); } catch (error) { logger.error('Error updating file usage', error); } @@ -807,7 +806,7 @@ const processOpenAIImageOutput = async ({ req, buffer, file_id, filename, fileEx file_id, filename, }; - createFile(file, true); + db.createFile(file, true); return file; }; @@ -951,7 +950,7 @@ async function saveBase64Image( fileName: filename, buffer: image.buffer, }); - return await createFile( + return await db.createFile( { type, source, diff --git a/api/server/services/Files/process.spec.js b/api/server/services/Files/process.spec.js index 7737255a52..39300161a8 100644 --- a/api/server/services/Files/process.spec.js +++ b/api/server/services/Files/process.spec.js @@ -30,11 +30,6 @@ jest.mock('~/server/controllers/assistants/v2', () => ({ deleteResourceFileId: jest.fn(), })); -jest.mock('~/models/Agent', () => ({ - addAgentResourceFile: jest.fn().mockResolvedValue({}), - removeAgentResourceFiles: jest.fn(), -})); - jest.mock('~/server/controllers/assistants/helpers', () => ({ getOpenAIClient: jest.fn(), })); @@ -47,6 +42,8 @@ jest.mock('~/models', () => ({ createFile: jest.fn().mockResolvedValue({ file_id: 'created-file-id' }), updateFileUsage: jest.fn(), deleteFiles: jest.fn(), + addAgentResourceFile: jest.fn().mockResolvedValue({}), + removeAgentResourceFiles: jest.fn(), })); jest.mock('~/server/utils/getFileStrategy', () => ({ diff --git a/api/server/services/Files/strategies.js b/api/server/services/Files/strategies.js index 25341b5715..47b39cb87b 100644 --- a/api/server/services/Files/strategies.js +++ b/api/server/services/Files/strategies.js @@ -1,6 +1,13 @@ const { FileSources } = require('librechat-data-provider'); const { + getS3URL, + saveURLToS3, parseDocument, + uploadFileToS3, + S3ImageService, + saveBufferToS3, + getS3FileStream, + deleteFileFromS3, uploadMistralOCR, uploadAzureMistralOCR, uploadGoogleVertexMistralOCR, @@ -27,17 +34,18 @@ const { processLocalAvatar, getLocalFileStream, } = require('./Local'); -const { - getS3URL, - saveURLToS3, - saveBufferToS3, - getS3FileStream, - uploadImageToS3, - prepareImageURLS3, - deleteFileFromS3, - processS3Avatar, - uploadFileToS3, -} = require('./S3'); +const { resizeImageBuffer } = require('./images/resize'); +const { updateUser, updateFile } = require('~/models'); + +const s3ImageService = new S3ImageService({ + resizeImageBuffer, + updateUser, + updateFile, +}); + +const uploadImageToS3 = (params) => s3ImageService.uploadImageToS3(params); +const prepareImageURLS3 = (_req, file) => s3ImageService.prepareImageURL(file); +const processS3Avatar = (params) => s3ImageService.processAvatar(params); const { saveBufferToAzure, saveURLToAzure, diff --git a/api/server/services/MCP.js b/api/server/services/MCP.js index ad1f9f5cc3..5d97891c55 100644 --- a/api/server/services/MCP.js +++ b/api/server/services/MCP.js @@ -15,13 +15,7 @@ const { GenerationJobManager, resolveJsonSchemaRefs, } = require('@librechat/api'); -const { - Time, - CacheKeys, - Constants, - ContentTypes, - isAssistantsEndpoint, -} = require('librechat-data-provider'); +const { Time, CacheKeys, Constants, isAssistantsEndpoint } = require('librechat-data-provider'); const { getOAuthReconnectionManager, getMCPServersRegistry, @@ -34,6 +28,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 +254,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 +321,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 +384,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 +460,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 +481,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({ @@ -526,9 +599,6 @@ function createToolInstance({ if (isAssistantsEndpoint(provider) && Array.isArray(result)) { return result[0]; } - if (isGoogle && Array.isArray(result[0]) && result[0][0]?.type === ContentTypes.TEXT) { - return [result[0][0].text, result[1]]; - } return result; } catch (error) { logger.error( @@ -720,4 +790,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/PermissionService.js b/api/server/services/PermissionService.js index a843f48f6f..fc67b0bc49 100644 --- a/api/server/services/PermissionService.js +++ b/api/server/services/PermissionService.js @@ -9,22 +9,7 @@ const { getGroupMembers, getGroupOwners, } = require('~/server/services/GraphApiService'); -const { - findAccessibleResources: findAccessibleResourcesACL, - getEffectivePermissions: getEffectivePermissionsACL, - getEffectivePermissionsForResources: getEffectivePermissionsForResourcesACL, - grantPermission: grantPermissionACL, - findEntriesByPrincipalsAndResource, - findGroupByExternalId, - findRoleByIdentifier, - getUserPrincipals, - hasPermission, - createGroup, - createUser, - updateUser, - findUser, -} = require('~/models'); -const { AclEntry, AccessRole, Group } = require('~/db/models'); +const db = require('~/models'); /** @type {boolean|null} */ let transactionSupportCache = null; @@ -96,7 +81,7 @@ const grantPermission = async ({ validateResourceType(resourceType); // Get the role to determine permission bits - const role = await findRoleByIdentifier(accessRoleId); + const role = await db.findRoleByIdentifier(accessRoleId); if (!role) { throw new Error(`Role ${accessRoleId} not found`); } @@ -107,7 +92,7 @@ const grantPermission = async ({ `Role ${accessRoleId} is for ${role.resourceType} resources, not ${resourceType}`, ); } - return await grantPermissionACL( + return await db.grantPermission( principalType, principalId, resourceType, @@ -141,13 +126,13 @@ const checkPermission = async ({ userId, role, resourceType, resourceId, require validateResourceType(resourceType); - const principals = await getUserPrincipals({ userId, role }); + const principals = await db.getUserPrincipals({ userId, role }); if (principals.length === 0) { return false; } - return await hasPermission(principals, resourceType, resourceId, requiredPermission); + return await db.hasPermission(principals, resourceType, resourceId, requiredPermission); } catch (error) { logger.error(`[PermissionService.checkPermission] Error: ${error.message}`); if (error.message.includes('requiredPermission must be')) { @@ -170,13 +155,13 @@ const getEffectivePermissions = async ({ userId, role, resourceType, resourceId try { validateResourceType(resourceType); - const principals = await getUserPrincipals({ userId, role }); + const principals = await db.getUserPrincipals({ userId, role }); if (principals.length === 0) { return 0; } - return await getEffectivePermissionsACL(principals, resourceType, resourceId); + return await db.getEffectivePermissions(principals, resourceType, resourceId); } catch (error) { logger.error(`[PermissionService.getEffectivePermissions] Error: ${error.message}`); return 0; @@ -206,10 +191,10 @@ const getResourcePermissionsMap = async ({ userId, role, resourceType, resourceI try { // Get user principals (user + groups + public) - const principals = await getUserPrincipals({ userId, role }); + const principals = await db.getUserPrincipals({ userId, role }); // Use batch method from aclEntry - const permissionsMap = await getEffectivePermissionsForResourcesACL( + const permissionsMap = await db.getEffectivePermissionsForResources( principals, resourceType, resourceIds, @@ -244,12 +229,12 @@ const findAccessibleResources = async ({ userId, role, resourceType, requiredPer validateResourceType(resourceType); // Get all principals for the user (user + groups + public) - const principalsList = await getUserPrincipals({ userId, role }); + const principalsList = await db.getUserPrincipals({ userId, role }); if (principalsList.length === 0) { return []; } - return await findAccessibleResourcesACL(principalsList, resourceType, requiredPermissions); + return await db.findAccessibleResources(principalsList, resourceType, requiredPermissions); } catch (error) { logger.error(`[PermissionService.findAccessibleResources] Error: ${error.message}`); // Re-throw validation errors @@ -275,17 +260,9 @@ const findPubliclyAccessibleResources = async ({ resourceType, requiredPermissio validateResourceType(resourceType); - // Find all public ACL entries where the public principal has at least the required permission bits - const entries = await AclEntry.find({ - principalType: PrincipalType.PUBLIC, - resourceType, - permBits: { $bitsAllSet: requiredPermissions }, - }).distinct('resourceId'); - - return entries; + return await db.findPublicResourceIds(resourceType, requiredPermissions); } catch (error) { logger.error(`[PermissionService.findPubliclyAccessibleResources] Error: ${error.message}`); - // Re-throw validation errors if (error.message.includes('requiredPermissions must be')) { throw error; } @@ -302,7 +279,7 @@ const findPubliclyAccessibleResources = async ({ resourceType, requiredPermissio const getAvailableRoles = async ({ resourceType }) => { validateResourceType(resourceType); - return await AccessRole.find({ resourceType }).lean(); + return await db.findRolesByResourceType(resourceType); }; /** @@ -331,15 +308,15 @@ const ensurePrincipalExists = async function (principal) { throw new Error('Entra ID user principals must have email and idOnTheSource'); } - let existingUser = await findUser({ idOnTheSource: principal.idOnTheSource }); + let existingUser = await db.findUser({ idOnTheSource: principal.idOnTheSource }); if (!existingUser) { - existingUser = await findUser({ email: principal.email }); + existingUser = await db.findUser({ email: principal.email }); } if (existingUser) { if (!existingUser.idOnTheSource && principal.idOnTheSource) { - await updateUser(existingUser._id, { + await db.updateUser(existingUser._id, { idOnTheSource: principal.idOnTheSource, provider: 'openid', }); @@ -355,7 +332,7 @@ const ensurePrincipalExists = async function (principal) { idOnTheSource: principal.idOnTheSource, }; - const userId = await createUser(userData, true, true); + const userId = await db.createUser(userData, true, true); return userId.toString(); } @@ -420,10 +397,10 @@ const ensureGroupPrincipalExists = async function (principal, authContext = null } } - let existingGroup = await findGroupByExternalId(principal.idOnTheSource, 'entra'); + let existingGroup = await db.findGroupByExternalId(principal.idOnTheSource, 'entra'); if (!existingGroup && principal.email) { - existingGroup = await Group.findOne({ email: principal.email.toLowerCase() }).lean(); + existingGroup = await db.findGroupByQuery({ email: principal.email.toLowerCase() }); } if (existingGroup) { @@ -452,7 +429,7 @@ const ensureGroupPrincipalExists = async function (principal, authContext = null } if (needsUpdate) { - await Group.findByIdAndUpdate(existingGroup._id, { $set: updateData }, { new: true }); + await db.updateGroupById(existingGroup._id, updateData); } return existingGroup._id.toString(); @@ -473,7 +450,7 @@ const ensureGroupPrincipalExists = async function (principal, authContext = null groupData.description = principal.description; } - const newGroup = await createGroup(groupData); + const newGroup = await db.createGroup(groupData); return newGroup._id.toString(); } if (principal.id && authContext == null) { @@ -520,7 +497,7 @@ const syncUserEntraGroupMemberships = async (user, accessToken, session = null) const sessionOptions = session ? { session } : {}; - await Group.updateMany( + await db.bulkUpdateGroups( { idOnTheSource: { $in: allGroupIds }, source: 'entra', @@ -530,13 +507,13 @@ const syncUserEntraGroupMemberships = async (user, accessToken, session = null) sessionOptions, ); - await Group.updateMany( + await db.bulkUpdateGroups( { source: 'entra', memberIds: user.idOnTheSource, idOnTheSource: { $nin: allGroupIds }, }, - { $pull: { memberIds: user.idOnTheSource } }, + { $pullAll: { memberIds: [user.idOnTheSource] } }, sessionOptions, ); } catch (error) { @@ -563,7 +540,7 @@ const hasPublicPermission = async ({ resourceType, resourceId, requiredPermissio // Use public principal to check permissions const publicPrincipal = [{ principalType: PrincipalType.PUBLIC }]; - const entries = await findEntriesByPrincipalsAndResource( + const entries = await db.findEntriesByPrincipalsAndResource( publicPrincipal, resourceType, resourceId, @@ -628,7 +605,7 @@ const bulkUpdateResourcePermissions = async ({ const sessionOptions = localSession ? { session: localSession } : {}; - const roles = await AccessRole.find({ resourceType }).lean(); + const roles = await db.findRolesByResourceType(resourceType); const rolesMap = new Map(); roles.forEach((role) => { rolesMap.set(role.accessRoleId, role); @@ -732,7 +709,7 @@ const bulkUpdateResourcePermissions = async ({ } if (bulkWrites.length > 0) { - await AclEntry.bulkWrite(bulkWrites, sessionOptions); + await db.bulkWriteAclEntries(bulkWrites, sessionOptions); } const deleteQueries = []; @@ -773,12 +750,7 @@ const bulkUpdateResourcePermissions = async ({ } if (deleteQueries.length > 0) { - await AclEntry.deleteMany( - { - $or: deleteQueries, - }, - sessionOptions, - ); + await db.deleteAclEntries({ $or: deleteQueries }, sessionOptions); } if (shouldEndSession && supportsTransactions) { @@ -788,7 +760,15 @@ const bulkUpdateResourcePermissions = async ({ return results; } catch (error) { if (shouldEndSession && supportsTransactions) { - await localSession.abortTransaction(); + try { + await localSession.abortTransaction(); + } catch (transactionError) { + /** best-effort abort; may fail if commit already succeeded */ + logger.error( + `[PermissionService.bulkUpdateResourcePermissions] Error aborting transaction:`, + transactionError, + ); + } } logger.error(`[PermissionService.bulkUpdateResourcePermissions] Error: ${error.message}`); throw error; @@ -814,7 +794,7 @@ const removeAllPermissions = async ({ resourceType, resourceId }) => { throw new Error(`Invalid resource ID: ${resourceId}`); } - const result = await AclEntry.deleteMany({ + const result = await db.deleteAclEntries({ resourceType, resourceId, }); diff --git a/api/server/services/PermissionService.spec.js b/api/server/services/PermissionService.spec.js index b41780f345..477b0702b9 100644 --- a/api/server/services/PermissionService.spec.js +++ b/api/server/services/PermissionService.spec.js @@ -9,6 +9,7 @@ const { } = require('librechat-data-provider'); const { bulkUpdateResourcePermissions, + syncUserEntraGroupMemberships, getEffectivePermissions, findAccessibleResources, getAvailableRoles, @@ -26,7 +27,11 @@ jest.mock('@librechat/data-schemas', () => ({ // Mock GraphApiService to prevent config loading issues jest.mock('~/server/services/GraphApiService', () => ({ + entraIdPrincipalFeatureEnabled: jest.fn().mockReturnValue(false), + getUserOwnedEntraGroups: jest.fn().mockResolvedValue([]), + getUserEntraGroups: jest.fn().mockResolvedValue([]), getGroupMembers: jest.fn().mockResolvedValue([]), + getGroupOwners: jest.fn().mockResolvedValue([]), })); // Mock the logger @@ -1933,3 +1938,134 @@ describe('PermissionService', () => { }); }); }); + +describe('syncUserEntraGroupMemberships - $pullAll on Group.memberIds', () => { + const { + entraIdPrincipalFeatureEnabled, + getUserEntraGroups, + } = require('~/server/services/GraphApiService'); + const { Group } = require('~/db/models'); + + const userEntraId = 'entra-user-001'; + const user = { + openidId: 'openid-sub-001', + idOnTheSource: userEntraId, + provider: 'openid', + }; + + beforeEach(async () => { + await Group.deleteMany({}); + entraIdPrincipalFeatureEnabled.mockReturnValue(true); + }); + + afterEach(() => { + entraIdPrincipalFeatureEnabled.mockReturnValue(false); + getUserEntraGroups.mockResolvedValue([]); + }); + + it('should add user to matching Entra groups and remove from non-matching ones', async () => { + await Group.create([ + { name: 'Group A', source: 'entra', idOnTheSource: 'entra-group-a', memberIds: [] }, + { + name: 'Group B', + source: 'entra', + idOnTheSource: 'entra-group-b', + memberIds: [userEntraId], + }, + { + name: 'Group C', + source: 'entra', + idOnTheSource: 'entra-group-c', + memberIds: [userEntraId], + }, + ]); + + getUserEntraGroups.mockResolvedValue(['entra-group-a', 'entra-group-c']); + + await syncUserEntraGroupMemberships(user, 'fake-access-token'); + + const groups = await Group.find({ source: 'entra' }).sort({ name: 1 }).lean(); + expect(groups[0].memberIds).toContain(userEntraId); + expect(groups[1].memberIds).not.toContain(userEntraId); + expect(groups[2].memberIds).toContain(userEntraId); + }); + + it('should not modify groups when API returns empty list (early return)', async () => { + await Group.create([ + { + name: 'Group X', + source: 'entra', + idOnTheSource: 'entra-x', + memberIds: [userEntraId, 'other-user'], + }, + { name: 'Group Y', source: 'entra', idOnTheSource: 'entra-y', memberIds: [userEntraId] }, + ]); + + getUserEntraGroups.mockResolvedValue([]); + + await syncUserEntraGroupMemberships(user, 'fake-token'); + + const groups = await Group.find({ source: 'entra' }).sort({ name: 1 }).lean(); + expect(groups[0].memberIds).toContain(userEntraId); + expect(groups[0].memberIds).toContain('other-user'); + expect(groups[1].memberIds).toContain(userEntraId); + }); + + it('should remove user from groups not in the API response via $pullAll', async () => { + await Group.create([ + { name: 'Keep', source: 'entra', idOnTheSource: 'entra-keep', memberIds: [userEntraId] }, + { + name: 'Remove', + source: 'entra', + idOnTheSource: 'entra-remove', + memberIds: [userEntraId, 'other-user'], + }, + ]); + + getUserEntraGroups.mockResolvedValue(['entra-keep']); + + await syncUserEntraGroupMemberships(user, 'fake-token'); + + const keep = await Group.findOne({ idOnTheSource: 'entra-keep' }).lean(); + const remove = await Group.findOne({ idOnTheSource: 'entra-remove' }).lean(); + expect(keep.memberIds).toContain(userEntraId); + expect(remove.memberIds).not.toContain(userEntraId); + expect(remove.memberIds).toContain('other-user'); + }); + + it('should not modify local groups', async () => { + await Group.create([ + { name: 'Local Group', source: 'local', memberIds: [userEntraId] }, + { + name: 'Entra Group', + source: 'entra', + idOnTheSource: 'entra-only', + memberIds: [userEntraId], + }, + ]); + + getUserEntraGroups.mockResolvedValue([]); + + await syncUserEntraGroupMemberships(user, 'fake-token'); + + const localGroup = await Group.findOne({ source: 'local' }).lean(); + expect(localGroup.memberIds).toContain(userEntraId); + }); + + it('should early-return when feature is disabled', async () => { + entraIdPrincipalFeatureEnabled.mockReturnValue(false); + + await Group.create({ + name: 'Should Not Touch', + source: 'entra', + idOnTheSource: 'entra-safe', + memberIds: [userEntraId], + }); + + getUserEntraGroups.mockResolvedValue([]); + await syncUserEntraGroupMemberships(user, 'fake-token'); + + const group = await Group.findOne({ idOnTheSource: 'entra-safe' }).lean(); + expect(group.memberIds).toContain(userEntraId); + }); +}); diff --git a/api/server/services/Threads/manage.js b/api/server/services/Threads/manage.js index 627dba1a35..27520f38a5 100644 --- a/api/server/services/Threads/manage.js +++ b/api/server/services/Threads/manage.js @@ -1,16 +1,15 @@ const path = require('path'); const { v4 } = require('uuid'); -const { countTokens, escapeRegExp } = require('@librechat/api'); +const { countTokens } = require('@librechat/api'); +const { escapeRegExp } = require('@librechat/data-schemas'); const { Constants, ContentTypes, AnnotationTypes, defaultOrderQuery, } = require('librechat-data-provider'); +const { recordMessage, getMessages, spendTokens, saveConvo } = require('~/models'); const { retrieveAndProcessFile } = require('~/server/services/Files/process'); -const { recordMessage, getMessages } = require('~/models/Message'); -const { spendTokens } = require('~/models/spendTokens'); -const { saveConvo } = require('~/models/Conversation'); /** * Initializes a new thread or adds messages to an existing thread. @@ -62,24 +61,6 @@ async function initThread({ openai, body, thread_id: _thread_id }) { async function saveUserMessage(req, params) { const tokenCount = await countTokens(params.text); - // todo: do this on the frontend - // const { file_ids = [] } = params; - // let content; - // if (file_ids.length) { - // content = [ - // { - // value: params.text, - // }, - // ...( - // file_ids - // .filter(f => f) - // .map((file_id) => ({ - // file_id, - // })) - // ), - // ]; - // } - const userMessage = { user: params.user, endpoint: params.endpoint, @@ -110,9 +91,15 @@ async function saveUserMessage(req, params) { } const message = await recordMessage(userMessage); - await saveConvo(req, convo, { - context: 'api/server/services/Threads/manage.js #saveUserMessage', - }); + await saveConvo( + { + userId: req?.user?.id, + isTemporary: req?.body?.isTemporary, + interfaceConfig: req?.config?.interfaceConfig, + }, + convo, + { context: 'api/server/services/Threads/manage.js #saveUserMessage' }, + ); return message; } @@ -161,7 +148,11 @@ async function saveAssistantMessage(req, params) { }); await saveConvo( - req, + { + userId: req?.user?.id, + isTemporary: req?.body?.isTemporary, + interfaceConfig: req?.config?.interfaceConfig, + }, { endpoint: params.endpoint, conversationId: params.conversationId, @@ -353,7 +344,11 @@ async function syncMessages({ await Promise.all(recordPromises); await saveConvo( - openai.req, + { + userId: openai.req?.user?.id, + isTemporary: openai.req?.body?.isTemporary, + interfaceConfig: openai.req?.config?.interfaceConfig, + }, { conversationId, file_ids: attached_file_ids, diff --git a/api/server/services/ToolService.js b/api/server/services/ToolService.js index 62499348e6..ca75e7eb4f 100644 --- a/api/server/services/ToolService.js +++ b/api/server/services/ToolService.js @@ -42,6 +42,7 @@ const { } = require('librechat-data-provider'); const { createActionTool, + legacyDomainEncode, decryptMetadata, loadActionSets, domainParser, @@ -64,6 +65,28 @@ const { redactMessage } = require('~/config/parsers'); const { findPluginAuthsByKeys } = require('~/models'); const { getFlowStateManager } = require('~/config'); const { getLogStores } = require('~/cache'); + +const domainSeparatorRegex = new RegExp(actionDomainSeparator, 'g'); + +/** + * 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. @@ -152,8 +175,7 @@ async function processRequiredActions(client, requiredActions) { const promises = []; - /** @type {Action[]} */ - let actionSets = []; + let actionSetsData = null; let isActionTool = false; const ActionToolMap = {}; const ActionBuildersMap = {}; @@ -239,9 +261,9 @@ async function processRequiredActions(client, requiredActions) { if (!tool) { // throw new Error(`Tool ${currentAction.tool} not found.`); - // Load all action sets once if not already loaded - if (!actionSets.length) { - actionSets = + if (!actionSetsData) { + /** @type {Action[]} */ + const actionSets = (await loadActionSets({ assistant_id: client.req.body.assistant_id, })) ?? []; @@ -249,11 +271,16 @@ async function processRequiredActions(client, requiredActions) { // Process all action sets once // Map domains to their processed action sets const processedDomains = new Map(); - const domainMap = new Map(); + const domainLookupMap = new Map(); for (const action of actionSets) { const domain = await domainParser(action.metadata.domain, true); - domainMap.set(domain, action); + domainLookupMap.set(domain, domain); + + const legacyDomain = legacyDomainEncode(action.metadata.domain); + if (legacyDomain !== domain) { + domainLookupMap.set(legacyDomain, domain); + } const isDomainAllowed = await isActionDomainAllowed( action.metadata.domain, @@ -308,27 +335,26 @@ async function processRequiredActions(client, requiredActions) { ActionBuildersMap[action.metadata.domain] = requestBuilders; } - // Update actionSets reference to use the domain map - actionSets = { domainMap, processedDomains }; + actionSetsData = { domainLookupMap, processedDomains }; } - // Find the matching domain for this tool let currentDomain = ''; - for (const domain of actionSets.domainMap.keys()) { - if (currentAction.tool.includes(domain)) { - currentDomain = domain; + let matchedKey = ''; + for (const [key, canonical] of actionSetsData.domainLookupMap.entries()) { + if (currentAction.tool.includes(key)) { + currentDomain = canonical; + matchedKey = key; break; } } - if (!currentDomain || !actionSets.processedDomains.has(currentDomain)) { - // TODO: try `function` if no action set is found - // throw new Error(`Tool ${currentAction.tool} not found.`); + if (!currentDomain || !actionSetsData.processedDomains.has(currentDomain)) { continue; } - const { action, requestBuilders, encrypted } = actionSets.processedDomains.get(currentDomain); - const functionName = currentAction.tool.replace(`${actionDelimiter}${currentDomain}`, ''); + const { action, requestBuilders, encrypted } = + actionSetsData.processedDomains.get(currentDomain); + const functionName = currentAction.tool.replace(`${actionDelimiter}${matchedKey}`, ''); const requestBuilder = requestBuilders[functionName]; if (!requestBuilder) { @@ -445,17 +471,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) => { @@ -468,7 +488,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; @@ -569,12 +592,17 @@ async function loadToolDefinitionsWrapper({ req, res, agent, streamId = null, to const definitions = []; const allowedDomains = appConfig?.actions?.allowedDomains; - const domainSeparatorRegex = new RegExp(actionDomainSeparator, 'g'); + const normalizedToolNames = new Set( + actionToolNames.map((n) => n.replace(domainSeparatorRegex, '_')), + ); for (const action of actionSets) { const domain = await domainParser(action.metadata.domain, true); const normalizedDomain = domain.replace(domainSeparatorRegex, '_'); + const legacyDomain = legacyDomainEncode(action.metadata.domain); + const legacyNormalized = legacyDomain.replace(domainSeparatorRegex, '_'); + const isDomainAllowed = await isActionDomainAllowed(action.metadata.domain, allowedDomains); if (!isDomainAllowed) { logger.warn( @@ -594,7 +622,8 @@ async function loadToolDefinitionsWrapper({ req, res, agent, streamId = null, to for (const sig of functionSignatures) { const toolName = `${sig.name}${actionDelimiter}${normalizedDomain}`; - if (!actionToolNames.some((name) => name.replace(domainSeparatorRegex, '_') === toolName)) { + const legacyToolName = `${sig.name}${actionDelimiter}${legacyNormalized}`; + if (!normalizedToolNames.has(toolName) && !normalizedToolNames.has(legacyToolName)) { continue; } @@ -765,6 +794,7 @@ async function loadToolDefinitionsWrapper({ req, res, agent, streamId = null, to toolContextMap, toolDefinitions, hasDeferredTools, + actionsEnabled, }; } @@ -808,14 +838,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) { @@ -832,6 +855,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) => { @@ -842,7 +866,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; @@ -947,13 +973,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, }; } @@ -969,19 +997,22 @@ async function loadAgentTools({ toolContextMap, toolDefinitions, hasDeferredTools, + actionsEnabled, tools: agentTools, }; } - // Process each action set once (validate spec, decrypt metadata) const processedActionSets = new Map(); - const domainMap = new Map(); + const domainLookupMap = new Map(); for (const action of actionSets) { const domain = await domainParser(action.metadata.domain, true); - domainMap.set(domain, action); + domainLookupMap.set(domain, domain); - // Check if domain is allowed (do this once per action set) + const legacyDomain = legacyDomainEncode(action.metadata.domain); + if (legacyDomain !== domain) { + domainLookupMap.set(legacyDomain, domain); + } const isDomainAllowed = await isActionDomainAllowed( action.metadata.domain, appConfig?.actions?.allowedDomains, @@ -1043,11 +1074,12 @@ async function loadAgentTools({ continue; } - // Find the matching domain for this tool let currentDomain = ''; - for (const domain of domainMap.keys()) { - if (toolName.includes(domain)) { - currentDomain = domain; + let matchedKey = ''; + for (const [key, canonical] of domainLookupMap.entries()) { + if (toolName.includes(key)) { + currentDomain = canonical; + matchedKey = key; break; } } @@ -1058,7 +1090,7 @@ async function loadAgentTools({ const { action, encrypted, zodSchemas, requestBuilders, functionSignatures } = processedActionSets.get(currentDomain); - const functionName = toolName.replace(`${actionDelimiter}${currentDomain}`, ''); + const functionName = toolName.replace(`${actionDelimiter}${matchedKey}`, ''); const functionSig = functionSignatures.find((sig) => sig.name === functionName); const requestBuilder = requestBuilders[functionName]; const zodSchema = zodSchemas[functionName]; @@ -1101,6 +1133,7 @@ async function loadAgentTools({ userMCPAuthMap, toolDefinitions, hasDeferredTools, + actionsEnabled, tools: agentTools, }; } @@ -1118,9 +1151,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({ @@ -1133,11 +1168,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); @@ -1194,7 +1235,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; @@ -1225,7 +1265,7 @@ async function loadToolsForExecution({ } } - if (actionToolNames.length > 0 && agent) { + if (actionToolNames.length > 0 && agent && actionsEnabled) { const actionTools = await loadActionToolsForExecution({ req, res, @@ -1235,6 +1275,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) { @@ -1280,12 +1325,20 @@ async function loadActionToolsForExecution({ } const processedActionSets = new Map(); - const domainMap = new Map(); + /** Maps both new and legacy normalized domains to their canonical (new) domain key */ + const normalizedToDomain = new Map(); const allowedDomains = appConfig?.actions?.allowedDomains; for (const action of actionSets) { const domain = await domainParser(action.metadata.domain, true); - domainMap.set(domain, action); + const normalizedDomain = domain.replace(domainSeparatorRegex, '_'); + normalizedToDomain.set(normalizedDomain, domain); + + const legacyDomain = legacyDomainEncode(action.metadata.domain); + const legacyNormalized = legacyDomain.replace(domainSeparatorRegex, '_'); + if (legacyNormalized !== normalizedDomain) { + normalizedToDomain.set(legacyNormalized, domain); + } const isDomainAllowed = await isActionDomainAllowed(action.metadata.domain, allowedDomains); if (!isDomainAllowed) { @@ -1334,16 +1387,15 @@ async function loadActionToolsForExecution({ functionSignatures, zodSchemas, encrypted, + legacyNormalized, }); } - const domainSeparatorRegex = new RegExp(actionDomainSeparator, 'g'); for (const toolName of actionToolNames) { let currentDomain = ''; - for (const domain of domainMap.keys()) { - const normalizedDomain = domain.replace(domainSeparatorRegex, '_'); + for (const [normalizedDomain, canonicalDomain] of normalizedToDomain.entries()) { if (toolName.includes(normalizedDomain)) { - currentDomain = domain; + currentDomain = canonicalDomain; break; } } @@ -1352,7 +1404,7 @@ async function loadActionToolsForExecution({ continue; } - const { action, encrypted, zodSchemas, requestBuilders, functionSignatures } = + const { action, encrypted, zodSchemas, requestBuilders, functionSignatures, legacyNormalized } = processedActionSets.get(currentDomain); const normalizedDomain = currentDomain.replace(domainSeparatorRegex, '_'); const functionName = toolName.replace(`${actionDelimiter}${normalizedDomain}`, ''); @@ -1361,6 +1413,25 @@ async function loadActionToolsForExecution({ const zodSchema = zodSchemas[functionName]; if (!requestBuilder) { + const legacyFnName = toolName.replace(`${actionDelimiter}${legacyNormalized}`, ''); + if (legacyFnName !== toolName && requestBuilders[legacyFnName]) { + const legacyTool = await createActionTool({ + userId: req.user.id, + res, + action, + streamId, + encrypted, + requestBuilder: requestBuilders[legacyFnName], + zodSchema: zodSchemas[legacyFnName], + name: toolName, + description: + functionSignatures.find((sig) => sig.name === legacyFnName)?.description ?? '', + useSSRFProtection: !Array.isArray(allowedDomains) || allowedDomains.length === 0, + }); + if (legacyTool) { + loadedActionTools.push(legacyTool); + } + } continue; } @@ -1395,4 +1466,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 c44298b09c..a468a88eb3 100644 --- a/api/server/services/__tests__/ToolService.spec.js +++ b/api/server/services/__tests__/ToolService.spec.js @@ -1,19 +1,304 @@ const { + Tools, Constants, + EModelEndpoint, + actionDelimiter, AgentCapabilities, defaultAgentCapabilities, } = require('librechat-data-provider'); -/** - * 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', () => { +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(); + }); + }); + describe('checkCapability logic', () => { - /** - * Simulates the checkCapability function from loadAgentTools - */ const createCheckCapability = (enabledCapabilities, logger = { warn: jest.fn() }) => { return (capability) => { const enabled = enabledCapabilities.has(capability); @@ -124,10 +409,6 @@ describe('ToolService - Capability Checking', () => { }); describe('userMCPAuthMap gating', () => { - /** - * Simulates the guard condition used in both loadToolDefinitionsWrapper - * and loadAgentTools to decide whether getUserMCPAuthMap should be called. - */ const shouldFetchMCPAuth = (tools) => tools?.some((t) => t.includes(Constants.mcp_delimiter)) ?? false; @@ -178,20 +459,17 @@ describe('ToolService - Capability Checking', () => { 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/cleanup.js b/api/server/services/cleanup.js index 7d3dfdec12..dc4f62c2ac 100644 --- a/api/server/services/cleanup.js +++ b/api/server/services/cleanup.js @@ -1,5 +1,5 @@ const { logger } = require('@librechat/data-schemas'); -const { deleteNullOrEmptyConversations } = require('~/models/Conversation'); +const { deleteNullOrEmptyConversations } = require('~/models'); const cleanup = async () => { try { diff --git a/api/server/services/start/migration.js b/api/server/services/start/migration.js index 83b9c83e39..70f8300e08 100644 --- a/api/server/services/start/migration.js +++ b/api/server/services/start/migration.js @@ -6,8 +6,6 @@ const { checkAgentPermissionsMigration, checkPromptPermissionsMigration, } = require('@librechat/api'); -const { getProjectByName } = require('~/models/Project'); -const { Agent, PromptGroup } = require('~/db/models'); const { findRoleByIdentifier } = require('~/models'); /** @@ -20,9 +18,8 @@ async function checkMigrations() { mongoose, methods: { findRoleByIdentifier, - getProjectByName, }, - AgentModel: Agent, + AgentModel: mongoose.models.Agent, }); logAgentMigrationWarning(agentMigrationResult); } catch (error) { @@ -33,9 +30,8 @@ async function checkMigrations() { mongoose, methods: { findRoleByIdentifier, - getProjectByName, }, - PromptGroupModel: PromptGroup, + PromptGroupModel: mongoose.models.PromptGroup, }); logPromptMigrationWarning(promptMigrationResult); } catch (error) { diff --git a/api/server/services/systemGrant.spec.js b/api/server/services/systemGrant.spec.js new file mode 100644 index 0000000000..4e10ee5641 --- /dev/null +++ b/api/server/services/systemGrant.spec.js @@ -0,0 +1,407 @@ +const mongoose = require('mongoose'); +const { createModels, createMethods } = require('@librechat/data-schemas'); +const { MongoMemoryServer } = require('mongodb-memory-server'); +const { SystemRoles, PrincipalType } = require('librechat-data-provider'); +const { SystemCapabilities } = require('@librechat/data-schemas'); + +jest.mock('@librechat/data-schemas', () => ({ + ...jest.requireActual('@librechat/data-schemas'), + getTransactionSupport: jest.fn().mockResolvedValue(false), + createModels: jest.requireActual('@librechat/data-schemas').createModels, + createMethods: jest.requireActual('@librechat/data-schemas').createMethods, +})); + +jest.mock('~/server/services/GraphApiService', () => ({ + entraIdPrincipalFeatureEnabled: jest.fn().mockReturnValue(false), + getUserOwnedEntraGroups: jest.fn().mockResolvedValue([]), + getUserEntraGroups: jest.fn().mockResolvedValue([]), + getGroupMembers: jest.fn().mockResolvedValue([]), + getGroupOwners: jest.fn().mockResolvedValue([]), +})); + +jest.mock('~/config', () => ({ + logger: { error: jest.fn() }, +})); + +let mongoServer; +let methods; +let SystemGrant; + +beforeAll(async () => { + mongoServer = await MongoMemoryServer.create(); + await mongoose.connect(mongoServer.getUri()); + + createModels(mongoose); + const dbModels = require('~/db/models'); + Object.assign(mongoose.models, dbModels); + SystemGrant = dbModels.SystemGrant; + + methods = createMethods(mongoose, { + matchModelName: () => null, + findMatchingPattern: () => null, + getCache: () => ({ + get: async () => null, + set: async () => {}, + }), + }); +}); + +afterAll(async () => { + await mongoose.disconnect(); + await mongoServer.stop(); +}); + +beforeEach(async () => { + await SystemGrant.deleteMany({}); +}); + +describe('SystemGrant methods', () => { + describe('seedSystemGrants', () => { + it('seeds all capabilities for the ADMIN role', async () => { + await methods.seedSystemGrants(); + + const grants = await SystemGrant.find({ + principalType: PrincipalType.ROLE, + principalId: SystemRoles.ADMIN, + }).lean(); + + const expectedCount = Object.values(SystemCapabilities).length; + expect(grants).toHaveLength(expectedCount); + + const capabilities = grants.map((g) => g.capability).sort(); + const expected = Object.values(SystemCapabilities).sort(); + expect(capabilities).toEqual(expected); + }); + + it('is idempotent — calling twice does not duplicate grants', async () => { + await methods.seedSystemGrants(); + await methods.seedSystemGrants(); + + const count = await SystemGrant.countDocuments({ + principalType: PrincipalType.ROLE, + principalId: SystemRoles.ADMIN, + }); + + expect(count).toBe(Object.values(SystemCapabilities).length); + }); + + it('seeds grants with no tenantId', async () => { + await methods.seedSystemGrants(); + + const withTenant = await SystemGrant.countDocuments({ + principalType: PrincipalType.ROLE, + principalId: SystemRoles.ADMIN, + tenantId: { $exists: true }, + }); + + expect(withTenant).toBe(0); + }); + }); + + describe('grantCapability / revokeCapability', () => { + it('grants a capability to a user', async () => { + const userId = new mongoose.Types.ObjectId(); + + await methods.grantCapability({ + principalType: PrincipalType.USER, + principalId: userId, + capability: SystemCapabilities.READ_USERS, + }); + + const grant = await SystemGrant.findOne({ + principalType: PrincipalType.USER, + principalId: userId, + capability: SystemCapabilities.READ_USERS, + }).lean(); + + expect(grant).toBeTruthy(); + expect(grant.grantedAt).toBeInstanceOf(Date); + }); + + it('upsert does not create duplicates', async () => { + const userId = new mongoose.Types.ObjectId(); + + await methods.grantCapability({ + principalType: PrincipalType.USER, + principalId: userId, + capability: SystemCapabilities.READ_USERS, + }); + + await methods.grantCapability({ + principalType: PrincipalType.USER, + principalId: userId, + capability: SystemCapabilities.READ_USERS, + }); + + const count = await SystemGrant.countDocuments({ + principalType: PrincipalType.USER, + principalId: userId, + capability: SystemCapabilities.READ_USERS, + }); + + expect(count).toBe(1); + }); + + it('revokes a capability', async () => { + const userId = new mongoose.Types.ObjectId(); + + await methods.grantCapability({ + principalType: PrincipalType.USER, + principalId: userId, + capability: SystemCapabilities.READ_USERS, + }); + + await methods.revokeCapability({ + principalType: PrincipalType.USER, + principalId: userId, + capability: SystemCapabilities.READ_USERS, + }); + + const grant = await SystemGrant.findOne({ + principalType: PrincipalType.USER, + principalId: userId, + capability: SystemCapabilities.READ_USERS, + }).lean(); + + expect(grant).toBeNull(); + }); + }); + + describe('hasCapabilityForPrincipals', () => { + it('returns true when role principal has the capability', async () => { + await methods.seedSystemGrants(); + + const principals = [ + { principalType: PrincipalType.USER, principalId: new mongoose.Types.ObjectId() }, + { principalType: PrincipalType.ROLE, principalId: SystemRoles.ADMIN }, + { principalType: PrincipalType.PUBLIC }, + ]; + + const result = await methods.hasCapabilityForPrincipals({ + principals, + capability: SystemCapabilities.ACCESS_ADMIN, + }); + + expect(result).toBe(true); + }); + + it('returns false when no principal has the capability', async () => { + const principals = [ + { principalType: PrincipalType.USER, principalId: new mongoose.Types.ObjectId() }, + { principalType: PrincipalType.ROLE, principalId: SystemRoles.USER }, + { principalType: PrincipalType.PUBLIC }, + ]; + + const result = await methods.hasCapabilityForPrincipals({ + principals, + capability: SystemCapabilities.ACCESS_ADMIN, + }); + + expect(result).toBe(false); + }); + + it('returns false for an empty principals list', async () => { + const result = await methods.hasCapabilityForPrincipals({ + principals: [], + capability: SystemCapabilities.ACCESS_ADMIN, + }); + + expect(result).toBe(false); + }); + + it('ignores PUBLIC principals', async () => { + const result = await methods.hasCapabilityForPrincipals({ + principals: [{ principalType: PrincipalType.PUBLIC }], + capability: SystemCapabilities.ACCESS_ADMIN, + }); + + expect(result).toBe(false); + }); + + it('matches user-level grants', async () => { + const userId = new mongoose.Types.ObjectId(); + + await methods.grantCapability({ + principalType: PrincipalType.USER, + principalId: userId, + capability: SystemCapabilities.READ_CONFIGS, + }); + + const principals = [ + { principalType: PrincipalType.USER, principalId: userId }, + { principalType: PrincipalType.ROLE, principalId: SystemRoles.USER }, + { principalType: PrincipalType.PUBLIC }, + ]; + + const result = await methods.hasCapabilityForPrincipals({ + principals, + capability: SystemCapabilities.READ_CONFIGS, + }); + + expect(result).toBe(true); + }); + + it('matches group-level grants', async () => { + const groupId = new mongoose.Types.ObjectId(); + + await methods.grantCapability({ + principalType: PrincipalType.GROUP, + principalId: groupId, + capability: SystemCapabilities.READ_USAGE, + }); + + const principals = [ + { principalType: PrincipalType.USER, principalId: new mongoose.Types.ObjectId() }, + { principalType: PrincipalType.GROUP, principalId: groupId }, + { principalType: PrincipalType.PUBLIC }, + ]; + + const result = await methods.hasCapabilityForPrincipals({ + principals, + capability: SystemCapabilities.READ_USAGE, + }); + + expect(result).toBe(true); + }); + }); + + describe('getCapabilitiesForPrincipal', () => { + it('lists all capabilities for a principal', async () => { + await methods.seedSystemGrants(); + + const grants = await methods.getCapabilitiesForPrincipal({ + principalType: PrincipalType.ROLE, + principalId: SystemRoles.ADMIN, + }); + + expect(grants).toHaveLength(Object.values(SystemCapabilities).length); + }); + + it('returns empty array for a principal with no grants', async () => { + const grants = await methods.getCapabilitiesForPrincipal({ + principalType: PrincipalType.ROLE, + principalId: SystemRoles.USER, + }); + + expect(grants).toHaveLength(0); + }); + }); + + describe('principalId normalization', () => { + it('grant with string userId is found by hasCapabilityForPrincipals with ObjectId', async () => { + const userId = new mongoose.Types.ObjectId(); + + await methods.grantCapability({ + principalType: PrincipalType.USER, + principalId: userId.toString(), // string input + capability: SystemCapabilities.READ_USAGE, + }); + + const result = await methods.hasCapabilityForPrincipals({ + principals: [{ principalType: PrincipalType.USER, principalId: userId }], // ObjectId input + capability: SystemCapabilities.READ_USAGE, + }); + + expect(result).toBe(true); + }); + + it('revoke with string userId removes the grant stored as ObjectId', async () => { + const userId = new mongoose.Types.ObjectId(); + + await methods.grantCapability({ + principalType: PrincipalType.USER, + principalId: userId.toString(), + capability: SystemCapabilities.READ_USAGE, + }); + + await methods.revokeCapability({ + principalType: PrincipalType.USER, + principalId: userId.toString(), // string revoke + capability: SystemCapabilities.READ_USAGE, + }); + + const result = await methods.hasCapabilityForPrincipals({ + principals: [{ principalType: PrincipalType.USER, principalId: userId }], + capability: SystemCapabilities.READ_USAGE, + }); + + expect(result).toBe(false); + }); + + it('getCapabilitiesForPrincipal with string userId returns grants stored as ObjectId', async () => { + const userId = new mongoose.Types.ObjectId(); + + await methods.grantCapability({ + principalType: PrincipalType.USER, + principalId: userId.toString(), + capability: SystemCapabilities.READ_USAGE, + }); + + const grants = await methods.getCapabilitiesForPrincipal({ + principalType: PrincipalType.USER, + principalId: userId.toString(), // string lookup + }); + + expect(grants).toHaveLength(1); + expect(grants[0].capability).toBe(SystemCapabilities.READ_USAGE); + }); + }); + + describe('tenant scoping', () => { + it('tenant-scoped grant does not match platform-level query', async () => { + const userId = new mongoose.Types.ObjectId(); + + await methods.grantCapability({ + principalType: PrincipalType.USER, + principalId: userId, + capability: SystemCapabilities.READ_CONFIGS, + tenantId: 'tenant-1', + }); + + const result = await methods.hasCapabilityForPrincipals({ + principals: [{ principalType: PrincipalType.USER, principalId: userId }], + capability: SystemCapabilities.READ_CONFIGS, + }); + + expect(result).toBe(false); + }); + + it('tenant-scoped grant matches same-tenant query', async () => { + const userId = new mongoose.Types.ObjectId(); + + await methods.grantCapability({ + principalType: PrincipalType.USER, + principalId: userId, + capability: SystemCapabilities.READ_CONFIGS, + tenantId: 'tenant-1', + }); + + const result = await methods.hasCapabilityForPrincipals({ + principals: [{ principalType: PrincipalType.USER, principalId: userId }], + capability: SystemCapabilities.READ_CONFIGS, + tenantId: 'tenant-1', + }); + + expect(result).toBe(true); + }); + + it('tenant-scoped grant does not match different tenant', async () => { + const userId = new mongoose.Types.ObjectId(); + + await methods.grantCapability({ + principalType: PrincipalType.USER, + principalId: userId, + capability: SystemCapabilities.READ_CONFIGS, + tenantId: 'tenant-1', + }); + + const result = await methods.hasCapabilityForPrincipals({ + principals: [{ principalType: PrincipalType.USER, principalId: userId }], + capability: SystemCapabilities.READ_CONFIGS, + tenantId: 'tenant-2', + }); + + expect(result).toBe(false); + }); + }); +}); 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/__tests__/sendEmail.spec.js b/api/server/utils/__tests__/sendEmail.spec.js new file mode 100644 index 0000000000..5c79094c53 --- /dev/null +++ b/api/server/utils/__tests__/sendEmail.spec.js @@ -0,0 +1,143 @@ +const nodemailer = require('nodemailer'); +const { readFileAsString } = require('@librechat/api'); + +jest.mock('nodemailer'); +jest.mock('@librechat/data-schemas', () => ({ + logger: { debug: jest.fn(), warn: jest.fn(), error: jest.fn() }, +})); +jest.mock('@librechat/api', () => ({ + logAxiosError: jest.fn(), + isEnabled: jest.fn((val) => val === 'true' || val === true), + readFileAsString: jest.fn(), +})); + +const savedEnv = { ...process.env }; + +const mockSendMail = jest.fn().mockResolvedValue({ messageId: 'test-id' }); + +beforeEach(() => { + jest.clearAllMocks(); + process.env = { ...savedEnv }; + process.env.EMAIL_HOST = 'smtp.example.com'; + process.env.EMAIL_PORT = '587'; + process.env.EMAIL_FROM = 'noreply@example.com'; + process.env.APP_TITLE = 'TestApp'; + delete process.env.EMAIL_USERNAME; + delete process.env.EMAIL_PASSWORD; + delete process.env.MAILGUN_API_KEY; + delete process.env.MAILGUN_DOMAIN; + delete process.env.EMAIL_SERVICE; + delete process.env.EMAIL_ENCRYPTION; + delete process.env.EMAIL_ENCRYPTION_HOSTNAME; + delete process.env.EMAIL_ALLOW_SELFSIGNED; + + readFileAsString.mockResolvedValue({ content: '

{{name}}

' }); + nodemailer.createTransport.mockReturnValue({ sendMail: mockSendMail }); +}); + +afterAll(() => { + process.env = savedEnv; +}); + +/** Loads a fresh copy of sendEmail so process.env reads are re-evaluated. */ +function loadSendEmail() { + jest.resetModules(); + jest.mock('nodemailer', () => ({ + createTransport: jest.fn().mockReturnValue({ sendMail: mockSendMail }), + })); + jest.mock('@librechat/data-schemas', () => ({ + logger: { debug: jest.fn(), warn: jest.fn(), error: jest.fn() }, + })); + jest.mock('@librechat/api', () => ({ + logAxiosError: jest.fn(), + isEnabled: jest.fn((val) => val === 'true' || val === true), + readFileAsString: jest.fn().mockResolvedValue({ content: '

{{name}}

' }), + })); + return require('../sendEmail'); +} + +const baseParams = { + email: 'user@example.com', + subject: 'Test', + payload: { name: 'User' }, + template: 'test.handlebars', +}; + +describe('sendEmail SMTP auth assembly', () => { + it('includes auth when both EMAIL_USERNAME and EMAIL_PASSWORD are set', async () => { + process.env.EMAIL_USERNAME = 'smtp_user'; + process.env.EMAIL_PASSWORD = 'smtp_pass'; + const sendEmail = loadSendEmail(); + const { createTransport } = require('nodemailer'); + + await sendEmail(baseParams); + + expect(createTransport).toHaveBeenCalledTimes(1); + const transporterOptions = createTransport.mock.calls[0][0]; + expect(transporterOptions.auth).toEqual({ + user: 'smtp_user', + pass: 'smtp_pass', + }); + }); + + it('omits auth when both EMAIL_USERNAME and EMAIL_PASSWORD are absent', async () => { + const sendEmail = loadSendEmail(); + const { createTransport } = require('nodemailer'); + + await sendEmail(baseParams); + + expect(createTransport).toHaveBeenCalledTimes(1); + const transporterOptions = createTransport.mock.calls[0][0]; + expect(transporterOptions.auth).toBeUndefined(); + }); + + it('omits auth and logs a warning when only EMAIL_USERNAME is set', async () => { + process.env.EMAIL_USERNAME = 'smtp_user'; + const sendEmail = loadSendEmail(); + const { createTransport } = require('nodemailer'); + const { logger: freshLogger } = require('@librechat/data-schemas'); + + await sendEmail(baseParams); + + const transporterOptions = createTransport.mock.calls[0][0]; + expect(transporterOptions.auth).toBeUndefined(); + expect(freshLogger.warn).toHaveBeenCalledWith( + expect.stringContaining('EMAIL_USERNAME and EMAIL_PASSWORD must both be set'), + ); + }); + + it('omits auth and logs a warning when only EMAIL_PASSWORD is set', async () => { + process.env.EMAIL_PASSWORD = 'smtp_pass'; + const sendEmail = loadSendEmail(); + const { createTransport } = require('nodemailer'); + const { logger: freshLogger } = require('@librechat/data-schemas'); + + await sendEmail(baseParams); + + const transporterOptions = createTransport.mock.calls[0][0]; + expect(transporterOptions.auth).toBeUndefined(); + expect(freshLogger.warn).toHaveBeenCalledWith( + expect.stringContaining('EMAIL_USERNAME and EMAIL_PASSWORD must both be set'), + ); + }); + + it('does not log a warning when both credentials are properly set', async () => { + process.env.EMAIL_USERNAME = 'smtp_user'; + process.env.EMAIL_PASSWORD = 'smtp_pass'; + const sendEmail = loadSendEmail(); + const { logger: freshLogger } = require('@librechat/data-schemas'); + + await sendEmail(baseParams); + + expect(freshLogger.warn).not.toHaveBeenCalled(); + }); + + it('does not log a warning when both credentials are absent', async () => { + const sendEmail = loadSendEmail(); + const { logger: freshLogger } = require('@librechat/data-schemas'); + + await sendEmail(baseParams); + + expect(freshLogger.warn).not.toHaveBeenCalled(); + }); +}); diff --git a/api/server/utils/import/fork.js b/api/server/utils/import/fork.js index c4ce8cb5d4..5df4d27af2 100644 --- a/api/server/utils/import/fork.js +++ b/api/server/utils/import/fork.js @@ -3,8 +3,7 @@ const { logger } = require('@librechat/data-schemas'); const { EModelEndpoint, Constants, ForkOptions } = require('librechat-data-provider'); const { createImportBatchBuilder } = require('./importBatchBuilder'); const BaseClient = require('~/app/clients/BaseClient'); -const { getConvo } = require('~/models/Conversation'); -const { getMessages } = require('~/models/Message'); +const { getConvo, getMessages } = require('~/models'); /** * Helper function to clone messages with proper parent-child relationships and timestamps @@ -358,16 +357,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 +381,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/fork.spec.js b/api/server/utils/import/fork.spec.js index 552620dc89..6fd108674a 100644 --- a/api/server/utils/import/fork.spec.js +++ b/api/server/utils/import/fork.spec.js @@ -1,16 +1,10 @@ const { Constants, ForkOptions } = require('librechat-data-provider'); -jest.mock('~/models/Conversation', () => ({ +jest.mock('~/models', () => ({ getConvo: jest.fn(), bulkSaveConvos: jest.fn(), -})); - -jest.mock('~/models/Message', () => ({ getMessages: jest.fn(), bulkSaveMessages: jest.fn(), -})); - -jest.mock('~/models/ConversationTag', () => ({ bulkIncrementTagCounts: jest.fn(), })); @@ -32,9 +26,13 @@ const { getMessagesUpToTargetLevel, cloneMessagesWithTimestamps, } = require('./fork'); -const { bulkIncrementTagCounts } = require('~/models/ConversationTag'); -const { getConvo, bulkSaveConvos } = require('~/models/Conversation'); -const { getMessages, bulkSaveMessages } = require('~/models/Message'); +const { + bulkIncrementTagCounts, + getConvo, + bulkSaveConvos, + getMessages, + bulkSaveMessages, +} = require('~/models'); const { createImportBatchBuilder } = require('./importBatchBuilder'); const BaseClient = require('~/app/clients/BaseClient'); diff --git a/api/server/utils/import/importBatchBuilder.js b/api/server/utils/import/importBatchBuilder.js index 5e499043d2..29fbfa85a2 100644 --- a/api/server/utils/import/importBatchBuilder.js +++ b/api/server/utils/import/importBatchBuilder.js @@ -1,9 +1,7 @@ const { v4: uuidv4 } = require('uuid'); const { logger } = require('@librechat/data-schemas'); const { EModelEndpoint, Constants, openAISettings } = require('librechat-data-provider'); -const { bulkIncrementTagCounts } = require('~/models/ConversationTag'); -const { bulkSaveConvos } = require('~/models/Conversation'); -const { bulkSaveMessages } = require('~/models/Message'); +const { bulkIncrementTagCounts, bulkSaveConvos, bulkSaveMessages } = require('~/models'); /** * Factory function for creating an instance of ImportBatchBuilder. 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-timestamp.spec.js b/api/server/utils/import/importers-timestamp.spec.js index c7665dfe25..09021a9ccd 100644 --- a/api/server/utils/import/importers-timestamp.spec.js +++ b/api/server/utils/import/importers-timestamp.spec.js @@ -1,12 +1,11 @@ +const { logger } = require('@librechat/data-schemas'); const { Constants } = require('librechat-data-provider'); const { ImportBatchBuilder } = require('./importBatchBuilder'); const { getImporter } = require('./importers'); // Mock the database methods -jest.mock('~/models/Conversation', () => ({ +jest.mock('~/models', () => ({ bulkSaveConvos: jest.fn(), -})); -jest.mock('~/models/Message', () => ({ bulkSaveMessages: jest.fn(), })); jest.mock('~/cache/getLogStores'); @@ -368,6 +367,133 @@ describe('Import Timestamp Ordering', () => { new Date(nullTimeMsg.createdAt).getTime(), ); }); + + test('should terminate on cyclic parent relationships and break cycles before saving', async () => { + const warnSpy = jest.spyOn(logger, 'warn'); + const jsonData = [ + { + title: 'Cycle Test', + create_time: 1700000000, + mapping: { + 'root-node': { + id: 'root-node', + message: null, + parent: null, + children: ['message-a'], + }, + 'message-a': { + id: 'message-a', + message: { + id: 'message-a', + author: { role: 'user' }, + create_time: 1700000000, + content: { content_type: 'text', parts: ['Message A'] }, + metadata: {}, + }, + parent: 'message-b', + children: ['message-b'], + }, + 'message-b': { + id: 'message-b', + message: { + id: 'message-b', + author: { role: 'assistant' }, + create_time: 1700000000, + content: { content_type: 'text', parts: ['Message B'] }, + metadata: {}, + }, + parent: 'message-a', + children: ['message-a'], + }, + }, + }, + ]; + + const requestUserId = 'user-123'; + const importBatchBuilder = new ImportBatchBuilder(requestUserId); + + const importer = getImporter(jsonData); + await importer(jsonData, requestUserId, () => importBatchBuilder); + + const { messages } = importBatchBuilder; + expect(messages).toHaveLength(2); + + const msgA = messages.find((m) => m.text === 'Message A'); + const msgB = messages.find((m) => m.text === 'Message B'); + expect(msgA).toBeDefined(); + expect(msgB).toBeDefined(); + + const roots = messages.filter((m) => m.parentMessageId === Constants.NO_PARENT); + expect(roots).toHaveLength(1); + + const [root] = roots; + const nonRoot = messages.find((m) => m.parentMessageId !== Constants.NO_PARENT); + expect(nonRoot.parentMessageId).toBe(root.messageId); + + expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('cyclic parent relationships')); + warnSpy.mockRestore(); + }); + + test('should not hang when findValidParent encounters a skippable-message cycle', async () => { + const jsonData = [ + { + title: 'Skippable Cycle Test', + create_time: 1700000000, + mapping: { + 'root-node': { + id: 'root-node', + message: null, + parent: null, + children: ['real-msg'], + }, + 'sys-a': { + id: 'sys-a', + message: { + id: 'sys-a', + author: { role: 'system' }, + create_time: 1700000000, + content: { content_type: 'text', parts: ['system a'] }, + metadata: {}, + }, + parent: 'sys-b', + children: ['real-msg'], + }, + 'sys-b': { + id: 'sys-b', + message: { + id: 'sys-b', + author: { role: 'system' }, + create_time: 1700000000, + content: { content_type: 'text', parts: ['system b'] }, + metadata: {}, + }, + parent: 'sys-a', + children: [], + }, + 'real-msg': { + id: 'real-msg', + message: { + id: 'real-msg', + author: { role: 'user' }, + create_time: 1700000001, + content: { content_type: 'text', parts: ['Hello'] }, + metadata: {}, + }, + parent: 'sys-a', + children: [], + }, + }, + }, + ]; + + const importBatchBuilder = new ImportBatchBuilder('user-123'); + const importer = getImporter(jsonData); + await importer(jsonData, 'user-123', () => importBatchBuilder); + + const realMsg = importBatchBuilder.messages.find((m) => m.text === 'Hello'); + expect(realMsg).toBeDefined(); + expect(realMsg.parentMessageId).toBe(Constants.NO_PARENT); + }); }); describe('Comparison with Fork Functionality', () => { diff --git a/api/server/utils/import/importers.js b/api/server/utils/import/importers.js index 81a0f048df..39734c181c 100644 --- a/api/server/utils/import/importers.js +++ b/api/server/utils/import/importers.js @@ -324,32 +324,42 @@ function processConversation(conv, importBatchBuilder, requestUserId) { } /** - * Helper function to find the nearest valid parent (skips system, reasoning_recap, and thoughts messages) - * @param {string} parentId - The ID of the parent message. + * Finds the nearest valid parent by traversing up through skippable messages + * (system, reasoning_recap, thoughts). Uses iterative traversal to avoid + * stack overflow on deep chains of skippable messages. + * + * @param {string} startId - The ID of the starting parent message. * @returns {string} The ID of the nearest valid parent message. */ - const findValidParent = (parentId) => { - if (!parentId || !messageMap.has(parentId)) { - return Constants.NO_PARENT; + const findValidParent = (startId) => { + const visited = new Set(); + let parentId = startId; + + while (parentId) { + if (!messageMap.has(parentId) || visited.has(parentId)) { + return Constants.NO_PARENT; + } + visited.add(parentId); + + const parentMapping = conv.mapping[parentId]; + if (!parentMapping?.message) { + return Constants.NO_PARENT; + } + + const contentType = parentMapping.message.content?.content_type; + const shouldSkip = + parentMapping.message.author?.role === 'system' || + contentType === 'reasoning_recap' || + contentType === 'thoughts'; + + if (!shouldSkip) { + return messageMap.get(parentId); + } + + parentId = parentMapping.parent; } - const parentMapping = conv.mapping[parentId]; - if (!parentMapping?.message) { - return Constants.NO_PARENT; - } - - /* If parent is a system message, reasoning_recap, or thoughts, traverse up to find the nearest valid parent */ - const contentType = parentMapping.message.content?.content_type; - const shouldSkip = - parentMapping.message.author?.role === 'system' || - contentType === 'reasoning_recap' || - contentType === 'thoughts'; - - if (shouldSkip) { - return findValidParent(parentMapping.parent); - } - - return messageMap.get(parentId); + return Constants.NO_PARENT; }; /** @@ -466,7 +476,10 @@ function processConversation(conv, importBatchBuilder, requestUserId) { messages.push(message); } - adjustTimestampsForOrdering(messages); + const cycleDetected = adjustTimestampsForOrdering(messages); + if (cycleDetected) { + breakParentCycles(messages); + } for (const message of messages) { importBatchBuilder.saveMessage(message); @@ -553,21 +566,30 @@ function formatMessageText(messageData) { * Messages are sorted by createdAt and buildTree expects parents to appear before children. * ChatGPT exports can have slight timestamp inversions (e.g., tool call results * arriving a few ms before their parent). Uses multiple passes to handle cascading adjustments. + * Capped at N passes (where N = message count) to guarantee termination on cyclic graphs. * * @param {Array} messages - Array of message objects with messageId, parentMessageId, and createdAt. + * @returns {boolean} True if cyclic parent relationships were detected. */ function adjustTimestampsForOrdering(messages) { + if (messages.length === 0) { + return false; + } + const timestampMap = new Map(); - messages.forEach((msg) => timestampMap.set(msg.messageId, msg.createdAt)); + for (const msg of messages) { + timestampMap.set(msg.messageId, msg.createdAt); + } let hasChanges = true; - while (hasChanges) { + let remainingPasses = messages.length; + while (hasChanges && remainingPasses > 0) { hasChanges = false; + remainingPasses--; for (const message of messages) { if (message.parentMessageId && message.parentMessageId !== Constants.NO_PARENT) { const parentTimestamp = timestampMap.get(message.parentMessageId); if (parentTimestamp && message.createdAt <= parentTimestamp) { - // Bump child timestamp to 1ms after parent message.createdAt = new Date(parentTimestamp.getTime() + 1); timestampMap.set(message.messageId, message.createdAt); hasChanges = true; @@ -575,6 +597,49 @@ function adjustTimestampsForOrdering(messages) { } } } + + const cycleDetected = remainingPasses === 0 && hasChanges; + if (cycleDetected) { + logger.warn( + '[importers] Detected cyclic parent relationships while adjusting import timestamps', + ); + } + return cycleDetected; +} + +/** + * Severs cyclic parentMessageId back-edges so saved messages form a valid tree. + * Walks each message's parent chain; if a message is visited twice, its parentMessageId + * is set to NO_PARENT to break the cycle. + * + * @param {Array} messages - Array of message objects with messageId and parentMessageId. + */ +function breakParentCycles(messages) { + const parentLookup = new Map(); + for (const msg of messages) { + parentLookup.set(msg.messageId, msg); + } + + const settled = new Set(); + for (const message of messages) { + const chain = new Set(); + let current = message; + while (current && !settled.has(current.messageId)) { + if (chain.has(current.messageId)) { + current.parentMessageId = Constants.NO_PARENT; + break; + } + chain.add(current.messageId); + const parentId = current.parentMessageId; + if (!parentId || parentId === Constants.NO_PARENT) { + break; + } + current = parentLookup.get(parentId); + } + for (const id of chain) { + settled.add(id); + } + } } module.exports = { getImporter, processAssistantMessage }; diff --git a/api/server/utils/import/importers.spec.js b/api/server/utils/import/importers.spec.js index 2ddfa76658..7984144cbc 100644 --- a/api/server/utils/import/importers.spec.js +++ b/api/server/utils/import/importers.spec.js @@ -1,10 +1,9 @@ const fs = require('fs'); const path = require('path'); const { EModelEndpoint, Constants, openAISettings } = require('librechat-data-provider'); -const { bulkSaveConvos: _bulkSaveConvos } = require('~/models/Conversation'); const { getImporter, processAssistantMessage } = require('./importers'); const { ImportBatchBuilder } = require('./importBatchBuilder'); -const { bulkSaveMessages } = require('~/models/Message'); +const { bulkSaveMessages, bulkSaveConvos: _bulkSaveConvos } = require('~/models'); const getLogStores = require('~/cache/getLogStores'); jest.mock('~/cache/getLogStores'); @@ -14,10 +13,8 @@ getLogStores.mockImplementation(() => ({ })); // Mock the database methods -jest.mock('~/models/Conversation', () => ({ +jest.mock('~/models', () => ({ bulkSaveConvos: jest.fn(), -})); -jest.mock('~/models/Message', () => ({ bulkSaveMessages: jest.fn(), })); diff --git a/api/server/utils/index.js b/api/server/utils/index.js index 918ab54f85..59cb71625f 100644 --- a/api/server/utils/index.js +++ b/api/server/utils/index.js @@ -1,4 +1,3 @@ -const removePorts = require('./removePorts'); const handleText = require('./handleText'); const sendEmail = require('./sendEmail'); const queue = require('./queue'); @@ -6,7 +5,6 @@ const files = require('./files'); module.exports = { ...handleText, - removePorts, sendEmail, ...files, ...queue, diff --git a/api/server/utils/removePorts.js b/api/server/utils/removePorts.js deleted file mode 100644 index 375ff1cc71..0000000000 --- a/api/server/utils/removePorts.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = (req) => req?.ip?.replace(/:\d+[^:]*$/, ''); diff --git a/api/server/utils/sendEmail.js b/api/server/utils/sendEmail.js index 432a571ffb..3fa3e6fcba 100644 --- a/api/server/utils/sendEmail.js +++ b/api/server/utils/sendEmail.js @@ -124,11 +124,20 @@ const sendEmail = async ({ email, subject, payload, template, throwError = true // Whether to accept unsigned certificates rejectUnauthorized: !isEnabled(process.env.EMAIL_ALLOW_SELFSIGNED), }, - auth: { + }; + + const hasUsername = !!process.env.EMAIL_USERNAME; + const hasPassword = !!process.env.EMAIL_PASSWORD; + if (hasUsername && hasPassword) { + transporterOptions.auth = { user: process.env.EMAIL_USERNAME, pass: process.env.EMAIL_PASSWORD, - }, - }; + }; + } else if (hasUsername !== hasPassword) { + logger.warn( + '[sendEmail] EMAIL_USERNAME and EMAIL_PASSWORD must both be set for authenticated SMTP, or both omitted for unauthenticated SMTP. Proceeding without authentication.', + ); + } if (process.env.EMAIL_ENCRYPTION_HOSTNAME) { // Check the certificate against this name explicitly diff --git a/api/strategies/localStrategy.js b/api/strategies/localStrategy.js index 0d220ead25..5d725c0907 100644 --- a/api/strategies/localStrategy.js +++ b/api/strategies/localStrategy.js @@ -1,8 +1,9 @@ +const bcrypt = require('bcryptjs'); const { logger } = require('@librechat/data-schemas'); const { errorsToString } = require('librechat-data-provider'); -const { isEnabled, checkEmailConfig } = require('@librechat/api'); const { Strategy: PassportLocalStrategy } = require('passport-local'); -const { findUser, comparePassword, updateUser } = require('~/models'); +const { isEnabled, checkEmailConfig, comparePassword } = require('@librechat/api'); +const { findUser, updateUser } = require('~/models'); const { loginSchema } = require('./validators'); // Unix timestamp for 2024-06-07 15:20:18 Eastern Time @@ -35,7 +36,7 @@ async function passportLogin(req, email, password, done) { return done(null, false, { message: 'Email does not exist.' }); } - const isMatch = await comparePassword(user, password); + const isMatch = await comparePassword(user, password, { compare: bcrypt.compare }); if (!isMatch) { logError('Passport Local Strategy - Password does not match', { isMatch }); logger.error(`[Login] [Login failed] [Username: ${email}] [Request-IP: ${req.ip}]`); diff --git a/api/strategies/openIdJwtStrategy.spec.js b/api/strategies/openIdJwtStrategy.spec.js index 79af848046..fd710f1ebd 100644 --- a/api/strategies/openIdJwtStrategy.spec.js +++ b/api/strategies/openIdJwtStrategy.spec.js @@ -271,6 +271,32 @@ describe('openIdJwtStrategy – OPENID_EMAIL_CLAIM', () => { expect(user).toBe(false); }); + it('should reject login when email fallback finds user with mismatched openidId', async () => { + const emailMatchWithDifferentSub = { + _id: 'user-id-2', + provider: 'openid', + openidId: 'different-sub', + email: payload.email, + role: SystemRoles.USER, + }; + + findUser.mockImplementation(async (query) => { + if (query.$or) { + return null; + } + if (query.email === payload.email) { + return emailMatchWithDifferentSub; + } + return null; + }); + + const req = { headers: { authorization: 'Bearer tok' }, session: {} }; + const { user, info } = await invokeVerify(req, payload); + + expect(user).toBe(false); + expect(info).toEqual({ message: 'auth_failed' }); + }); + it('should trim whitespace from OPENID_EMAIL_CLAIM', async () => { process.env.OPENID_EMAIL_CLAIM = ' upn '; findUser.mockResolvedValue(null); diff --git a/api/strategies/openidStrategy.js b/api/strategies/openidStrategy.js index 0ebdcb04e1..7c43358297 100644 --- a/api/strategies/openidStrategy.js +++ b/api/strategies/openidStrategy.js @@ -315,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'; @@ -344,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 }), @@ -364,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( @@ -432,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(',') @@ -451,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; } } @@ -550,7 +616,25 @@ async function processOpenIDAuth(tokenset, existingUsersOnly = false) { throw new Error('Invalid admin role token kind'); } - const adminRoles = get(adminRoleObject, adminRoleParameterPath); + let adminRoles = get(adminRoleObject, adminRoleParameterPath); + + // 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; diff --git a/api/strategies/openidStrategy.spec.js b/api/strategies/openidStrategy.spec.js index 485b77829e..4436fab672 100644 --- a/api/strategies/openidStrategy.spec.js +++ b/api/strategies/openidStrategy.spec.js @@ -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'), }; }); @@ -352,6 +356,33 @@ describe('setupOpenId', () => { expect(updateUser).not.toHaveBeenCalled(); }); + it('should block login when email fallback finds user with mismatched openidId', async () => { + const existingUser = { + _id: 'existingUserId', + provider: 'openid', + openidId: 'different-sub-claim', + email: tokenset.claims().email, + username: 'existinguser', + name: 'Existing User', + }; + findUser.mockImplementation(async (query) => { + if (query.$or) { + return null; + } + if (query.email === tokenset.claims().email) { + return existingUser; + } + return null; + }); + + const result = await validate(tokenset); + + expect(result.user).toBe(false); + expect(result.details.message).toBe(ErrorTypes.AUTH_FAILED); + expect(createUser).not.toHaveBeenCalled(); + expect(updateUser).not.toHaveBeenCalled(); + }); + it('should enforce the required role and reject login if missing', async () => { // Arrange – simulate a token without the required role. jwtDecode.mockReturnValue({ @@ -730,7 +761,7 @@ describe('setupOpenId', () => { expect.objectContaining({ method: 'POST', headers: expect.objectContaining({ - Authorization: `Bearer ${tokenset.access_token}`, + Authorization: 'Bearer exchanged_graph_token', }), }), ); @@ -745,6 +776,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); 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/server/middleware/checkBan.test.js b/api/test/server/middleware/checkBan.test.js new file mode 100644 index 0000000000..518153be67 --- /dev/null +++ b/api/test/server/middleware/checkBan.test.js @@ -0,0 +1,426 @@ +const mockBanCacheGet = jest.fn().mockResolvedValue(undefined); +const mockBanCacheSet = jest.fn().mockResolvedValue(undefined); + +jest.mock('keyv', () => ({ + Keyv: jest.fn().mockImplementation(() => ({ + get: mockBanCacheGet, + set: mockBanCacheSet, + })), +})); + +const mockBanLogsGet = jest.fn().mockResolvedValue(undefined); +const mockBanLogsDelete = jest.fn().mockResolvedValue(true); +const mockBanLogs = { + get: mockBanLogsGet, + delete: mockBanLogsDelete, + opts: { ttl: 7200000 }, +}; + +jest.mock('~/cache', () => ({ + getLogStores: jest.fn(() => mockBanLogs), +})); + +jest.mock('@librechat/data-schemas', () => ({ + logger: { + info: jest.fn(), + warn: jest.fn(), + debug: jest.fn(), + error: jest.fn(), + }, +})); + +jest.mock('@librechat/api', () => ({ + isEnabled: (value) => { + if (typeof value === 'boolean') { + return value; + } + if (typeof value === 'string') { + return value.toLowerCase().trim() === 'true'; + } + return false; + }, + keyvMongo: {}, + removePorts: jest.fn((req) => req.ip), +})); + +jest.mock('~/models', () => ({ + findUser: jest.fn(), +})); + +jest.mock('~/server/middleware/denyRequest', () => jest.fn().mockResolvedValue(undefined)); + +jest.mock('ua-parser-js', () => jest.fn(() => ({ browser: { name: 'Chrome' } }))); + +const checkBan = require('~/server/middleware/checkBan'); +const { logger } = require('@librechat/data-schemas'); +const { findUser } = require('~/models'); + +const createReq = (overrides = {}) => ({ + ip: '192.168.1.1', + user: { id: 'user123' }, + headers: { 'user-agent': 'Mozilla/5.0' }, + body: {}, + baseUrl: '/api', + originalUrl: '/api/test', + ...overrides, +}); + +const createRes = () => ({ + status: jest.fn().mockReturnThis(), + json: jest.fn().mockReturnThis(), +}); + +describe('checkBan middleware', () => { + let originalEnv; + + beforeEach(() => { + originalEnv = { ...process.env }; + process.env.BAN_VIOLATIONS = 'true'; + delete process.env.USE_REDIS; + mockBanLogs.opts.ttl = 7200000; + }); + + afterEach(() => { + process.env = originalEnv; + jest.clearAllMocks(); + }); + + describe('early exits', () => { + it('calls next() when BAN_VIOLATIONS is disabled', async () => { + process.env.BAN_VIOLATIONS = 'false'; + const next = jest.fn(); + + await checkBan(createReq(), createRes(), next); + + expect(next).toHaveBeenCalledWith(); + expect(mockBanCacheGet).not.toHaveBeenCalled(); + }); + + it('calls next() when BAN_VIOLATIONS is unset', async () => { + delete process.env.BAN_VIOLATIONS; + const next = jest.fn(); + + await checkBan(createReq(), createRes(), next); + + expect(next).toHaveBeenCalledWith(); + }); + + it('calls next() when neither userId nor IP is available', async () => { + const next = jest.fn(); + const req = createReq({ ip: null, user: null }); + + await checkBan(req, createRes(), next); + + expect(next).toHaveBeenCalledWith(); + }); + + it('calls next() when ban duration is <= 0', async () => { + mockBanLogs.opts.ttl = 0; + const next = jest.fn(); + + await checkBan(createReq(), createRes(), next); + + expect(next).toHaveBeenCalledWith(); + }); + + it('calls next() when no ban exists in cache or DB', async () => { + const next = jest.fn(); + + await checkBan(createReq(), createRes(), next); + + expect(next).toHaveBeenCalledWith(); + expect(mockBanCacheGet).toHaveBeenCalled(); + expect(mockBanLogsGet).toHaveBeenCalled(); + }); + }); + + describe('cache hit path', () => { + it('returns 403 when IP ban is cached', async () => { + mockBanCacheGet.mockResolvedValueOnce({ expiresAt: Date.now() + 60000 }); + const next = jest.fn(); + const req = createReq(); + const res = createRes(); + + await checkBan(req, res, next); + + expect(next).not.toHaveBeenCalled(); + expect(req.banned).toBe(true); + expect(res.status).toHaveBeenCalledWith(403); + }); + + it('returns 403 when user ban is cached (IP miss)', async () => { + mockBanCacheGet + .mockResolvedValueOnce(undefined) + .mockResolvedValueOnce({ expiresAt: Date.now() + 60000 }); + const next = jest.fn(); + const req = createReq(); + const res = createRes(); + + await checkBan(req, res, next); + + expect(next).not.toHaveBeenCalled(); + expect(req.banned).toBe(true); + expect(res.status).toHaveBeenCalledWith(403); + }); + + it('does not query banLogs when cache hit occurs', async () => { + mockBanCacheGet.mockResolvedValueOnce({ expiresAt: Date.now() + 60000 }); + + await checkBan(createReq(), createRes(), jest.fn()); + + expect(mockBanLogsGet).not.toHaveBeenCalled(); + }); + }); + + describe('active ban (positive timeLeft)', () => { + it('caches ban with correct TTL and returns 403', async () => { + const expiresAt = Date.now() + 3600000; + const banRecord = { expiresAt, type: 'ban', violation_count: 3 }; + mockBanLogsGet.mockResolvedValueOnce(banRecord); + const next = jest.fn(); + const req = createReq(); + const res = createRes(); + + await checkBan(req, res, next); + + expect(next).not.toHaveBeenCalled(); + expect(req.banned).toBe(true); + expect(res.status).toHaveBeenCalledWith(403); + expect(mockBanCacheSet).toHaveBeenCalledTimes(2); + + const [ipCacheCall, userCacheCall] = mockBanCacheSet.mock.calls; + expect(ipCacheCall[0]).toBe('192.168.1.1'); + expect(ipCacheCall[1]).toBe(banRecord); + expect(ipCacheCall[2]).toBeGreaterThan(0); + expect(ipCacheCall[2]).toBeLessThanOrEqual(3600000); + + expect(userCacheCall[0]).toBe('user123'); + expect(userCacheCall[1]).toBe(banRecord); + }); + + it('caches only IP when no userId is present', async () => { + const expiresAt = Date.now() + 3600000; + mockBanLogsGet.mockResolvedValueOnce({ expiresAt, type: 'ban' }); + const req = createReq({ user: null }); + + await checkBan(req, createRes(), jest.fn()); + + expect(mockBanCacheSet).toHaveBeenCalledTimes(1); + expect(mockBanCacheSet).toHaveBeenCalledWith( + '192.168.1.1', + expect.any(Object), + expect.any(Number), + ); + }); + }); + + describe('expired ban cleanup', () => { + it('cleans up and calls next() for expired user-key ban', async () => { + const expiresAt = Date.now() - 1000; + mockBanLogsGet + .mockResolvedValueOnce(undefined) + .mockResolvedValueOnce({ expiresAt, type: 'ban' }); + const next = jest.fn(); + const req = createReq(); + + await checkBan(req, createRes(), next); + + expect(next).toHaveBeenCalledWith(); + expect(req.banned).toBeUndefined(); + expect(mockBanLogsDelete).toHaveBeenCalledWith('user123'); + expect(mockBanCacheSet).not.toHaveBeenCalled(); + }); + + it('cleans up and calls next() for expired IP-only ban (Finding 1 regression)', async () => { + const expiresAt = Date.now() - 1000; + mockBanLogsGet.mockResolvedValueOnce({ expiresAt, type: 'ban' }); + const next = jest.fn(); + const req = createReq({ user: null }); + + await checkBan(req, createRes(), next); + + expect(next).toHaveBeenCalledWith(); + expect(req.banned).toBeUndefined(); + expect(mockBanLogsDelete).toHaveBeenCalledWith('192.168.1.1'); + expect(mockBanCacheSet).not.toHaveBeenCalled(); + }); + + it('cleans up both IP and user bans when both are expired', async () => { + const expiresAt = Date.now() - 1000; + mockBanLogsGet + .mockResolvedValueOnce({ expiresAt, type: 'ban' }) + .mockResolvedValueOnce({ expiresAt, type: 'ban' }); + const next = jest.fn(); + + await checkBan(createReq(), createRes(), next); + + expect(next).toHaveBeenCalledWith(); + expect(mockBanLogsDelete).toHaveBeenCalledTimes(2); + expect(mockBanLogsDelete).toHaveBeenCalledWith('192.168.1.1'); + expect(mockBanLogsDelete).toHaveBeenCalledWith('user123'); + }); + + it('does not write to banCache when ban is expired', async () => { + const expiresAt = Date.now() - 60000; + mockBanLogsGet.mockResolvedValueOnce({ expiresAt, type: 'ban' }); + + await checkBan(createReq({ user: null }), createRes(), jest.fn()); + + expect(mockBanCacheSet).not.toHaveBeenCalled(); + }); + }); + + describe('Redis key paths (Finding 2 regression)', () => { + beforeEach(() => { + process.env.USE_REDIS = 'true'; + }); + + it('uses cache-prefixed keys for banCache.get', async () => { + await checkBan(createReq(), createRes(), jest.fn()); + + expect(mockBanCacheGet).toHaveBeenCalledWith('ban_cache:ip:192.168.1.1'); + expect(mockBanCacheGet).toHaveBeenCalledWith('ban_cache:user:user123'); + }); + + it('uses raw keys (not cache-prefixed) for banLogs.delete on cleanup', async () => { + const expiresAt = Date.now() - 1000; + mockBanLogsGet + .mockResolvedValueOnce({ expiresAt, type: 'ban' }) + .mockResolvedValueOnce({ expiresAt, type: 'ban' }); + + await checkBan(createReq(), createRes(), jest.fn()); + + expect(mockBanLogsDelete).toHaveBeenCalledWith('192.168.1.1'); + expect(mockBanLogsDelete).toHaveBeenCalledWith('user123'); + for (const call of mockBanLogsDelete.mock.calls) { + expect(call[0]).not.toMatch(/^ban_cache:/); + } + }); + + it('uses cache-prefixed keys for banCache.set on active ban', async () => { + const expiresAt = Date.now() + 3600000; + mockBanLogsGet.mockResolvedValueOnce({ expiresAt, type: 'ban' }); + + await checkBan(createReq(), createRes(), jest.fn()); + + expect(mockBanCacheSet).toHaveBeenCalledWith( + 'ban_cache:ip:192.168.1.1', + expect.any(Object), + expect.any(Number), + ); + expect(mockBanCacheSet).toHaveBeenCalledWith( + 'ban_cache:user:user123', + expect.any(Object), + expect.any(Number), + ); + }); + }); + + describe('missing expiresAt guard (Finding 5)', () => { + it('returns 403 without caching when expiresAt is missing', async () => { + mockBanLogsGet.mockResolvedValueOnce({ type: 'ban' }); + const next = jest.fn(); + const req = createReq(); + const res = createRes(); + + await checkBan(req, res, next); + + expect(next).not.toHaveBeenCalled(); + expect(req.banned).toBe(true); + expect(res.status).toHaveBeenCalledWith(403); + expect(mockBanCacheSet).not.toHaveBeenCalled(); + }); + + it('returns 403 without caching when expiresAt is NaN-producing', async () => { + mockBanLogsGet.mockResolvedValueOnce({ type: 'ban', expiresAt: 'not-a-number' }); + const next = jest.fn(); + const res = createRes(); + + await checkBan(createReq(), res, next); + + expect(next).not.toHaveBeenCalled(); + expect(res.status).toHaveBeenCalledWith(403); + expect(mockBanCacheSet).not.toHaveBeenCalled(); + }); + + it('returns 403 without caching when expiresAt is null', async () => { + mockBanLogsGet.mockResolvedValueOnce({ type: 'ban', expiresAt: null }); + const next = jest.fn(); + const res = createRes(); + + await checkBan(createReq(), res, next); + + expect(next).not.toHaveBeenCalled(); + expect(res.status).toHaveBeenCalledWith(403); + expect(mockBanCacheSet).not.toHaveBeenCalled(); + }); + }); + + describe('cache write error handling (Finding 4)', () => { + it('still returns 403 when banCache.set rejects', async () => { + const expiresAt = Date.now() + 3600000; + mockBanLogsGet.mockResolvedValueOnce({ expiresAt, type: 'ban' }); + mockBanCacheSet.mockRejectedValue(new Error('MongoDB write failure')); + const next = jest.fn(); + const req = createReq(); + const res = createRes(); + + await checkBan(req, res, next); + + expect(next).not.toHaveBeenCalled(); + expect(req.banned).toBe(true); + expect(res.status).toHaveBeenCalledWith(403); + }); + + it('logs a warning when banCache.set fails', async () => { + const expiresAt = Date.now() + 3600000; + mockBanLogsGet.mockResolvedValueOnce({ expiresAt, type: 'ban' }); + mockBanCacheSet.mockRejectedValue(new Error('write failed')); + + await checkBan(createReq(), createRes(), jest.fn()); + + expect(logger.warn).toHaveBeenCalledWith( + '[checkBan] Failed to write ban cache:', + expect.any(Error), + ); + }); + }); + + describe('user lookup by email', () => { + it('resolves userId from email when not on request', async () => { + const req = createReq({ user: null, body: { email: 'test@example.com' } }); + findUser.mockResolvedValueOnce({ _id: 'resolved-user-id' }); + const expiresAt = Date.now() + 3600000; + mockBanLogsGet + .mockResolvedValueOnce(undefined) + .mockResolvedValueOnce({ expiresAt, type: 'ban' }); + + await checkBan(req, createRes(), jest.fn()); + + expect(findUser).toHaveBeenCalledWith({ email: 'test@example.com' }, '_id'); + expect(req.banned).toBe(true); + }); + + it('continues with IP-only check when email lookup finds no user', async () => { + const req = createReq({ user: null, body: { email: 'unknown@example.com' } }); + findUser.mockResolvedValueOnce(null); + const next = jest.fn(); + + await checkBan(req, createRes(), next); + + expect(next).toHaveBeenCalledWith(); + }); + }); + + describe('error handling', () => { + it('calls next(error) when an unexpected error occurs', async () => { + mockBanCacheGet.mockRejectedValueOnce(new Error('connection lost')); + const next = jest.fn(); + + await checkBan(createReq(), createRes(), next); + + expect(next).toHaveBeenCalledWith(expect.any(Error)); + expect(logger.error).toHaveBeenCalled(); + }); + }); +}); diff --git a/api/test/server/services/Files/S3/crud.test.js b/api/test/server/services/Files/S3/crud.test.js deleted file mode 100644 index d847a82cf0..0000000000 --- a/api/test/server/services/Files/S3/crud.test.js +++ /dev/null @@ -1,72 +0,0 @@ -const { getS3URL } = require('../../../../../server/services/Files/S3/crud'); - -// Mock AWS SDK -jest.mock('@aws-sdk/client-s3', () => ({ - S3Client: jest.fn(() => ({ - send: jest.fn(), - })), - GetObjectCommand: jest.fn(), -})); - -jest.mock('@aws-sdk/s3-request-presigner', () => ({ - getSignedUrl: jest.fn(), -})); - -jest.mock('../../../../../config', () => ({ - logger: { - error: jest.fn(), - }, -})); - -const { getSignedUrl } = require('@aws-sdk/s3-request-presigner'); -const { GetObjectCommand } = require('@aws-sdk/client-s3'); - -describe('S3 crud.js - test only new parameter changes', () => { - beforeEach(() => { - jest.clearAllMocks(); - process.env.AWS_BUCKET_NAME = 'test-bucket'; - }); - - // Test only the new customFilename parameter - it('should include customFilename in response headers when provided', async () => { - getSignedUrl.mockResolvedValue('https://test-presigned-url.com'); - - await getS3URL({ - userId: 'user123', - fileName: 'test.pdf', - customFilename: 'cleaned_filename.pdf', - }); - - // Verify the new ResponseContentDisposition parameter is added to GetObjectCommand - const commandArgs = GetObjectCommand.mock.calls[0][0]; - expect(commandArgs.ResponseContentDisposition).toBe( - 'attachment; filename="cleaned_filename.pdf"', - ); - }); - - // Test only the new contentType parameter - it('should include contentType in response headers when provided', async () => { - getSignedUrl.mockResolvedValue('https://test-presigned-url.com'); - - await getS3URL({ - userId: 'user123', - fileName: 'test.pdf', - contentType: 'application/pdf', - }); - - // Verify the new ResponseContentType parameter is added to GetObjectCommand - const commandArgs = GetObjectCommand.mock.calls[0][0]; - expect(commandArgs.ResponseContentType).toBe('application/pdf'); - }); - - it('should work without new parameters (backward compatibility)', async () => { - getSignedUrl.mockResolvedValue('https://test-presigned-url.com'); - - const result = await getS3URL({ - userId: 'user123', - fileName: 'test.pdf', - }); - - expect(result).toBe('https://test-presigned-url.com'); - }); -}); diff --git a/api/test/services/Files/S3/crud.test.js b/api/test/services/Files/S3/crud.test.js deleted file mode 100644 index c7b46fba4c..0000000000 --- a/api/test/services/Files/S3/crud.test.js +++ /dev/null @@ -1,876 +0,0 @@ -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/test/services/Files/processFileCitations.test.js b/api/test/services/Files/processFileCitations.test.js index e9fe850ebd..8dd588afe9 100644 --- a/api/test/services/Files/processFileCitations.test.js +++ b/api/test/services/Files/processFileCitations.test.js @@ -7,12 +7,7 @@ const { // Mock dependencies jest.mock('~/models', () => ({ - Files: { - find: jest.fn().mockResolvedValue([]), - }, -})); - -jest.mock('~/models/Role', () => ({ + getFiles: jest.fn().mockResolvedValue([]), getRoleByName: jest.fn(), })); @@ -179,7 +174,7 @@ describe('processFileCitations', () => { }); describe('enhanceSourcesWithMetadata', () => { - const { Files } = require('~/models'); + const { getFiles } = require('~/models'); const mockCustomConfig = { fileStrategy: 'local', }; @@ -204,7 +199,7 @@ describe('processFileCitations', () => { }, ]; - Files.find.mockResolvedValue([ + getFiles.mockResolvedValue([ { file_id: 'file_123', filename: 'example_from_db.pdf', @@ -219,7 +214,7 @@ describe('processFileCitations', () => { const result = await enhanceSourcesWithMetadata(sources, mockCustomConfig); - expect(Files.find).toHaveBeenCalledWith({ file_id: { $in: ['file_123', 'file_456'] } }); + expect(getFiles).toHaveBeenCalledWith({ file_id: { $in: ['file_123', 'file_456'] } }); expect(result).toHaveLength(2); expect(result[0]).toEqual({ @@ -258,7 +253,7 @@ describe('processFileCitations', () => { }, ]; - Files.find.mockResolvedValue([ + getFiles.mockResolvedValue([ { file_id: 'file_123', filename: 'example_from_db.pdf', @@ -292,7 +287,7 @@ describe('processFileCitations', () => { }, ]; - Files.find.mockResolvedValue([]); + getFiles.mockResolvedValue([]); const result = await enhanceSourcesWithMetadata(sources, mockCustomConfig); @@ -317,7 +312,7 @@ describe('processFileCitations', () => { }, ]; - Files.find.mockRejectedValue(new Error('Database error')); + getFiles.mockRejectedValue(new Error('Database error')); const result = await enhanceSourcesWithMetadata(sources, mockCustomConfig); @@ -339,14 +334,14 @@ describe('processFileCitations', () => { { fileId: 'file_456', fileName: 'doc2.pdf', relevance: 0.7, type: 'file' }, ]; - Files.find.mockResolvedValue([ + getFiles.mockResolvedValue([ { file_id: 'file_123', filename: 'document1.pdf', source: 's3' }, { file_id: 'file_456', filename: 'document2.pdf', source: 'local' }, ]); await enhanceSourcesWithMetadata(sources, mockCustomConfig); - expect(Files.find).toHaveBeenCalledWith({ file_id: { $in: ['file_123', 'file_456'] } }); + expect(getFiles).toHaveBeenCalledWith({ file_id: { $in: ['file_123', 'file_456'] } }); }); }); }); diff --git a/bun.lock b/bun.lock index 622489ea0f..fb1ec00840 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,33 @@ "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.4", "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.57", "@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", + "ai-tokenizer": "^1.0.6", + "axios": "^1.13.5", "bcryptjs": "^2.4.3", "compression": "^1.8.1", "connect-redis": "^8.1.0", @@ -64,12 +67,12 @@ "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", + "file-type": "^21.3.2", "firebase": "^11.0.2", "form-data": "^4.0.4", "handlebars": "^4.7.7", @@ -82,13 +85,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 +109,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.24.1", "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", + "yauzl": "^3.2.1", "zod": "^3.22.4", }, "devDependencies": { @@ -124,22 +130,23 @@ }, "client": { "name": "@librechat/frontend", - "version": "0.8.300", + "version": "0.8.4", "dependencies": { "@ariakit/react": "^0.4.15", "@ariakit/react-core": "^0.4.17", "@codesandbox/sandpack-react": "^2.19.10", - "@dicebear/collection": "^9.2.2", - "@dicebear/core": "^9.2.2", + "@dicebear/collection": "^9.4.1", + "@dicebear/core": "^9.4.1", "@headlessui/react": "^2.1.2", "@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 +181,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 +197,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 +213,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 +225,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 +234,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 +248,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.24", + "version": "1.7.27", "devDependencies": { "@babel/preset-env": "^7.21.5", "@babel/preset-react": "^7.18.6", @@ -266,7 +276,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", @@ -276,52 +285,67 @@ "@types/node-fetch": "^2.6.13", "@types/react": "^18.2.18", "@types/winston": "^2.4.4", + "@types/yauzl": "^2.10.3", "jest": "^30.2.0", "jest-junit": "^16.0.0", + "jszip": "^3.10.1", "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", + "yauzl": "^3.2.1", }, "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.57", "@librechat/data-schemas": "*", - "@modelcontextprotocol/sdk": "^1.24.3", - "axios": "^1.12.1", + "@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", - "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.24.1", + "yauzl": "^3.2.1", "zod": "^3.22.4", }, }, "packages/client": { "name": "@librechat/client", - "version": "0.4.53", + "version": "0.4.56", "devDependencies": { "@babel/core": "^7.28.5", "@babel/preset-env": "^7.28.5", @@ -351,8 +375,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", @@ -362,14 +386,14 @@ "peerDependencies": { "@ariakit/react": "^0.4.16", "@ariakit/react-core": "^0.4.17", - "@dicebear/collection": "^9.2.2", - "@dicebear/core": "^9.2.2", + "@dicebear/collection": "^9.4.1", + "@dicebear/core": "^9.4.1", "@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 +433,9 @@ }, "packages/data-provider": { "name": "librechat-data-provider", - "version": "0.8.301", + "version": "0.8.401", "dependencies": { - "axios": "^1.12.1", + "axios": "^1.13.5", "dayjs": "^1.11.13", "js-yaml": "^4.1.1", "zod": "^3.22.4", @@ -420,7 +444,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 +458,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 +470,7 @@ }, "packages/data-schemas": { "name": "@librechat/data-schemas", - "version": "0.0.37", + "version": "0.0.40", "devDependencies": { "@rollup/plugin-alias": "^5.1.0", "@rollup/plugin-commonjs": "^29.0.0", @@ -456,15 +479,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 +496,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 +506,19 @@ }, }, "overrides": { - "axios": "1.12.1", + "@anthropic-ai/sdk": "0.73.0", + "@hono/node-server": "^1.19.10", "elliptic": "^6.6.1", + "fast-xml-parser": "5.5.7", "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 +527,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 +559,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.1013.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.22", "@aws-sdk/credential-provider-node": "^3.972.23", "@aws-sdk/eventstream-handler-node": "^3.972.11", "@aws-sdk/middleware-eventstream": "^3.972.8", "@aws-sdk/middleware-host-header": "^3.972.8", "@aws-sdk/middleware-logger": "^3.972.8", "@aws-sdk/middleware-recursion-detection": "^3.972.8", "@aws-sdk/middleware-user-agent": "^3.972.23", "@aws-sdk/middleware-websocket": "^3.972.13", "@aws-sdk/region-config-resolver": "^3.972.8", "@aws-sdk/token-providers": "3.1013.0", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@aws-sdk/util-user-agent-browser": "^3.972.8", "@aws-sdk/util-user-agent-node": "^3.973.9", "@smithy/config-resolver": "^4.4.11", "@smithy/core": "^3.23.12", "@smithy/eventstream-serde-browser": "^4.2.12", "@smithy/eventstream-serde-config-resolver": "^4.3.12", "@smithy/eventstream-serde-node": "^4.2.12", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/hash-node": "^4.2.12", "@smithy/invalid-dependency": "^4.2.12", "@smithy/middleware-content-length": "^4.2.12", "@smithy/middleware-endpoint": "^4.4.26", "@smithy/middleware-retry": "^4.4.43", "@smithy/middleware-serde": "^4.2.15", "@smithy/middleware-stack": "^4.2.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/node-http-handler": "^4.5.0", "@smithy/protocol-http": "^5.3.12", "@smithy/smithy-client": "^4.12.6", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@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.42", "@smithy/util-defaults-mode-node": "^4.2.45", "@smithy/util-endpoints": "^3.3.3", "@smithy/util-middleware": "^4.2.12", "@smithy/util-retry": "^4.2.12", "@smithy/util-stream": "^4.5.20", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-LU80q1avpBwQ0eVAGbQpPApdVY4vcdBEIycY5iaznI10mdabeG83nrFySJrZ8knX7G6hl5d5KIOSjcpnolMKSA=="], "@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.22", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@aws-sdk/xml-builder": "^3.972.14", "@smithy/core": "^3.23.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/property-provider": "^4.2.12", "@smithy/protocol-http": "^5.3.12", "@smithy/signature-v4": "^5.3.12", "@smithy/smithy-client": "^4.12.6", "@smithy/types": "^4.13.1", "@smithy/util-base64": "^4.3.2", "@smithy/util-middleware": "^4.2.12", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-lY6g5L95jBNgOUitUhfV2N/W+i08jHEl3xuLODYSQH5Sf50V+LkVYBSyZRLtv2RyuXZXiV7yQ+acpswK1tlrOA=="], + + "@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 +583,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.22", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/nested-clients": "^3.996.12", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/protocol-http": "^5.3.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-u33CO9zeNznlVSg9tWTCRYxaGkqr1ufU6qeClpmzAabXZa8RZxQoVXxL5T53oZJFzQYj+FImORCSsi7H7B77gQ=="], - "@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.23", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.20", "@aws-sdk/credential-provider-http": "^3.972.22", "@aws-sdk/credential-provider-ini": "^3.972.22", "@aws-sdk/credential-provider-process": "^3.972.20", "@aws-sdk/credential-provider-sso": "^3.972.22", "@aws-sdk/credential-provider-web-identity": "^3.972.22", "@aws-sdk/types": "^3.973.6", "@smithy/credential-provider-imds": "^4.2.12", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-U8tyLbLOZItuVWTH0ay9gWo4xMqZwqQbg1oMzdU4FQSkTpqXemm4X0uoKBR6llqAStgBp30ziKFJHTA43l4qMw=="], "@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 +595,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.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/eventstream-codec": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-2IrLrOruRr1NhTK0vguBL1gCWv1pu4bf4KaqpsA+/vCJpFEbvXFawn71GvCzk1wyjnDUsemtKypqoKGv4cSGbA=="], - "@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.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-r+oP+tbCxgqXVC3pu3MUVePgSY0ILMjA+aEwOosS77m3/DRbtvHrHwqvMcw+cjANMeGzJ+i0ar+n77KXpRA8RQ=="], - "@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.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-wAr2REfKsqoKQ+OkNqvOShnBoh+nkPurDKW7uAeVSu6kUECnWlSJiPvnoqxGlfousEY/v9LfS9sNc46hjSYDIQ=="], - "@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.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-CWl5UCM57WUFaFi5kB7IBY1UmOeLvNZAZ2/OZ5l20ldiJ3TiIz1pC65gYj8X0BCPWkeR1E32mpsCk1L1I4n+lA=="], - "@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.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-BnnvYs2ZEpdlmZ2PNlV2ZyQ8j8AEkMTjN79y/YA475ER1ByFYrkVR85qmhni8oeTaJcDqbx364wDpitDAA/wCA=="], - "@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.23", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@smithy/core": "^3.23.12", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/util-retry": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-HQu8QoqGZZTvg0Spl9H39QTsSMFwgu+8yz/QGKndXFLk9FZMiCiIgBCVlTVKMDvVbgqIzD9ig+/HmXsIL2Rb+g=="], - "@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.13", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-format-url": "^3.972.8", "@smithy/eventstream-codec": "^4.2.12", "@smithy/eventstream-serde-browser": "^4.2.12", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/protocol-http": "^5.3.12", "@smithy/signature-v4": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/util-base64": "^4.3.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-Gp6EWIqHX5wmsOR5ZxWyyzEU8P0xBdSxkm6VHEwXwBqScKZ7QWRoj6ZmHpr+S44EYb5tuzGya4ottsogSu2W3A=="], - "@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.12", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.22", "@aws-sdk/middleware-host-header": "^3.972.8", "@aws-sdk/middleware-logger": "^3.972.8", "@aws-sdk/middleware-recursion-detection": "^3.972.8", "@aws-sdk/middleware-user-agent": "^3.972.23", "@aws-sdk/region-config-resolver": "^3.972.8", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@aws-sdk/util-user-agent-browser": "^3.972.8", "@aws-sdk/util-user-agent-node": "^3.973.9", "@smithy/config-resolver": "^4.4.11", "@smithy/core": "^3.23.12", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/hash-node": "^4.2.12", "@smithy/invalid-dependency": "^4.2.12", "@smithy/middleware-content-length": "^4.2.12", "@smithy/middleware-endpoint": "^4.4.26", "@smithy/middleware-retry": "^4.4.43", "@smithy/middleware-serde": "^4.2.15", "@smithy/middleware-stack": "^4.2.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/node-http-handler": "^4.5.0", "@smithy/protocol-http": "^5.3.12", "@smithy/smithy-client": "^4.12.6", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@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.42", "@smithy/util-defaults-mode-node": "^4.2.45", "@smithy/util-endpoints": "^3.3.3", "@smithy/util-middleware": "^4.2.12", "@smithy/util-retry": "^4.2.12", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-KLdQGJPSm98uLINolQ0Tol8OAbk7g0Y7zplHJ1K83vbMIH13aoCvR6Tho66xueW4l4aZlEgVGLWBnD8ifUMsGQ=="], - "@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.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/config-resolver": "^4.4.11", "@smithy/node-config-provider": "^4.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-1eD4uhTDeambO/PNIDVG19A6+v4NdD7xzwLHDutHsUqz0B+i661MwQB2eYO4/crcCvCiQG4SRm1k81k54FEIvw=="], "@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.1013.0", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/nested-clients": "^3.996.12", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-IL1c54UvbuERrs9oLm5rvkzMciwhhpn1FL0SlC3XUMoLlFhdBsWJgQKK8O5fsQLxbFVqjbjFx9OBkrn44X9PHw=="], - "@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.6", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-Atfcy4E++beKtwJHiDln2Nby8W/mam64opFPTiHEqgsthqeydFS1pY+OUlN1ouNOmf8ArPU/6cDS65anOP3KQw=="], - "@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.5", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-endpoints": "^3.3.3", "tslib": "^2.6.2" } }, "sha512-Uh93L5sXFNbyR5sEPMzUU8tJ++Ku97EY4udmC01nB8Zu+xfBPwpIwJ6F7snqQeq8h2pf+8SGN5/NoytfKgYPIw=="], "@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.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/types": "^4.13.1", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-B3KGXJviV2u6Cdw2SDY2aDhoJkVfY/Q/Trwk2CMSkikE1Oi6gRzxhvhIfiRpHfmIsAhV4EA54TVEX8K6CbHbkA=="], - "@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.9", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.23", "@aws-sdk/types": "^3.973.6", "@smithy/node-config-provider": "^4.3.12", "@smithy/types": "^4.13.1", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-jeFqqp8KD/P5O+qeKxyGeu7WEVIZFNprnkaDjGmBOjwxYwafCBhpxTgV1TlW6L8e76Vh/siNylNmN/OmSIFBUQ=="], - "@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.14", "", { "dependencies": { "@smithy/types": "^4.13.1", "fast-xml-parser": "5.5.6", "tslib": "^2.6.2" } }, "sha512-G/Yd8Bnnyh8QrqLf8jWJbixEnScUFW24e/wOBGYdw1Cl4r80KX/DvHyM2GVZ2vTp7J4gTEr8IXJlTadA8+UfuQ=="], "@aws/lambda-invoke-store": ["@aws/lambda-invoke-store@0.2.2", "", {}, "sha512-C0NBLsIqzDIae8HFw9YIrIBsbc0xTiOtt7fAukGPnqQ/+zZNaq+4jhuccltK0QuWHBnNm/a6kLIRA6GFiM10eg=="], @@ -647,55 +683,45 @@ "@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=="], - "@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=="], + "@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.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="], "@babel/compat-data": ["@babel/compat-data@7.28.5", "", {}, "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA=="], - "@babel/core": ["@babel/core@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.4", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@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-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw=="], + "@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=="], - "@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/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=="], - "@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-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=="], - "@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 +729,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/helpers": ["@babel/helpers@7.28.6", "", { "dependencies": { "@babel/template": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw=="], - "@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], + "@babel/parser": ["@babel/parser@7.29.0", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww=="], - "@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 +755,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,144 +785,158 @@ "@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=="], - "@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + "@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=="], - "@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], + "@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=="], - "@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + "@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=="], "@bcoe/v8-coverage": ["@bcoe/v8-coverage@0.2.3", "", {}, "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw=="], + "@borewit/text-codec": ["@borewit/text-codec@0.2.2", "", {}, "sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ=="], + + "@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,133 +965,177 @@ "@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=="], - "@dicebear/adventurer": ["@dicebear/adventurer@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-Xvboay3VH1qe7lH17T+bA3qPawf5EjccssDiyhCX/VT0P21c65JyjTIUJV36Nsv08HKeyDscyP0kgt9nPTRKvA=="], + "@dicebear/adventurer": ["@dicebear/adventurer@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-jqYp834ZmGDA9HBBDQAdgF1O2UTCwHF4vVrktXWa2Dppp1JczPL5HnVOWsjtrLmXNn61Wd6OLmBb2e6rhzp3ig=="], - "@dicebear/adventurer-neutral": ["@dicebear/adventurer-neutral@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-I9IrB4ZYbUHSOUpWoUbfX3vG8FrjcW8htoQ4bEOR7TYOKKE11Mo1nrGMuHZ7GPfwN0CQeK1YVJhWqLTmtYn7Pg=="], + "@dicebear/adventurer-neutral": ["@dicebear/adventurer-neutral@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-5xgkG/mNL4j3Q4SJGQLBU/KnU90tng8Ze5ofThD+55wi0oeY/nSAUowg6UFCmHrktjifj/MEx3CQqbpcPWtfIA=="], - "@dicebear/avataaars": ["@dicebear/avataaars@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-QKNBtA/1QGEzR+JjS4XQyrFHYGbzdOp0oa6gjhGhUDrMegDFS8uyjdRfDQsFTebVkyLWjgBQKZEiDqKqHptB6A=="], + "@dicebear/avataaars": ["@dicebear/avataaars@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-3x9jKFkOkFSPmpTbt9xvhiU2E1GX7beCSsX0tXRUShj8x6+5Ks9yBRT1VlkySbnXrZ/GglADGg7vJ/D2uIx1Yw=="], - "@dicebear/avataaars-neutral": ["@dicebear/avataaars-neutral@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-HtBvA7elRv50QTOOsBdtYB1GVimCpGEDlDgWsu1snL5Z3d1+3dIESoXQd3mXVvKTVT8Z9ciA4TEaF09WfxDjAA=="], + "@dicebear/avataaars-neutral": ["@dicebear/avataaars-neutral@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-/eNrp0YCNJRwQXqOloLm1+3Ss2C+pMpUQIGkbEnGsP1UK+13Ge80ggDDof1HpdqvG9HAZcKa7hnbG/0HSwyDSw=="], - "@dicebear/big-ears": ["@dicebear/big-ears@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-U33tbh7Io6wG6ViUMN5fkWPER7hPKMaPPaYgafaYQlCT4E7QPKF2u8X1XGag3jCKm0uf4SLXfuZ8v+YONcHmNQ=="], + "@dicebear/big-ears": ["@dicebear/big-ears@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-mNfz3ppNA7UBq0IO3nXCiV5pFPG7c1DfzRB0foNU2Wo1XXT8FIcSY2BvDlYqorZTOUOz7dHb0vx06hqvG0HP5w=="], - "@dicebear/big-ears-neutral": ["@dicebear/big-ears-neutral@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-pPjYu80zMFl43A9sa5+tAKPkhp4n9nd7eN878IOrA1HAowh/XePh5JN8PTkNFS9eM+rnN9m8WX08XYFe30kLYw=="], + "@dicebear/big-ears-neutral": ["@dicebear/big-ears-neutral@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-M8Ozmzza4eY4hpLOYULgJxMYmBA0CsBnrE15/xw6LZkEREXnrX5z0NJsf8hUfdyF6BWZ+RBgzoiav32DAC5zcg=="], - "@dicebear/big-smile": ["@dicebear/big-smile@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-zeEfXOOXy7j9tfkPLzfQdLBPyQsctBetTdEfKRArc1k3RUliNPxfJG9j88+cXQC6GXrVW2pcT2X50NSPtugCFQ=="], + "@dicebear/big-smile": ["@dicebear/big-smile@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-hmT5i7rcPPhStjZyg28pbIhdTnnMBzK3RObI0vKCpY30EFrzaPkkdDL6Ck5fAFBdvDIW1EpOJkenyR0XPmhgbQ=="], - "@dicebear/bottts": ["@dicebear/bottts@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-4CTqrnVg+NQm6lZ4UuCJish8gGWe8EqSJrzvHQRO5TEyAKjYxbTdVqejpkycG1xkawha4FfxsYgtlSx7UwoVMw=="], + "@dicebear/bottts": ["@dicebear/bottts@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-tsx+dII7EFUCVA8URj66G1GqORCCVduCAx4dY2prEY2IeFianVpkntXuFsWZ9BBGx1NZFndvDith5oTwKMQPbQ=="], - "@dicebear/bottts-neutral": ["@dicebear/bottts-neutral@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-eMVdofdD/udHsKIaeWEXShDRtiwk7vp4FjY7l0f79vIzfhkIsXKEhPcnvHKOl/yoArlDVS3Uhgjj0crWTO9RJA=="], + "@dicebear/bottts-neutral": ["@dicebear/bottts-neutral@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-kFNwWt6j+gzZ5n5Pz7WVwePubREAQOF8ZwWA9ztwVYDVMLnOChWbAofy5FED4j5md2MXFH2EgLCFCMr5K2BmIA=="], - "@dicebear/collection": ["@dicebear/collection@9.2.4", "", { "dependencies": { "@dicebear/adventurer": "9.2.4", "@dicebear/adventurer-neutral": "9.2.4", "@dicebear/avataaars": "9.2.4", "@dicebear/avataaars-neutral": "9.2.4", "@dicebear/big-ears": "9.2.4", "@dicebear/big-ears-neutral": "9.2.4", "@dicebear/big-smile": "9.2.4", "@dicebear/bottts": "9.2.4", "@dicebear/bottts-neutral": "9.2.4", "@dicebear/croodles": "9.2.4", "@dicebear/croodles-neutral": "9.2.4", "@dicebear/dylan": "9.2.4", "@dicebear/fun-emoji": "9.2.4", "@dicebear/glass": "9.2.4", "@dicebear/icons": "9.2.4", "@dicebear/identicon": "9.2.4", "@dicebear/initials": "9.2.4", "@dicebear/lorelei": "9.2.4", "@dicebear/lorelei-neutral": "9.2.4", "@dicebear/micah": "9.2.4", "@dicebear/miniavs": "9.2.4", "@dicebear/notionists": "9.2.4", "@dicebear/notionists-neutral": "9.2.4", "@dicebear/open-peeps": "9.2.4", "@dicebear/personas": "9.2.4", "@dicebear/pixel-art": "9.2.4", "@dicebear/pixel-art-neutral": "9.2.4", "@dicebear/rings": "9.2.4", "@dicebear/shapes": "9.2.4", "@dicebear/thumbs": "9.2.4" }, "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-I1wCUp0yu5qSIeMQHmDYXQIXKkKjcja/SYBxppPkYFXpR2alxb0k9/swFDdMbkY6a1c9AT1kI1y+Pg6ywQ2rTA=="], + "@dicebear/collection": ["@dicebear/collection@9.4.2", "", { "dependencies": { "@dicebear/adventurer": "9.4.2", "@dicebear/adventurer-neutral": "9.4.2", "@dicebear/avataaars": "9.4.2", "@dicebear/avataaars-neutral": "9.4.2", "@dicebear/big-ears": "9.4.2", "@dicebear/big-ears-neutral": "9.4.2", "@dicebear/big-smile": "9.4.2", "@dicebear/bottts": "9.4.2", "@dicebear/bottts-neutral": "9.4.2", "@dicebear/croodles": "9.4.2", "@dicebear/croodles-neutral": "9.4.2", "@dicebear/dylan": "9.4.2", "@dicebear/fun-emoji": "9.4.2", "@dicebear/glass": "9.4.2", "@dicebear/icons": "9.4.2", "@dicebear/identicon": "9.4.2", "@dicebear/initials": "9.4.2", "@dicebear/lorelei": "9.4.2", "@dicebear/lorelei-neutral": "9.4.2", "@dicebear/micah": "9.4.2", "@dicebear/miniavs": "9.4.2", "@dicebear/notionists": "9.4.2", "@dicebear/notionists-neutral": "9.4.2", "@dicebear/open-peeps": "9.4.2", "@dicebear/personas": "9.4.2", "@dicebear/pixel-art": "9.4.2", "@dicebear/pixel-art-neutral": "9.4.2", "@dicebear/rings": "9.4.2", "@dicebear/shapes": "9.4.2", "@dicebear/thumbs": "9.4.2", "@dicebear/toon-head": "9.4.2" }, "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-KArubv7if8H7j9sIfpDK2hJJqrdNVR5zMPAMOSpIU2JPyXx8TC9o5wsmXb8il5wOHgaS9Q/cla7jUNIiDD7Gsg=="], - "@dicebear/core": ["@dicebear/core@9.2.4", "", { "dependencies": { "@types/json-schema": "^7.0.11" } }, "sha512-hz6zArEcUwkZzGOSJkWICrvqnEZY7BKeiq9rqKzVJIc1tRVv0MkR0FGvIxSvXiK9TTIgKwu656xCWAGAl6oh+w=="], + "@dicebear/core": ["@dicebear/core@9.4.2", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-MF0042+Z3s8PGZKZLySfhft28bUa3B1iq0e5NSjCvY8gfMi5aIH/iRJGRJa1N9Jz1BNkxYb4yvJ/N9KO8Z6Y+w=="], - "@dicebear/croodles": ["@dicebear/croodles@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-CqT0NgVfm+5kd+VnjGY4WECNFeOrj5p7GCPTSEA7tCuN72dMQOX47P9KioD3wbExXYrIlJgOcxNrQeb/FMGc3A=="], + "@dicebear/croodles": ["@dicebear/croodles@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-6VoO0JviIf7dKKMBTL/SMXxWhnXHaZuzufX90G0nXxS77ELG1YkGNMaZzawizN4C09Gbya2gJkozqrWiJN/aGw=="], - "@dicebear/croodles-neutral": ["@dicebear/croodles-neutral@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-8vAS9lIEKffSUVx256GSRAlisB8oMX38UcPWw72venO/nitLVsyZ6hZ3V7eBdII0Onrjqw1RDndslQODbVcpTw=="], + "@dicebear/croodles-neutral": ["@dicebear/croodles-neutral@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-oG5IeUdtiYshQ89gkAVcl5w3xAEi5UZX2fTzIyelpBPCG176l7VuuFzlxi2umnB3E6LVHYy06DXvUo/p+rXB2Q=="], - "@dicebear/dylan": ["@dicebear/dylan@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-tiih1358djAq0jDDzmW3N3S4C3ynC2yn4hhlTAq/MaUAQtAi47QxdHdFGdxH0HBMZKqA4ThLdVk3yVgN4xsukg=="], + "@dicebear/dylan": ["@dicebear/dylan@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-1vQvRu9x9DrwFxhFaIU2rf0EUL04yDTbAt7fHyAjM0mEsKzTD4mRNf95tCRuavCoW6W48u7A/OY6jyIub6kxLQ=="], - "@dicebear/fun-emoji": ["@dicebear/fun-emoji@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-Od729skczse1HvHekgEFv+mSuJKMC4sl5hENGi/izYNe6DZDqJrrD0trkGT/IVh/SLXUFbq1ZFY9I2LoUGzFZg=="], + "@dicebear/fun-emoji": ["@dicebear/fun-emoji@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-kqB6LPkdYCdEU/mwbyz34xLzoNUKL6ARcoo3fr5ASq9D6ZE07qIKybC3xv5+CPz7VmspJ1Q3c/VVWVMDRP7Twg=="], - "@dicebear/glass": ["@dicebear/glass@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-5lxbJode1t99eoIIgW0iwZMoZU4jNMJv/6vbsgYUhAslYFX5zP0jVRscksFuo89TTtS7YKqRqZAL3eNhz4bTDw=="], + "@dicebear/glass": ["@dicebear/glass@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-z5qUogHQ1b6UJ2zCqT848mU2U9DKbVDhiX6GPDjD7tYLisCCJVisH9p6WyNdHvflUd4SHkA6gRqVJIh2v2HnTA=="], - "@dicebear/icons": ["@dicebear/icons@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-bRsK1qj8u9Z76xs8XhXlgVr/oHh68tsHTJ/1xtkX9DeTQTSamo2tS26+r231IHu+oW3mePtFnwzdG9LqEPRd4A=="], + "@dicebear/icons": ["@dicebear/icons@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-QSMMz0NA03ypSGhXC8HQX8FSj8lYT+/5yqH+/N03OH2IjL0q7wwGZ7nqsrtlRp76O5WqMTwGfSbTUUYPjFr+Xw=="], - "@dicebear/identicon": ["@dicebear/identicon@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-R9nw/E8fbu9HltHOqI9iL/o9i7zM+2QauXWMreQyERc39oGR9qXiwgBxsfYGcIS4C85xPyuL5B3I2RXrLBlJPg=="], + "@dicebear/identicon": ["@dicebear/identicon@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-JVDSmZsv11mSWqwAktK5x9Bslht2xY3TFUn8xzu6slAYe1Z7hEXZ76eb+UJ6F4qEzdwZ7xPWzAS6Nb0Y3A0pww=="], - "@dicebear/initials": ["@dicebear/initials@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-4SzHG5WoQZl1TGcpEZR4bdsSkUVqwNQCOwWSPAoBJa3BNxbVsvL08LF7I97BMgrCoknWZjQHUYt05amwTPTKtg=="], + "@dicebear/initials": ["@dicebear/initials@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-yePuIUasmwtl9IrtB6rEzE/zb5fImKP/neW0CdcTC2MwLgMuP1GLHEGRgg1zI8exIh+PMv1YdLGyyUuRTE2Qpw=="], - "@dicebear/lorelei": ["@dicebear/lorelei@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-eS4mPYUgDpo89HvyFAx/kgqSSKh8W4zlUA8QJeIUCWTB0WpQmeqkSgIyUJjGDYSrIujWi+zEhhckksM5EwW0Dg=="], + "@dicebear/lorelei": ["@dicebear/lorelei@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-YMv6vnriW6VLFDsreKuOnUFFno6SRe7+7X7R7zPY0rZ+MaHX9V3jcioIG+1PSjIHEDfOLUHpr5vd1JBWv8y7UA=="], - "@dicebear/lorelei-neutral": ["@dicebear/lorelei-neutral@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-bWq2/GonbcJULtT+B/MGcM2UnA7kBQoH+INw8/oW83WI3GNTZ6qEwe3/W4QnCgtSOhUsuwuiSULguAFyvtkOZQ=="], + "@dicebear/lorelei-neutral": ["@dicebear/lorelei-neutral@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-yspanTthA5vh6iCdeLzn6xZ4yYMYRcfcxblcgSvHTF1ut0bjAXtw5SXzZ6aJTrJWiHkzYOQuTOR6GVYiW80Q7w=="], - "@dicebear/micah": ["@dicebear/micah@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-XNWJ8Mx+pncIV8Ye0XYc/VkMiax8kTxcP3hLTC5vmELQyMSLXzg/9SdpI+W/tCQghtPZRYTT3JdY9oU9IUlP2g=="], + "@dicebear/micah": ["@dicebear/micah@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-e4D3W/OlChSsLo7Llwsy0J18vk0azJqF/uFoY+EKACCNHBc1HGNsqVvu2CTf+OWOA8wTyAK6UkjBN5p01r7D+g=="], - "@dicebear/miniavs": ["@dicebear/miniavs@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-k7IYTAHE/4jSO6boMBRrNlqPT3bh7PLFM1atfe0nOeCDwmz/qJUBP3HdONajbf3fmo8f2IZYhELrNWTOE7Ox3Q=="], + "@dicebear/miniavs": ["@dicebear/miniavs@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-wLwyFNNUnDRd3BbhSBhXR0XEpX8sG0/xDA5M/OkDoapLqZnnI48YLUSDd2N5QTAVMmcSEuZOYxkcnj7WW79vlg=="], - "@dicebear/notionists": ["@dicebear/notionists@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-zcvpAJ93EfC0xQffaPZQuJPShwPhnu9aTcoPsaYGmw0oEDLcv2XYmDhUUdX84QYCn6LtCZH053rHLVazRW+OGw=="], + "@dicebear/notionists": ["@dicebear/notionists@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-ZCySq+nxcD/x4xyYgytcj2N9uY3gxrL+qpnmOdp2BdA221KacVrxlsUPpIgEMqxS2rMmBQXfxg129Pzn4ycIpA=="], - "@dicebear/notionists-neutral": ["@dicebear/notionists-neutral@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-fskWzBVxQzJhCKqY24DGZbYHSBaauoRa1DgXM7+7xBuksH7mfbTmZTvnUAsAqJYBkla8IPb4ERKduDWtlWYYjQ=="], + "@dicebear/notionists-neutral": ["@dicebear/notionists-neutral@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-AyD9kEfVxQUwDGf4Op059gVmYIOAkTKg3dtE9h9mEKP7zl/kMy5B67BFFOo7sB0mXCjzAegZ6ekGU02E8+hIHw=="], - "@dicebear/open-peeps": ["@dicebear/open-peeps@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-s6nwdjXFsplqEI7imlsel4Gt6kFVJm6YIgtZSpry0UdwDoxUUudei5bn957j9lXwVpVUcRjJW+TuEKztYjXkKQ=="], + "@dicebear/open-peeps": ["@dicebear/open-peeps@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-i01tLgtp2g937T81sVeAOVlqsCtiTck/Kw20g7hN80+7xrXjOUepz2HPLy3HeiMjwjMGRy5o54kSd0/8Ht4Dqg=="], - "@dicebear/personas": ["@dicebear/personas@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-JNim8RfZYwb0MfxW6DLVfvreCFIevQg+V225Xe5tDfbFgbcYEp4OU/KaiqqO2476OBjCw7i7/8USbv2acBhjwA=="], + "@dicebear/personas": ["@dicebear/personas@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-NJlkvI5F5gugt6t2+7QrYNTwQC7+4IQZS3vG0dYk2BncxOHax0BuLovdSdiAesTL4ZkytFYIydWmKmV2/xcUwg=="], - "@dicebear/pixel-art": ["@dicebear/pixel-art@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-4Ao45asieswUdlCTBZqcoF/0zHR3OWUWB0Mvhlu9b1Fbc6IlPBiOfx2vsp6bnVGVnMag58tJLecx2omeXdECBQ=="], + "@dicebear/pixel-art": ["@dicebear/pixel-art@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-peHf7oKICDgBZ8dUyj+txPnS7VZEWgvKE+xW4mNQqBt6dYZIjmva2shOVHn0b1JU+FDxMx3uIkWVixKdUq4WGg=="], - "@dicebear/pixel-art-neutral": ["@dicebear/pixel-art-neutral@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-ZITPLD1cPN4GjKkhWi80s7e5dcbXy34ijWlvmxbc4eb/V7fZSsyRa9EDUW3QStpo+xrCJLcLR+3RBE5iz0PC/A=="], + "@dicebear/pixel-art-neutral": ["@dicebear/pixel-art-neutral@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-9e9Lz554uQvWaXV2P17ss+hPa6rTyuAKBtB8zk8ECjHiZzIl61N/KcTVLZ4dILVZwj7gYriaLo16QEqvL2GJCg=="], - "@dicebear/rings": ["@dicebear/rings@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-teZxELYyV2ogzgb5Mvtn/rHptT0HXo9SjUGS4A52mOwhIdHSGGU71MqA1YUzfae9yJThsw6K7Z9kzuY2LlZZHA=="], + "@dicebear/rings": ["@dicebear/rings@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-Pc3ymWrRDQPJFNrbbLt7RJrzGvUuuxUiDkrfLhoVE+B6mZWEL1PC78DPbS1yUWYLErJOpJuM2GSwXmTbVjWf+g=="], - "@dicebear/shapes": ["@dicebear/shapes@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-MhK9ZdFm1wUnH4zWeKPRMZ98UyApolf5OLzhCywfu38tRN6RVbwtBRHc/42ZwoN1JU1JgXr7hzjYucMqISHtbA=="], + "@dicebear/shapes": ["@dicebear/shapes@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-AFL6jAaiLztvcqyq+ds+lWZu6Vbp3PlGWhJeJRm842jxtiluJpl6r4f6nUXP2fdMz7MNpDzXfLooQK9E04NbUQ=="], - "@dicebear/thumbs": ["@dicebear/thumbs@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-EL4sMqv9p2+1Xy3d8e8UxyeKZV2+cgt3X2x2RTRzEOIIhobtkL8u6lJxmJbiGbpVtVALmrt5e7gjmwqpryYDpg=="], + "@dicebear/thumbs": ["@dicebear/thumbs@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-ccWvDBqbkWS5uzHbsg5L6uML6vBfX7jT3J3jHCQksvz8haHItxTK02w+6e1UavZUsvza4lG5X/XY3eji3siJ4Q=="], + + "@dicebear/toon-head": ["@dicebear/toon-head@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-lwFeSXyAnaKnCfMt9TiJwnD1cXQUGkey/0h6i/+4TVHVMCz5/Ri5u1ynovPNHy1SnBf858QwoXHkxilGLwQX/g=="], "@emnapi/core": ["@emnapi/core@1.7.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" } }, "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg=="], @@ -1063,55 +1143,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 +1207,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 +1313,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 +1335,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 +1403,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 +1447,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 +1493,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.62", "", { "dependencies": { "@anthropic-ai/sdk": "^0.73.0", "@aws-sdk/client-bedrock-runtime": "^3.1013.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", "ai-tokenizer": "^1.0.6", "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-QBZlJ4C89GmBg9w2qoWOWl1Y1xiRypUtIMBsL6eLPIsdbKHJ+GYO+076rfSD+tMqZB5ZbrxqPWOh+gxEXK1coQ=="], "@librechat/api": ["@librechat/api@workspace:packages/api"], @@ -1421,14 +1509,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=="], @@ -1547,7 +1665,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 +1679,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 +1705,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 +1737,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 +1791,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 +1799,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=="], @@ -1701,155 +1821,167 @@ "@rollup/pluginutils": ["@rollup/pluginutils@5.1.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^2.3.1" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" } }, "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g=="], - "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.37.0", "", { "os": "android", "cpu": "arm" }, "sha512-l7StVw6WAa8l3vA1ov80jyetOAEo1FtHvZDbzXDO/02Sq/QVvqlHkYoFwDJPIMj0GKiistsBudfx5tGFnwYWDQ=="], + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.59.0", "", { "os": "android", "cpu": "arm" }, "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg=="], - "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.37.0", "", { "os": "android", "cpu": "arm64" }, "sha512-6U3SlVyMxezt8Y+/iEBcbp945uZjJwjZimu76xoG7tO1av9VO691z8PkhzQ85ith2I8R2RddEPeSfcbyPfD4hA=="], + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.59.0", "", { "os": "android", "cpu": "arm64" }, "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q=="], - "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.37.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-+iTQ5YHuGmPt10NTzEyMPbayiNTcOZDWsbxZYR1ZnmLnZxG17ivrPSWFO9j6GalY0+gV3Jtwrrs12DBscxnlYA=="], + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.59.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg=="], - "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.37.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-m8W2UbxLDcmRKVjgl5J/k4B8d7qX2EcJve3Sut7YGrQoPtCIQGPH5AMzuFvYRWZi0FVS0zEY4c8uttPfX6bwYQ=="], + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.59.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w=="], - "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.37.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-FOMXGmH15OmtQWEt174v9P1JqqhlgYge/bUjIbiVD1nI1NeJ30HYT9SJlZMqdo1uQFyt9cz748F1BHghWaDnVA=="], + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.59.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA=="], - "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.37.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-SZMxNttjPKvV14Hjck5t70xS3l63sbVwl98g3FlVVx2YIDmfUIy29jQrsw06ewEYQ8lQSuY9mpAPlmgRD2iSsA=="], + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.59.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg=="], - "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.37.0", "", { "os": "linux", "cpu": "arm" }, "sha512-hhAALKJPidCwZcj+g+iN+38SIOkhK2a9bqtJR+EtyxrKKSt1ynCBeqrQy31z0oWU6thRZzdx53hVgEbRkuI19w=="], + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw=="], - "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.37.0", "", { "os": "linux", "cpu": "arm" }, "sha512-jUb/kmn/Gd8epbHKEqkRAxq5c2EwRt0DqhSGWjPFxLeFvldFdHQs/n8lQ9x85oAeVb6bHcS8irhTJX2FCOd8Ag=="], + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA=="], - "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.37.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-oNrJxcQT9IcbcmKlkF+Yz2tmOxZgG9D9GRq+1OE6XCQwCVwxixYAa38Z8qqPzQvzt1FCfmrHX03E0pWoXm1DqA=="], + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA=="], - "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.37.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-pfxLBMls+28Ey2enpX3JvjEjaJMBX5XlPCZNGxj4kdJyHduPBXtxYeb8alo0a7bqOoWZW2uKynhHxF/MWoHaGQ=="], + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA=="], - "@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.37.0", "", { "os": "linux", "cpu": "none" }, "sha512-yCE0NnutTC/7IGUq/PUHmoeZbIwq3KRh02e9SfFh7Vmc1Z7atuJRYWhRME5fKgT8aS20mwi1RyChA23qSyRGpA=="], + "@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-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.37.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-NxcICptHk06E2Lh3a4Pu+2PEdZ6ahNHuK7o6Np9zcWkrBMuv21j10SQDJW3C9Yf/A/P7cutWoC/DptNLVsZ0VQ=="], + "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q=="], - "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.37.0", "", { "os": "linux", "cpu": "none" }, "sha512-PpWwHMPCVpFZLTfLq7EWJWvrmEuLdGn1GMYcm5MV7PaRgwCEYJAwiN94uBuZev0/J/hFIIJCsYw4nLmXA9J7Pw=="], + "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.59.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA=="], - "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.37.0", "", { "os": "linux", "cpu": "none" }, "sha512-DTNwl6a3CfhGTAOYZ4KtYbdS8b+275LSLqJVJIrPa5/JuIufWWZ/QFvkxp52gpmguN95eujrM68ZG+zVxa8zHA=="], + "@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-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.37.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-hZDDU5fgWvDdHFuExN1gBOhCuzo/8TMpidfOR+1cPZJflcEzXdCy1LjnklQdW8/Et9sryOPJAKAQRw8Jq7Tg+A=="], + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg=="], - "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.37.0", "", { "os": "linux", "cpu": "x64" }, "sha512-pKivGpgJM5g8dwj0ywBwe/HeVAUSuVVJhUTa/URXjxvoyTT/AxsLTAbkHkDHG7qQxLoW2s3apEIl26uUe08LVQ=="], + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg=="], - "@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-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.59.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w=="], - "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.37.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-Jm7biMazjNzTU4PrQtr7VS8ibeys9Pn29/1bm4ph7CP2kf21950LgN+BaE2mJ1QujnvOc6p54eWWiVvn05SOBg=="], + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg=="], - "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.37.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-e3/1SFm1OjefWICB2Ucstg2dxYDkDTZGDYgwufcbsxTHyqQps1UQf33dFEChBNmeSsTOyrjw2JJq0zbG5GF6RA=="], + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg=="], - "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.37.0", "", { "os": "win32", "cpu": "x64" }, "sha512-LWbXUBwn/bcLx2sSsqy7pK5o+Nr+VCoRoAohfJ5C/aBio9nfJmGQqHAhU6pwxV/RmyTk5AqdySma7uwWGlmeuA=="], + "@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.59.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A=="], + + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.59.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA=="], + + "@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.59.0", "", { "os": "win32", "cpu": "x64" }, "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA=="], "@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.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-xolrFw6b+2iYGl6EcOL7IJY71vvyZ0DJ3mcKtpykqPe2uscwtzDZJa1uVQXyP7w9Dd+kGwYnPbMsJrGISKiY/Q=="], - "@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.13", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/types": "^4.13.1", "@smithy/util-config-provider": "^4.2.2", "@smithy/util-endpoints": "^3.3.3", "@smithy/util-middleware": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-iIzMC5NmOUP6WL6o8iPBjFhUhBZ9pPjpUpQYWMUFQqKyXXzOftbfK8zcQCz/jFV1Psmf05BK5ypx4K2r4Tnwdg=="], - "@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.12", "", { "dependencies": { "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-middleware": "^4.2.12", "@smithy/util-stream": "^4.5.20", "@smithy/util-utf8": "^4.2.2", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-o9VycsYNtgC+Dy3I0yrwCqv9CWicDnke0L7EVOrZtJpjb2t0EjaEofmMrYc0T1Kn3yk32zm6cspxF9u9Bj7e5w=="], "@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.12", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.13.1", "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FE3bZdEl62ojmy8x4FHqxq2+BuOHlcxiH5vaZ6aqHJr3AIZzwF5jfx8dEiU/X0a8RboyNDjmXjlbr8AdEyLgiA=="], - "@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.12", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-XUSuMxlTxV5pp4VpqZf6Sa3vT/Q75FVkLSpSSE3KkWBvAQWeuWt1msTv8fJfgA4/jcJhrbrbMzN1AC/hvPmm5A=="], - "@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.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-7epsAZ3QvfHkngz6RXQYseyZYHlmWXSTPOfPmXkiS+zA6TBNo1awUaMFL9vxyXlGdoELmCZyZe1nQE+imbmV+Q=="], - "@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.12", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-D1pFuExo31854eAvg89KMn9Oab/wEeJR6Buy32B49A9Ogdtx5fwZPqBHUlDzaCDpycTFk2+fSQgX689Qsk7UGA=="], - "@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.12", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-+yNuTiyBACxOJUTvbsNsSOfH9G9oKbaJE1lNL3YHpGcuucl6rPZMi3nrpehpVOVR2E07YqFFmtwpImtpzlouHQ=="], - "@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.15", "", { "dependencies": { "@smithy/protocol-http": "^5.3.12", "@smithy/querystring-builder": "^4.2.12", "@smithy/types": "^4.13.1", "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-T4jFU5N/yiIfrtrsb9uOQn7RdELdM/7HbyLNr6uO/mpkj1ctiVs7CihVr51w4LyQlXWDpXFn4BElf1WmQvZu/A=="], - "@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.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-QhBYbGrbxTkZ43QoTPrK72DoYviDeg6YKDrHTMJbbC+A0sml3kSjzFtXP7BtbyJnXojLfTQldGdUR0RGD8dA3w=="], - "@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.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-/4F1zb7Z8LOu1PalTdESFHR0RbPwHd3FcaG1sI3UEIriQTWakysgJr65lc1jj6QY5ye7aFsisajotH6UhWfm/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.12", "", { "dependencies": { "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-YE58Yz+cvFInWI/wOTrB+DbvUVz/pLn5mC5MvOV4fdRUc6qGwygyngcucRQjAhiCEbmfLOXX0gntSIcgMvAjmA=="], - "@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.27", "", { "dependencies": { "@smithy/core": "^3.23.12", "@smithy/middleware-serde": "^4.2.15", "@smithy/node-config-provider": "^4.3.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-middleware": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-T3TFfUgXQlpcg+UdzcAISdZpj4Z+XECZ/cefgA6wLBd6V4lRi0svN2hBouN/be9dXQ31X4sLWz3fAQDf+nt6BA=="], - "@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.44", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/protocol-http": "^5.3.12", "@smithy/service-error-classification": "^4.2.12", "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "@smithy/util-middleware": "^4.2.12", "@smithy/util-retry": "^4.2.12", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-Y1Rav7m5CFRPQyM4CI0koD/bXjyjJu3EQxZZhtLGD88WIrBrQ7kqXM96ncd6rYnojwOo/u9MXu57JrEvu/nLrA=="], - "@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.15", "", { "dependencies": { "@smithy/core": "^3.23.12", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-ExYhcltZSli0pgAKOpQQe1DLFBLryeZ22605y/YS+mQpdNWekum9Ujb/jMKfJKgjtz1AZldtwA/wCYuKJgjjlg=="], - "@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.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-kruC5gRHwsCOuyCd4ouQxYjgRAym2uDlCvQ5acuMtRrcdfg7mFBg6blaxcJ09STpt3ziEkis6bhg1uwrWU7txw=="], - "@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.12", "", { "dependencies": { "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-tr2oKX2xMcO+rBOjobSwVAkV05SIfUKz8iI53rzxEmgW3GOOPOv0UioSDk+J8OpRQnpnhsO3Af6IEBabQBVmiw=="], - "@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.5.0", "", { "dependencies": { "@smithy/abort-controller": "^4.2.12", "@smithy/protocol-http": "^5.3.12", "@smithy/querystring-builder": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-Rnq9vQWiR1+/I6NZZMNzJHV6pZYyEHt2ZnuV3MG8z2NNenC4i/8Kzttz7CjZiHSmsN5frhXhg17z3Zqjjhmz1A=="], "@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.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-fit0GZK9I1xoRlR4jXmbLhoN0OdEpa96ul8M65XdmXnxXkuMxM0Y8HDT0Fh0Xb4I85MBvBClOzgSrV1X2s1Hxw=="], - "@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.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-6wTZjGABQufekycfDGMEB84BgtdOE/rCVTov+EDXQ8NHKTUNIp/j27IliwP7tjIU9LR+sSzyGBOXjeEtVgzCHg=="], - "@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.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-P2OdvrgiAKpkPNKlKUtWbNZKB1XjPxM086NeVhK+W+wI46pIKdWBe5QyXvhUm3MEcyS/rkLvY8rZzyUdmyDZBw=="], - "@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.12", "", { "dependencies": { "@smithy/types": "^4.13.1" } }, "sha512-LlP29oSQN0Tw0b6D0Xo6BIikBswuIiGYbRACy5ujw/JgWSzTdYj46U83ssf6Ux0GyNJVivs2uReU8pt7Eu9okQ=="], - "@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.7", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-HrOKWsUb+otTeo1HxVWeEb99t5ER1XrBi/xka2Wv6NVmTbuCUC1dvlrksdvxFtODLBjsC+PHK+fuy2x/7Ynyiw=="], - "@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.12", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-middleware": "^4.2.12", "@smithy/util-uri-escape": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-B/FBwO3MVOL00DaRSXfXfa/TRXRheagt/q5A2NM13u7q+sHS59EOVGQNfG7DkmVtdQm5m3vOosoKAXSqn/OEgw=="], - "@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.7", "", { "dependencies": { "@smithy/core": "^3.23.12", "@smithy/middleware-endpoint": "^4.4.27", "@smithy/middleware-stack": "^4.2.12", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/util-stream": "^4.5.20", "tslib": "^2.6.2" } }, "sha512-q3gqnwml60G44FECaEEsdQMplYhDMZYCtYhMCzadCnRnnHIobZJjegmdoUo6ieLQlPUzvrMdIJUpx6DoPmzANQ=="], - "@smithy/types": ["@smithy/types@4.8.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-N0Zn0OT1zc+NA+UVfkYqQzviRh5ucWwO7mBV3TmHHprMnfcJNfhlPicDkBHi0ewbh+y3evR6cNAW0Raxvb01NA=="], + "@smithy/types": ["@smithy/types@4.13.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-787F3yzE2UiJIQ+wYW1CVg2odHjmaWLGksnKQHUrK/lYZSEcy1msuLVvxaR/sI2/aDe9U+TBuLsXnr3vod1g0g=="], - "@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.12", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-wOPKPEpso+doCZGIlr+e1lVI6+9VAKfL4kZWFgzVgGWY2hZxshNKod4l2LXS3PRC9otH/JRSjtEHqQ/7eLciRA=="], - "@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.43", "", { "dependencies": { "@smithy/property-provider": "^4.2.12", "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-Qd/0wCKMaXxev/z00TvNzGCH2jlKKKxXP1aDxB6oKwSQthe3Og2dMhSayGCnsma1bK/kQX1+X7SMP99t6FgiiQ=="], - "@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.47", "", { "dependencies": { "@smithy/config-resolver": "^4.4.13", "@smithy/credential-provider-imds": "^4.2.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/property-provider": "^4.2.12", "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-qSRbYp1EQ7th+sPFuVcVO05AE0QH635hycdEXlpzIahqHHf2Fyd/Zl+8v0XYMJ3cgDVPa0lkMefU7oNUjAP+DQ=="], - "@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.3", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-VACQVe50j0HZPjpwWcjyT51KUQ4AnsvEaQ2lKHOSL4mNLD0G9BjEniQ+yCt1qqfKfiAHRAts26ud7hBjamrwig=="], - "@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.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-Er805uFUOvgc0l8nv0e0su0VFISoxhJ/AwOn3gL2NWNY2LUEldP5WtVcRYSQBcjg0y9NfG8JYrCJaYDpupBHJQ=="], - "@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.12", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-1zopLDUEOwumjcHdJ1mwBHddubYF8GMQvstVCLC54Y46rqoHwlIU+8ZzUeaBcD+WCJHyDGSeZ2ml9YSe9aqcoQ=="], - "@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.20", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.15", "@smithy/node-http-handler": "^4.5.0", "@smithy/types": "^4.13.1", "@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-4yXLm5n/B5SRBR2p8cZ90Sbv4zL4NKsgxdzCzp/83cXw2KxLEumt5p+GAVyRNZgQOSrzXn9ARpO0lUe8XSlSDw=="], - "@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=="], @@ -1881,12 +2013,10 @@ "@testing-library/user-event": ["@testing-library/user-event@14.5.2", "", { "peerDependencies": { "@testing-library/dom": ">=7.21.4" } }, "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ=="], + "@tokenizer/inflate": ["@tokenizer/inflate@0.4.1", "", { "dependencies": { "debug": "^4.4.3", "token-types": "^6.1.1" } }, "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA=="], + "@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 +2043,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 +2117,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=="], @@ -1965,7 +2157,7 @@ "@types/multer": ["@types/multer@1.4.13", "", { "dependencies": { "@types/express": "*" } }, "sha512-bhhdtPw7JqCiEfC9Jimx5LqX9BDIPJEh2q/fQ4bqbBPtyEZYr3cvF22NwG0DmPZNYA0CAf2CnqDB4KIGGpJcaw=="], - "@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], + "@types/node": ["@types/node@20.19.37", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw=="], "@types/node-fetch": ["@types/node-fetch@2.6.13", "", { "dependencies": { "@types/node": "*", "form-data": "^4.0.4" } }, "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw=="], @@ -2011,10 +2203,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=="], @@ -2023,6 +2219,8 @@ "@types/yargs-parser": ["@types/yargs-parser@21.0.3", "", {}, "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ=="], + "@types/yauzl": ["@types/yauzl@2.10.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q=="], + "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.24.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.24.0", "@typescript-eslint/type-utils": "8.24.0", "@typescript-eslint/utils": "8.24.0", "@typescript-eslint/visitor-keys": "8.24.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-aFcXEJJCI4gUdXgoo/j9udUYIHgF23MFkg09LFz2dzEmU0+1Plk4rQWv/IYKvPHAtlkkGoB3m5e6oUp+JPsNaQ=="], "@typescript-eslint/parser": ["@typescript-eslint/parser@8.24.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.24.0", "@typescript-eslint/types": "8.24.0", "@typescript-eslint/typescript-estree": "8.24.0", "@typescript-eslint/visitor-keys": "8.24.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-MFDaO9CYiard9j9VepMNa9MTcqVvSny2N4hkY6roquzj8pdCBRENhErrteaQuu7Yjn1ppk0v1/ZF9CG3KIlrTA=="], @@ -2039,6 +2237,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 +2279,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 +2295,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 +2303,12 @@ "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=="], + "ai-tokenizer": ["ai-tokenizer@1.0.6", "", { "peerDependencies": { "ai": "^5.0.0" }, "optionalPeers": ["ai"] }, "sha512-GaakQFxen0pRH/HIA4v68ZM40llCH27HUYUSBLK+gVuZ57e53pYJe1xFvSTj4sJJjbWU92m1X6NjPWyeWkFDow=="], + + "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 +2325,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=="], @@ -2205,13 +2369,13 @@ "at-least-node": ["at-least-node@1.0.0", "", {}, "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg=="], - "autoprefixer": ["autoprefixer@10.4.20", "", { "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" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": "bin/autoprefixer" }, "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g=="], + "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=="], "available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="], "axe-core": ["axe-core@4.10.2", "", {}, "sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w=="], - "axios": ["axios@1.12.1", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-Kn4kbSXpkFHCGE6rBFNwIv0GQs4AvDT80jlveJDKFxjbTYMUeB4QtsdPCv6H8Cm19Je7IU6VFtRl2zWZI0rudQ=="], + "axios": ["axios@1.13.6", "", { "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } }, "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ=="], "axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="], @@ -2223,11 +2387,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 +2417,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 +2425,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=="], @@ -2289,7 +2455,7 @@ "browserify-zlib": ["browserify-zlib@0.2.0", "", { "dependencies": { "pako": "~1.0.5" } }, "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA=="], - "browserslist": ["browserslist@4.24.4", "", { "dependencies": { "caniuse-lite": "^1.0.30001688", "electron-to-chromium": "^1.5.73", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.1" }, "bin": "cli.js" }, "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A=="], + "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=="], "bser": ["bser@2.1.1", "", { "dependencies": { "node-int64": "^0.4.0" } }, "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ=="], @@ -2351,9 +2517,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 +2587,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 +2615,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 +2643,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 +2659,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 +2673,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=="], @@ -2525,9 +2765,9 @@ "date-fns": ["date-fns@3.3.1", "", {}, "sha512-y8e109LYGgoQDveiEBD3DYXKba1jWf5BA8YU1FL5Tvm0BTdEfy54WLCwnuYWZNnzzvALy/QQ4Hov+Q9RVRv+Zw=="], - "dayjs": ["dayjs@1.11.13", "", {}, "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="], + "dayjs": ["dayjs@1.11.19", "", {}, "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw=="], - "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 +2793,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 +2819,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 +2843,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 +2853,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=="], @@ -2621,7 +2865,7 @@ "ejs": ["ejs@3.1.10", "", { "dependencies": { "jake": "^10.8.5" }, "bin": "bin/cli.js" }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="], - "electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="], + "electron-to-chromium": ["electron-to-chromium@1.5.307", "", {}, "sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg=="], "elliptic": ["elliptic@6.6.1", "", { "dependencies": { "bn.js": "^4.11.9", "brorand": "^1.1.0", "hash.js": "^1.0.0", "hmac-drbg": "^1.0.1", "inherits": "^2.0.4", "minimalistic-assert": "^1.0.1", "minimalistic-crypto-utils": "^1.0.1" } }, "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g=="], @@ -2639,7 +2883,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 +2899,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 +2913,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 +2925,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 +2995,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 +3027,9 @@ "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-builder": ["fast-xml-builder@1.1.4", "", { "dependencies": { "path-expression-matcher": "^1.1.3" } }, "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg=="], + + "fast-xml-parser": ["fast-xml-parser@5.5.7", "", { "dependencies": { "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.1.3", "strnum": "^2.2.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-LteOsISQ2GEiDHZch6L9hB0+MLoYVLToR7xotrzU0opCICBkxOPgHAy1HxAvtxfJNXDJpgAsQN30mkrfpO2Prg=="], "fastq": ["fastq@1.17.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w=="], @@ -2807,7 +3049,7 @@ "file-stream-rotator": ["file-stream-rotator@0.6.1", "", { "dependencies": { "moment": "^2.29.1" } }, "sha512-u+dBid4PvZw17PmDeRcNOtCP9CCK/9lRN2w+r1xIS7yOL9JFrIBKTvrYsxT4P0pGtThYTn++QS5ChHaUov3+zQ=="], - "file-type": ["file-type@18.7.0", "", { "dependencies": { "readable-web-to-node-stream": "^3.0.2", "strtok3": "^7.0.0", "token-types": "^5.0.1" } }, "sha512-ihHtXRzXEziMrQ56VSgU7wkxh55iNchFkosu7Y9/S+tXHdKyrGjVK0ujbqNnsxzea+78MaLhN6PGmfYSAv1ACw=="], + "file-type": ["file-type@21.3.3", "", { "dependencies": { "@tokenizer/inflate": "^0.4.1", "strtok3": "^10.3.4", "token-types": "^6.1.1", "uint8array-extras": "^1.4.0" } }, "sha512-pNwbwz8c3aZ+GvbJnIsCnDjKvgCZLHxkFWLEFxU3RMa+Ey++ZSEfisvsWQMcdys6PpxQjWUOIDi1fifXsW3YRg=="], "filelist": ["filelist@1.0.4", "", { "dependencies": { "minimatch": "^5.0.1" } }, "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q=="], @@ -2833,7 +3075,7 @@ "fn.name": ["fn.name@1.1.0", "", {}, "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="], - "follow-redirects": ["follow-redirects@1.15.9", "", {}, "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ=="], + "follow-redirects": ["follow-redirects@1.15.11", "", {}, "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ=="], "for-each": ["for-each@0.3.3", "", { "dependencies": { "is-callable": "^1.1.3" } }, "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw=="], @@ -2849,7 +3091,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 +3109,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 +3139,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 +3151,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 +3159,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 +3215,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 +3267,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 +3293,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=="], @@ -3155,7 +3401,7 @@ "is-wsl": ["is-wsl@3.1.0", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw=="], - "isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], + "isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="], "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], @@ -3215,7 +3461,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 +3477,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 +3529,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 +3545,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 +3573,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 +3585,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 +3623,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 +3635,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 +3655,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 +3719,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 +3805,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,13 +3845,13 @@ "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=="], "mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="], - "nanoid": ["nanoid@3.3.8", "", { "bin": "bin/nanoid.cjs" }, "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w=="], + "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], "napi-postinstall": ["napi-postinstall@0.3.4", "", { "bin": "lib/cli.js" }, "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ=="], @@ -3605,6 +3871,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=="], @@ -3617,8 +3885,6 @@ "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], - "normalize-range": ["normalize-range@0.1.2", "", {}, "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA=="], - "normalize-url": ["normalize-url@6.1.0", "", {}, "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A=="], "npm-run-path": ["npm-run-path@5.3.0", "", { "dependencies": { "path-key": "^4.0.0" } }, "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ=="], @@ -3651,6 +3917,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 +3939,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 +3965,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,25 +4009,29 @@ "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-expression-matcher": ["path-expression-matcher@1.2.0", "", {}, "sha512-DwmPWeFn+tq7TiyJ2CxezCAirXjFxvaiD03npak3cRjlP9+OjTmSy1EpIrEbh+l6JgUundniloMLDQ/6VTdhLQ=="], + "path-is-absolute": ["path-is-absolute@1.0.1", "", {}, "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="], "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], "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=="], - "peek-readable": ["peek-readable@5.0.0", "", {}, "sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A=="], + "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=="], "pend": ["pend@1.2.0", "", {}, "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="], @@ -3773,37 +4049,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": ["postcss@8.5.8", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg=="], - "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 +4095,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 +4141,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 +4161,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 +4181,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 +4215,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 +4223,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 +4237,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 +4277,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=="], @@ -4033,9 +4305,7 @@ "read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="], - "readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], - - "readable-web-to-node-stream": ["readable-web-to-node-stream@3.0.2", "", { "dependencies": { "readable-stream": "^3.6.0" } }, "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw=="], + "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=="], "readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], @@ -4057,8 +4327,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 +4365,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,11 +4381,13 @@ "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=="], - "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=="], + "robust-predicates": ["robust-predicates@3.0.2", "", {}, "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg=="], + + "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=="], "rollup-plugin-peer-deps-external": ["rollup-plugin-peer-deps-external@2.2.4", "", { "peerDependencies": { "rollup": "*" } }, "sha512-AWdukIM1+k5JDdAqV/Cxd+nejvno2FVLVeZ74NKggm3Q5s9cbbcOgUPGdbxPi4BXu7xGaZ8HG12F+thImYu/0g=="], @@ -4129,6 +4397,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 +4407,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 +4429,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 +4507,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,9 +4569,9 @@ "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=="], + "strtok3": ["strtok3@10.3.4", "", { "dependencies": { "@tokenizer/token": "^0.3.0" } }, "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg=="], "style-inject": ["style-inject@0.3.0", "", {}, "sha512-IezA2qp+vcdlhJaVm5SOdPPTUu0FCEqfNSli2vRuSIBbu5Nq5UvygTk/VzeCqfLz2Atj3dVII5QBKGZRZ0edzw=="], @@ -4309,6 +4581,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 +4595,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 +4625,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=="], @@ -4361,13 +4635,13 @@ "thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="], - "tiktoken": ["tiktoken@1.0.15", "", {}, "sha512-sCsrq/vMWUSEW29CJLNmPvWxlVp7yh2tlkAjpJltIKqp5CKf98ZNpdeHRmAlPVFlGEbswDc6SmI8vz64W/qErw=="], - "timers-browserify": ["timers-browserify@2.0.12", "", { "dependencies": { "setimmediate": "^1.0.4" } }, "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ=="], "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=="], @@ -4383,7 +4657,7 @@ "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], - "token-types": ["token-types@5.0.1", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg=="], + "token-types": ["token-types@6.1.2", "", { "dependencies": { "@borewit/text-codec": "^0.2.1", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww=="], "touch": ["touch@3.1.0", "", { "dependencies": { "nopt": "~1.0.10" }, "bin": { "nodetouch": "bin/nodetouch.js" } }, "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA=="], @@ -4403,8 +4677,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 +4691,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,19 +4733,25 @@ "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=="], "uid2": ["uid2@0.0.4", "", {}, "sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA=="], + "uint8array-extras": ["uint8array-extras@1.5.0", "", {}, "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A=="], + "unbox-primitive": ["unbox-primitive@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", "has-symbols": "^1.1.0", "which-boxed-primitive": "^1.1.1" } }, "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw=="], "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-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + "undici": ["undici@7.24.4", "", {}, "sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w=="], + + "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], "unicode-canonical-property-names-ecmascript": ["unicode-canonical-property-names-ecmascript@2.0.1", "", {}, "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg=="], @@ -4489,16 +4787,12 @@ "upath": ["upath@1.2.0", "", {}, "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg=="], - "update-browserslist-db": ["update-browserslist-db@1.1.2", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg=="], + "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=="], "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], "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 +4829,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 +4895,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 +4937,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 +4949,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=="], @@ -4665,17 +4967,15 @@ "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], - "yauzl": ["yauzl@3.2.0", "", { "dependencies": { "buffer-crc32": "~0.2.3", "pend": "~1.2.0" } }, "sha512-Ow9nuGZE+qp1u4JIPvg+uCiUr7xGQWdff7JQSk5VGYTAZMDe2q8lxJ10ygv10qmSj031Ty/6FNJpLO4o1Sgc+w=="], + "yauzl": ["yauzl@3.2.1", "", { "dependencies": { "buffer-crc32": "~0.2.3", "pend": "~1.2.0" } }, "sha512-k1isifdbpNSFEHFJ1ZY4YDewv0IH9FR61lDetaRMD3j2ae3bIXGV+7c+LHCqtQGofSd8PIyV4X6+dHMAnSr60A=="], "yn": ["yn@3.1.1", "", {}, "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q=="], "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 +5035,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 +5061,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 +5081,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 +5205,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 +5225,85 @@ "@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-s3/@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/client-s3/@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/client-s3/@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/client-s3/@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/client-s3/@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/client-s3/@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/client-s3/@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/client-s3/@aws-sdk/types": ["@aws-sdk/types@3.973.5", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ=="], + + "@aws-sdk/client-s3/@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/client-s3/@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/client-s3/@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/client-s3/@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=="], + + "@aws-sdk/client-s3/@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=="], + + "@aws-sdk/client-s3/@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=="], + + "@aws-sdk/client-s3/@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=="], + + "@aws-sdk/client-s3/@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=="], + + "@aws-sdk/client-s3/@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=="], + + "@aws-sdk/client-s3/@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=="], + + "@aws-sdk/client-s3/@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-cGNMrgykRmddrNhYy1yBdrp5GwIgEkniS7k9O1VLB38yxQtlvrxpZtUVvo6T4cKpeZsriukBuuxfJcdZQc/f/g=="], + + "@aws-sdk/client-s3/@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=="], + + "@aws-sdk/client-s3/@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=="], + + "@aws-sdk/client-s3/@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=="], + + "@aws-sdk/client-s3/@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=="], + + "@aws-sdk/client-s3/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-s+eenEPW6RgliDk2IhjD2hWOxIx1NKrOHxEwNUaUXxYBxIyCcDfNULZ2Mu15E3kwcJWBedTET/kEASPV1A1Akg=="], + + "@aws-sdk/client-s3/@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=="], + + "@aws-sdk/client-s3/@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=="], + + "@aws-sdk/client-s3/@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=="], + + "@aws-sdk/client-s3/@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=="], + + "@aws-sdk/client-s3/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="], + + "@aws-sdk/client-s3/@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=="], + + "@aws-sdk/client-s3/@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=="], + + "@aws-sdk/client-s3/@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=="], + + "@aws-sdk/client-s3/@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=="], + + "@aws-sdk/client-s3/@smithy/util-middleware": ["@smithy/util-middleware@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-r3dtF9F+TpSZUxpOVVtPfk09Rlo4lT6ORBqEvX3IBT6SkQAdDSVKR5GcfmZbtl7WKhKnmb3wbDTQ6ibR2XHClw=="], + + "@aws-sdk/client-s3/@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=="], + + "@aws-sdk/client-s3/@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=="], "@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 +5447,9 @@ "@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.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="], + + "@aws-sdk/crc64-nvme/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="], "@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 +5479,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.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="], - "@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.20", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-vI0QN96DFx3g9AunfOWF3CS4cMkqFiR/WM/FyP9QHr5rZ2dKPkYwP3tCgAOvGuu9CXI7dC1vU2FVUuZ+tfpNvQ=="], - "@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.22", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/types": "^3.973.6", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/node-http-handler": "^4.5.0", "@smithy/property-provider": "^4.2.12", "@smithy/protocol-http": "^5.3.12", "@smithy/smithy-client": "^4.12.6", "@smithy/types": "^4.13.1", "@smithy/util-stream": "^4.5.20", "tslib": "^2.6.2" } }, "sha512-aS/81smalpe7XDnuQfOq4LIPuaV2PRKU2aMTrHcqO5BD4HwO5kESOHNcec2AYfBtLtIDqgF6RXisgBnfK/jt0w=="], - "@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.22", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/credential-provider-env": "^3.972.20", "@aws-sdk/credential-provider-http": "^3.972.22", "@aws-sdk/credential-provider-login": "^3.972.22", "@aws-sdk/credential-provider-process": "^3.972.20", "@aws-sdk/credential-provider-sso": "^3.972.22", "@aws-sdk/credential-provider-web-identity": "^3.972.22", "@aws-sdk/nested-clients": "^3.996.12", "@aws-sdk/types": "^3.973.6", "@smithy/credential-provider-imds": "^4.2.12", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-rpF8fBT0LllMDp78s62aL2A/8MaccjyJ0ORzqu+ZADeECLSrrCWIeeXsuRam+pxiAMkI1uIyDZJmgLGdadkPXw=="], - "@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.20", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-QRfk7GbA4/HDRjhP3QYR6QBr/QKreVoOzvvlRHnOuGgYJkeoPgPY3LAI1kK1ZMgZ4hH9KiGp757/ntol+INAig=="], - "@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.22", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/nested-clients": "^3.996.12", "@aws-sdk/token-providers": "3.1013.0", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-4vqlSaUbBj4aNPVKfB6yXuIQ2Z2mvLfIGba2OzzF6zUkN437/PGWsxBU2F8QPSFHti6seckvyCXidU3H+R8NvQ=="], - "@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.22", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/nested-clients": "^3.996.12", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-/wN1CYg2rVLhW8/jLxMWacQrkpaynnL+4j/Z+e6X1PfoE6NiC0BeOw3i0JmtZrKun85wNV5GmspvuWJihfeeUw=="], - "@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.12", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/property-provider": "^4.2.12", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-cr2lR792vNZcYMriSIj+Um3x9KWrjcu98kn234xA6reOAFMmbRpQMOv8KPgEmLLtx3eldU6c5wALKFqNOhugmg=="], - "@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.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="], "@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,125 +5521,181 @@ "@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-bucket-endpoint/@aws-sdk/types": ["@aws-sdk/types@3.973.5", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ=="], - "@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/middleware-bucket-endpoint/@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=="], - "@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/middleware-bucket-endpoint/@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=="], - "@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/middleware-bucket-endpoint/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="], - "@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/middleware-expect-continue/@aws-sdk/types": ["@aws-sdk/types@3.973.5", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ=="], - "@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/middleware-expect-continue/@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=="], - "@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/middleware-expect-continue/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="], - "@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/middleware-flexible-checksums/@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/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-flexible-checksums/@aws-sdk/types": ["@aws-sdk/types@3.973.5", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ=="], - "@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-flexible-checksums/@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=="], - "@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-flexible-checksums/@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=="], - "@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/middleware-flexible-checksums/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="], - "@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/middleware-flexible-checksums/@smithy/util-middleware": ["@smithy/util-middleware@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-r3dtF9F+TpSZUxpOVVtPfk09Rlo4lT6ORBqEvX3IBT6SkQAdDSVKR5GcfmZbtl7WKhKnmb3wbDTQ6ibR2XHClw=="], - "@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/middleware-flexible-checksums/@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=="], - "@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/middleware-location-constraint/@aws-sdk/types": ["@aws-sdk/types@3.973.5", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ=="], - "@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/middleware-location-constraint/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="], - "@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/middleware-sdk-s3/@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/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/middleware-sdk-s3/@aws-sdk/types": ["@aws-sdk/types@3.973.5", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ=="], - "@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/middleware-sdk-s3/@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=="], - "@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/middleware-sdk-s3/@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=="], - "@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/middleware-sdk-s3/@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=="], - "@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/middleware-sdk-s3/@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=="], - "@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/middleware-sdk-s3/@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=="], - "@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/middleware-sdk-s3/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="], - "@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/middleware-sdk-s3/@smithy/util-middleware": ["@smithy/util-middleware@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-r3dtF9F+TpSZUxpOVVtPfk09Rlo4lT6ORBqEvX3IBT6SkQAdDSVKR5GcfmZbtl7WKhKnmb3wbDTQ6ibR2XHClw=="], - "@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/middleware-sdk-s3/@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=="], - "@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/middleware-ssec/@aws-sdk/types": ["@aws-sdk/types@3.973.5", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ=="], - "@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/middleware-ssec/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="], - "@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/middleware-websocket/@aws-sdk/util-format-url": ["@aws-sdk/util-format-url@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/querystring-builder": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-J6DS9oocrgxM8xlUTTmQOuwRF6rnAGEujAN9SAzllcrQmwn5iJ58ogxy3SEhD0Q7JZvlA5jvIXBkpQRqEqlE9A=="], - "@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/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/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/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/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/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/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/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/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/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/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/s3-request-presigner/@smithy/types": ["@smithy/types@4.8.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-N0Zn0OT1zc+NA+UVfkYqQzviRh5ucWwO7mBV3TmHHprMnfcJNfhlPicDkBHi0ewbh+y3evR6cNAW0Raxvb01NA=="], - "@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/signature-v4-multi-region/@aws-sdk/types": ["@aws-sdk/types@3.973.5", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ=="], - "@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/signature-v4-multi-region/@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=="], - "@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/signature-v4-multi-region/@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=="], - "@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/signature-v4-multi-region/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="], - "@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/token-providers/@smithy/property-provider": ["@smithy/property-provider@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="], - "@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/@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=="], "@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=="], + "@babel/helper-annotate-as-pure/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + "@babel/helper-compilation-targets/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/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-class-features-plugin/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], - "@babel/plugin-transform-classes/globals": ["globals@11.12.0", "", {}, "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="], + "@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-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/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/helper-member-expression-to-functions/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], + + "@babel/helper-member-expression-to-functions/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@babel/helper-module-imports/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], + + "@babel/helper-module-imports/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@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=="], + + "@babel/helper-optimise-call-expression/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@babel/helper-remap-async-to-generator/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], + + "@babel/helper-replace-supers/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], + + "@babel/helper-skip-transparent-expression-wrappers/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], + + "@babel/helper-skip-transparent-expression-wrappers/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@babel/helper-wrap-function/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "@babel/helper-wrap-function/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], + + "@babel/helper-wrap-function/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@babel/plugin-bugfix-firefox-class-in-computed-class-key/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], + + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], + + "@babel/plugin-transform-async-generator-functions/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], + + "@babel/plugin-transform-classes/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], + + "@babel/plugin-transform-computed-properties/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "@babel/plugin-transform-destructuring/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], + + "@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-function-name/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], + + "@babel/plugin-transform-modules-amd/@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/plugin-transform-modules-commonjs/@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/plugin-transform-modules-systemjs/@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/plugin-transform-modules-systemjs/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], + + "@babel/plugin-transform-modules-umd/@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/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-object-rest-spread/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], + + "@babel/plugin-transform-react-jsx/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@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 +5703,40 @@ "@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/preset-modules/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], "@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/grpc-js/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], + + "@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,39 +5755,31 @@ "@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/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], "@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/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], "@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/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], - "@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/environment-jsdom-abstract/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], "@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/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], - "@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/pattern/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], "@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/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], - "@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/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/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="], @@ -5413,12 +5787,14 @@ "@jest/test-sequencer/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="], + "@jest/transform/@babel/core": ["@babel/core@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.4", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@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-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw=="], + "@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=="], + "@jest/types/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], + "@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=="], "@jridgewell/remapping/@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,17 +5821,11 @@ "@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/backend/@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=="], - "@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/backend/@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=="], - "@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/client/caniuse-lite": ["caniuse-lite@1.0.30001777", "", {}, "sha512-tmN+fJxroPndC74efCdp12j+0rk0RHwV5Jwa1zWaFVyw2ZxAuPeG8ZgWC3Wz7uSjT3qMRQ5XHZ4COgQmsCMJAQ=="], "@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=="], @@ -5463,20 +5833,20 @@ "@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/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/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=="], @@ -5485,9 +5855,19 @@ "@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/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 +5883,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 +5919,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 +5971,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 +5993,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 +6003,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 +6023,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 +6077,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,62 +6091,90 @@ "@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/hash-blob-browser/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="], - "@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/hash-stream-node/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="], - "@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/md5-js/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="], - "@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.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="], "@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.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="], - "@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.12", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/property-provider": "^4.2.12", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-cr2lR792vNZcYMriSIj+Um3x9KWrjcu98kn234xA6reOAFMmbRpQMOv8KPgEmLLtx3eldU6c5wALKFqNOhugmg=="], - "@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-node/@smithy/property-provider": ["@smithy/property-provider@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="], - "@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-waiter/@smithy/abort-controller": ["@smithy/abort-controller@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-Hj4WoYWMJnSpM6/kchsm4bUNTL9XiSyhvoMb2KIq4VJzyDt7JpGHUZHkVNPZVC7YE1tf8tPeVauxpFBKGW4/KQ=="], - "@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-waiter/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="], "@surma/rollup-plugin-off-main-thread/magic-string": ["magic-string@0.25.9", "", { "dependencies": { "sourcemap-codec": "^1.4.8" } }, "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ=="], "@tanstack/match-sorter-utils/remove-accents": ["remove-accents@0.4.2", "", {}, "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA=="], + "@testing-library/dom/@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=="], + "@testing-library/dom/aria-query": ["aria-query@5.1.3", "", { "dependencies": { "deep-equal": "^2.0.5" } }, "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ=="], "@testing-library/dom/dom-accessibility-api": ["dom-accessibility-api@0.5.16", "", {}, "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg=="], "@testing-library/dom/pretty-format": ["pretty-format@27.5.1", "", { "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" } }, "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ=="], + "@types/babel__core/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], + + "@types/babel__core/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@types/babel__generator/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@types/babel__template/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], + + "@types/babel__template/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@types/babel__traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@types/body-parser/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], + + "@types/connect/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], + + "@types/express-serve-static-core/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], + + "@types/jsdom/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], + + "@types/jsonwebtoken/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], + + "@types/ldapjs/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], + "@types/mdast/@types/unist": ["@types/unist@2.0.10", "", {}, "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="], + "@types/node-fetch/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], + + "@types/send/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], + + "@types/serve-static/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], + "@types/testing-library__jest-dom/@types/jest": ["@types/jest@29.5.12", "", { "dependencies": { "expect": "^29.0.0", "pretty-format": "^29.0.0" } }, "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw=="], "@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/xml-encryption/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], + + "@types/xml2js/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], + + "@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=="], @@ -5751,17 +6189,29 @@ "asn1.js/bn.js": ["bn.js@4.12.2", "", {}, "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw=="], + "autoprefixer/caniuse-lite": ["caniuse-lite@1.0.30001777", "", {}, "sha512-tmN+fJxroPndC74efCdp12j+0rk0RHwV5Jwa1zWaFVyw2ZxAuPeG8ZgWC3Wz7uSjT3qMRQ5XHZ4COgQmsCMJAQ=="], + "babel-jest/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="], "babel-plugin-root-import/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="], + "babel-plugin-transform-import-meta/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "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=="], "browserify-sign/bn.js": ["bn.js@5.2.2", "", {}, "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw=="], - "browserify-sign/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=="], + "browserslist/caniuse-lite": ["caniuse-lite@1.0.30001777", "", {}, "sha512-tmN+fJxroPndC74efCdp12j+0rk0RHwV5Jwa1zWaFVyw2ZxAuPeG8ZgWC3Wz7uSjT3qMRQ5XHZ4COgQmsCMJAQ=="], + + "bun-types/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], "caniuse-api/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=="], @@ -5769,6 +6219,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=="], @@ -5781,34 +6233,74 @@ "compression/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], + "concat-stream/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + "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=="], + "deep-equal/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], + "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=="], + "es-get-iterator/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], + + "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 +6311,23 @@ "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/whatwg-mimetype": ["whatwg-mimetype@3.0.0", "", {}, "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q=="], - "googleapis-common/qs": ["qs@6.13.0", "", { "dependencies": { "side-channel": "^1.0.6" } }, "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg=="], - - "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,12 +6361,22 @@ "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/@babel/core": ["@babel/core@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.4", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@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-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw=="], + + "istanbul-lib-instrument/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], + "istanbul-lib-instrument/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], "istanbul-lib-report/make-dir": ["make-dir@4.0.0", "", { "dependencies": { "semver": "^7.5.3" } }, "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw=="], @@ -5885,102 +6385,96 @@ "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/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], "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/@babel/core": ["@babel/core@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.4", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@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-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw=="], "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-jsdom/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], - "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-environment-node/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], "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-haste-map/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], "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=="], + "jest-message-util/@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=="], + "jest-message-util/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-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-mock/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], "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/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], "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/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], "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=="], + "jest-snapshot/@babel/core": ["@babel/core@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.4", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@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-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw=="], + + "jest-snapshot/@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=="], + + "jest-snapshot/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + "jest-snapshot/@jest/expect-utils": ["@jest/expect-utils@30.2.0", "", { "dependencies": { "@jest/get-type": "30.1.0" } }, "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA=="], "jest-snapshot/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-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-util/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], "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-watcher/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], - "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/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], "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=="], @@ -5993,28 +6487,24 @@ "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=="], - "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 +6517,54 @@ "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/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/follow-redirects": ["follow-redirects@1.15.9", "", {}, "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ=="], + "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=="], + "mongodb-memory-server-core/yauzl": ["yauzl@3.2.0", "", { "dependencies": { "buffer-crc32": "~0.2.3", "pend": "~1.2.0" } }, "sha512-Ow9nuGZE+qp1u4JIPvg+uCiUr7xGQWdff7JQSk5VGYTAZMDe2q8lxJ10ygv10qmSj031Ty/6FNJpLO4o1Sgc+w=="], + + "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=="], + "node-stdlib-browser/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + + "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=="], @@ -6061,6 +6575,8 @@ "parse-entities/@types/unist": ["@types/unist@2.0.10", "", {}, "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="], + "parse-json/@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=="], + "parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], "path-scurry/lru-cache": ["lru-cache@11.2.2", "", {}, "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg=="], @@ -6073,18 +6589,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,14 +6617,16 @@ "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/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-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=="], @@ -6115,6 +6641,8 @@ "read-cache/pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="], + "readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], + "readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], "regjsparser/jsesc": ["jsesc@3.0.2", "", { "bin": "bin/jsesc" }, "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g=="], @@ -6133,10 +6661,14 @@ "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=="], + "rollup/@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], + "rollup-plugin-postcss/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=="], "rollup-plugin-typescript2/@rollup/pluginutils": ["@rollup/pluginutils@4.2.1", "", { "dependencies": { "estree-walker": "^2.0.1", "picomatch": "^2.2.2" } }, "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ=="], @@ -6147,7 +6679,13 @@ "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=="], + + "safe-array-concat/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], + + "safe-push-apply/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], + + "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=="], @@ -6161,6 +6699,10 @@ "static-browser-server/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], + "stream-browserify/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + + "stream-http/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + "string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], "string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], @@ -6173,6 +6715,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,10 +6725,16 @@ "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=="], + "tailwindcss/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=="], + "tailwindcss/postcss-load-config": ["postcss-load-config@4.0.2", "", { "dependencies": { "lilconfig": "^3.0.0", "yaml": "^2.3.4" }, "peerDependencies": { "postcss": ">=8.0.9", "ts-node": ">=9.0.0" } }, "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ=="], "tailwindcss/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=="], @@ -6193,17 +6743,11 @@ "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=="], + "test-exclude/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], - "tinyglobby/picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="], - - "ts-node/diff": ["diff@4.0.2", "", {}, "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="], + "to-buffer/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], "tsconfig-paths/json5": ["json5@1.0.2", "", { "dependencies": { "minimist": "^1.2.0" }, "bin": "lib/cli.js" }, "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA=="], @@ -6225,19 +6769,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=="], + "which-builtin-type/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], - "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=="], + "winston/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], "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=="], + "winston-transport/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], "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 +6789,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 +6837,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 +6863,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 +6877,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 +6903,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 +6941,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,9 +6999,57 @@ "@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/@aws-sdk/core/@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-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-s3/@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/client-s3/@aws-sdk/core/@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=="], + + "@aws-sdk/client-s3/@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/client-s3/@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/client-s3/@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/client-s3/@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/client-s3/@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/client-s3/@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/client-s3/@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/client-s3/@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/client-s3/@aws-sdk/credential-provider-node/@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=="], + + "@aws-sdk/client-s3/@smithy/eventstream-serde-browser/@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=="], + + "@aws-sdk/client-s3/@smithy/eventstream-serde-node/@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=="], + + "@aws-sdk/client-s3/@smithy/fetch-http-handler/@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=="], + + "@aws-sdk/client-s3/@smithy/middleware-endpoint/@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=="], + + "@aws-sdk/client-s3/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0" } }, "sha512-HkMFJZJUhzU3HvND1+Yw/kYWXp4RPDLBWLcK1n+Vqw8xn4y2YiBhdww8IxhkQjP/QlZun5bwm3vcHc8AqIU3zw=="], + + "@aws-sdk/client-s3/@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=="], + + "@aws-sdk/client-s3/@smithy/node-config-provider/@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=="], + + "@aws-sdk/client-s3/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-Hj4WoYWMJnSpM6/kchsm4bUNTL9XiSyhvoMb2KIq4VJzyDt7JpGHUZHkVNPZVC7YE1tf8tPeVauxpFBKGW4/KQ=="], + + "@aws-sdk/client-s3/@smithy/node-http-handler/@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=="], + + "@aws-sdk/client-s3/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-nE3IRNjDltvGcoThD2abTozI1dkSy8aX+a2N1Rs55en5UsdyyIXgGEmevUL3okZFoJC77JgRGe99xYohhsjivQ=="], + + "@aws-sdk/client-s3/@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=="], + + "@aws-sdk/client-s3/@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=="], + + "@aws-sdk/client-s3/@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=="], + + "@aws-sdk/client-s3/@smithy/util-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0" } }, "sha512-HkMFJZJUhzU3HvND1+Yw/kYWXp4RPDLBWLcK1n+Vqw8xn4y2YiBhdww8IxhkQjP/QlZun5bwm3vcHc8AqIU3zw=="], "@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=="], @@ -6589,104 +7137,282 @@ "@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/middleware-bucket-endpoint/@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=="], - "@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/middleware-bucket-endpoint/@smithy/node-config-provider/@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=="], - "@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/middleware-flexible-checksums/@aws-sdk/core/@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-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/middleware-flexible-checksums/@aws-sdk/core/@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=="], - "@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/middleware-flexible-checksums/@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/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/middleware-flexible-checksums/@aws-sdk/core/@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=="], - "@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/middleware-flexible-checksums/@aws-sdk/core/@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=="], - "@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/middleware-flexible-checksums/@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=="], - "@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/middleware-flexible-checksums/@smithy/node-config-provider/@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=="], - "@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/middleware-flexible-checksums/@smithy/util-stream/@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=="], - "@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/middleware-flexible-checksums/@smithy/util-stream/@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=="], - "@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/middleware-sdk-s3/@aws-sdk/core/@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-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/middleware-sdk-s3/@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/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/middleware-sdk-s3/@smithy/core/@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=="], - "@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/middleware-sdk-s3/@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=="], - "@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/middleware-sdk-s3/@smithy/node-config-provider/@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=="], - "@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/middleware-sdk-s3/@smithy/smithy-client/@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=="], - "@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/middleware-sdk-s3/@smithy/smithy-client/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-s+eenEPW6RgliDk2IhjD2hWOxIx1NKrOHxEwNUaUXxYBxIyCcDfNULZ2Mu15E3kwcJWBedTET/kEASPV1A1Akg=="], - "@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/middleware-sdk-s3/@smithy/util-stream/@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=="], - "@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/middleware-sdk-s3/@smithy/util-stream/@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=="], - "@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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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=="], + "@aws-sdk/signature-v4-multi-region/@smithy/signature-v4/@smithy/util-middleware": ["@smithy/util-middleware@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-r3dtF9F+TpSZUxpOVVtPfk09Rlo4lT6ORBqEvX3IBT6SkQAdDSVKR5GcfmZbtl7WKhKnmb3wbDTQ6ibR2XHClw=="], - "@azure/core-xml/fast-xml-parser/strnum": ["strnum@2.0.5", "", {}, "sha512-YAT3K/sgpCUxhxNMrrdhtod3jckkpYwH6JAuwmUdXZsmzH1wUyzTMrrK2wYCEEqlKwrWDd35NeuUkbBy/1iK+Q=="], + "@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=="], + + "@babel/core/@babel/helper-compilation-targets/@babel/compat-data": ["@babel/compat-data@7.29.0", "", {}, "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg=="], + + "@babel/core/@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], + + "@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/electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="], "@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/helper-create-class-features-plugin/@babel/traverse/@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=="], + + "@babel/helper-create-class-features-plugin/@babel/traverse/@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-create-class-features-plugin/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], + + "@babel/helper-create-class-features-plugin/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "@babel/helper-create-class-features-plugin/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@babel/helper-create-class-features-plugin/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + + "@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@babel/helper-member-expression-to-functions/@babel/traverse/@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=="], + + "@babel/helper-member-expression-to-functions/@babel/traverse/@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-member-expression-to-functions/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], + + "@babel/helper-member-expression-to-functions/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "@babel/helper-member-expression-to-functions/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + + "@babel/helper-module-imports/@babel/traverse/@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=="], + + "@babel/helper-module-imports/@babel/traverse/@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-module-imports/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], + + "@babel/helper-module-imports/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "@babel/helper-module-imports/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + + "@babel/helper-remap-async-to-generator/@babel/traverse/@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=="], + + "@babel/helper-remap-async-to-generator/@babel/traverse/@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-remap-async-to-generator/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], + + "@babel/helper-remap-async-to-generator/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "@babel/helper-remap-async-to-generator/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@babel/helper-remap-async-to-generator/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + + "@babel/helper-replace-supers/@babel/traverse/@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=="], + + "@babel/helper-replace-supers/@babel/traverse/@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-replace-supers/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], + + "@babel/helper-replace-supers/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "@babel/helper-replace-supers/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@babel/helper-replace-supers/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + + "@babel/helper-skip-transparent-expression-wrappers/@babel/traverse/@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=="], + + "@babel/helper-skip-transparent-expression-wrappers/@babel/traverse/@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-skip-transparent-expression-wrappers/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], + + "@babel/helper-skip-transparent-expression-wrappers/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "@babel/helper-skip-transparent-expression-wrappers/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + + "@babel/helper-wrap-function/@babel/template/@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=="], + + "@babel/helper-wrap-function/@babel/template/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], + + "@babel/helper-wrap-function/@babel/traverse/@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=="], + + "@babel/helper-wrap-function/@babel/traverse/@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-wrap-function/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], + + "@babel/helper-wrap-function/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + + "@babel/plugin-bugfix-firefox-class-in-computed-class-key/@babel/traverse/@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=="], + + "@babel/plugin-bugfix-firefox-class-in-computed-class-key/@babel/traverse/@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/plugin-bugfix-firefox-class-in-computed-class-key/@babel/traverse/@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/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "@babel/plugin-bugfix-firefox-class-in-computed-class-key/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@babel/plugin-bugfix-firefox-class-in-computed-class-key/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/@babel/traverse/@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=="], + + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/@babel/traverse/@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/plugin-bugfix-v8-static-class-fields-redefine-readonly/@babel/traverse/@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-v8-static-class-fields-redefine-readonly/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + + "@babel/plugin-transform-async-generator-functions/@babel/traverse/@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=="], + + "@babel/plugin-transform-async-generator-functions/@babel/traverse/@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/plugin-transform-async-generator-functions/@babel/traverse/@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-transform-async-generator-functions/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "@babel/plugin-transform-async-generator-functions/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@babel/plugin-transform-async-generator-functions/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + + "@babel/plugin-transform-classes/@babel/traverse/@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=="], + + "@babel/plugin-transform-classes/@babel/traverse/@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/plugin-transform-classes/@babel/traverse/@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-transform-classes/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "@babel/plugin-transform-classes/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@babel/plugin-transform-classes/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + + "@babel/plugin-transform-computed-properties/@babel/template/@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=="], + + "@babel/plugin-transform-computed-properties/@babel/template/@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-transform-computed-properties/@babel/template/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@babel/plugin-transform-destructuring/@babel/traverse/@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=="], + + "@babel/plugin-transform-destructuring/@babel/traverse/@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/plugin-transform-destructuring/@babel/traverse/@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-transform-destructuring/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "@babel/plugin-transform-destructuring/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@babel/plugin-transform-destructuring/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + + "@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-function-name/@babel/traverse/@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=="], + + "@babel/plugin-transform-function-name/@babel/traverse/@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/plugin-transform-function-name/@babel/traverse/@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-transform-function-name/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "@babel/plugin-transform-function-name/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@babel/plugin-transform-function-name/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + + "@babel/plugin-transform-modules-amd/@babel/helper-module-transforms/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], + + "@babel/plugin-transform-modules-commonjs/@babel/helper-module-transforms/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], + + "@babel/plugin-transform-modules-systemjs/@babel/traverse/@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=="], + + "@babel/plugin-transform-modules-systemjs/@babel/traverse/@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/plugin-transform-modules-systemjs/@babel/traverse/@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-transform-modules-systemjs/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "@babel/plugin-transform-modules-systemjs/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@babel/plugin-transform-modules-systemjs/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + + "@babel/plugin-transform-modules-umd/@babel/helper-module-transforms/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], + + "@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-object-rest-spread/@babel/traverse/@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=="], + + "@babel/plugin-transform-object-rest-spread/@babel/traverse/@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/plugin-transform-object-rest-spread/@babel/traverse/@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-transform-object-rest-spread/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "@babel/plugin-transform-object-rest-spread/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@babel/plugin-transform-object-rest-spread/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + + "@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 +7421,21 @@ "@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=="], + + "@grpc/grpc-js/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + + "@grpc/proto-loader/protobufjs/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], "@headlessui/react/@tanstack/react-virtual/@tanstack/virtual-core": ["@tanstack/virtual-core@3.13.12", "", {}, "sha512-1YBOJfRHV4sXUmWsFSf5rQor4Ss82G8dQWLRbnk3GA4jeP8hQt1hxXh0tmflpC0dz3VgEv/1+qwPyLeWkQuPFA=="], @@ -6711,36 +7445,52 @@ "@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/console/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + + "@jest/core/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], "@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-jsdom-abstract/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], - "@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/environment/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], "@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/fake-timers/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], - "@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/pattern/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], - "@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/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], "@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=="], + "@jest/transform/@babel/core/@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=="], + + "@jest/transform/@babel/core/@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=="], + + "@jest/transform/@babel/core/@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=="], + + "@jest/transform/@babel/core/@babel/helpers": ["@babel/helpers@7.28.4", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.28.4" } }, "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w=="], + + "@jest/transform/@babel/core/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], + + "@jest/transform/@babel/core/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "@jest/transform/@babel/core/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], + + "@jest/transform/@babel/core/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@jest/transform/@babel/core/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + + "@jest/types/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + "@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=="], "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/eventstream-handler-node": ["@aws-sdk/eventstream-handler-node@3.922.0", "", { "dependencies": { "@aws-sdk/types": "3.922.0", "@smithy/eventstream-codec": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-DTKHeH1Bk17zSdoa5qXPGwCmZXuhQReqXOVW2/jIVX8NGVvnraH7WppGPlQxBjFtwSSwVTgzH2NVPgediQphNA=="], @@ -6773,6 +7523,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 +7549,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 +7569,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 +7599,99 @@ "@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/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/types": ["@aws-sdk/types@3.973.5", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-cGNMrgykRmddrNhYy1yBdrp5GwIgEkniS7k9O1VLB38yxQtlvrxpZtUVvo6T4cKpeZsriukBuuxfJcdZQc/f/g=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-s+eenEPW6RgliDk2IhjD2hWOxIx1NKrOHxEwNUaUXxYBxIyCcDfNULZ2Mu15E3kwcJWBedTET/kEASPV1A1Akg=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@smithy/util-middleware": ["@smithy/util-middleware@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-r3dtF9F+TpSZUxpOVVtPfk09Rlo4lT6ORBqEvX3IBT6SkQAdDSVKR5GcfmZbtl7WKhKnmb3wbDTQ6ibR2XHClw=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-Hj4WoYWMJnSpM6/kchsm4bUNTL9XiSyhvoMb2KIq4VJzyDt7JpGHUZHkVNPZVC7YE1tf8tPeVauxpFBKGW4/KQ=="], - "@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/backend/@smithy/node-http-handler/@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=="], - "@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/backend/@smithy/node-http-handler/@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=="], - "@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.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="], "@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,22 +7709,20 @@ "@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/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=="], @@ -7147,18 +7733,32 @@ "@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-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=="], + + "@opentelemetry/otlp-transformer/protobufjs/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], + "@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=="], "@radix-ui/react-checkbox/@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-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 +7799,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,25 +7841,51 @@ "@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=="], + "@types/body-parser/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], - "@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=="], + "@types/connect/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], - "@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/express-serve-static-core/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + + "@types/jsdom/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + + "@types/jsonwebtoken/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + + "@types/ldapjs/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + + "@types/node-fetch/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + + "@types/send/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + + "@types/serve-static/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], "@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/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + "@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/xml-encryption/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + + "@types/xml2js/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], "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=="], + "babel-plugin-transform-import-meta/@babel/template/@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=="], - "browserify-sign/readable-stream/isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="], + "babel-plugin-transform-import-meta/@babel/template/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], - "browserify-sign/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], + "babel-plugin-transform-import-meta/@babel/template/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "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=="], + + "bun-types/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + + "caniuse-api/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="], + + "caniuse-api/browserslist/electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="], "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=="], @@ -7271,14 +7901,38 @@ "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/electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="], + + "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/@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=="], + "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/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], + + "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,16 +7941,16 @@ "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=="], - "hast-util-from-html-isomorphic/@types/hast/@types/unist": ["@types/unist@2.0.10", "", {}, "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="], "hast-util-from-html/@types/hast/@types/unist": ["@types/unist@2.0.10", "", {}, "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="], @@ -7317,6 +7971,26 @@ "hastscript/@types/hast/@types/unist": ["@types/unist@2.0.10", "", {}, "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="], + "istanbul-lib-instrument/@babel/core/@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=="], + + "istanbul-lib-instrument/@babel/core/@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=="], + + "istanbul-lib-instrument/@babel/core/@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=="], + + "istanbul-lib-instrument/@babel/core/@babel/helpers": ["@babel/helpers@7.28.4", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.28.4" } }, "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w=="], + + "istanbul-lib-instrument/@babel/core/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "istanbul-lib-instrument/@babel/core/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], + + "istanbul-lib-instrument/@babel/core/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "istanbul-lib-instrument/@babel/core/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + + "istanbul-lib-instrument/@babel/core/semver": ["semver@6.3.1", "", { "bin": "bin/semver.js" }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "istanbul-lib-instrument/@babel/parser/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + "istanbul-lib-report/make-dir/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], "istanbul-lib-report/supports-color/has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], @@ -7333,10 +8007,32 @@ "jest-changed-files/execa/strip-final-newline": ["strip-final-newline@2.0.0", "", {}, "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="], + "jest-circus/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + "jest-circus/pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="], + "jest-config/@babel/core/@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=="], + + "jest-config/@babel/core/@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=="], + + "jest-config/@babel/core/@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=="], + + "jest-config/@babel/core/@babel/helpers": ["@babel/helpers@7.28.4", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.28.4" } }, "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w=="], + + "jest-config/@babel/core/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], + + "jest-config/@babel/core/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "jest-config/@babel/core/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], + + "jest-config/@babel/core/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "jest-config/@babel/core/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + "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,30 +8041,60 @@ "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-environment-jsdom/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + + "jest-environment-node/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + + "jest-haste-map/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], "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-mock/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], - "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-runner/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + + "jest-runtime/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], "jest-runtime/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], + "jest-runtime/glob/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], + "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/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-snapshot/@babel/core/@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=="], + + "jest-snapshot/@babel/core/@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=="], + + "jest-snapshot/@babel/core/@babel/helpers": ["@babel/helpers@7.28.4", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.28.4" } }, "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w=="], + + "jest-snapshot/@babel/core/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], + + "jest-snapshot/@babel/core/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "jest-snapshot/@babel/core/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], + + "jest-snapshot/@babel/core/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + + "jest-snapshot/@babel/core/semver": ["semver@6.3.1", "", { "bin": "bin/semver.js" }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "jest-snapshot/@babel/generator/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], + + "jest-snapshot/@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=="], "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-util/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], "jest-validate/pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="], + "jest-watcher/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + + "jest-worker/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + "jest-worker/supports-color/has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], "jsdom/whatwg-url/tr46": ["tr46@5.1.1", "", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw=="], @@ -7377,138 +8103,6 @@ "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=="], - "log-update/slice-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="], "log-update/slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@5.0.0", "", { "dependencies": { "get-east-asian-width": "^1.0.0" } }, "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA=="], @@ -7529,17 +8123,39 @@ "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/electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="], + "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/electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="], + "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/electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="], + "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/electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="], + "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/electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="], + "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-reduce-initial/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="], + + "postcss-reduce-initial/browserslist/electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="], "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=="], @@ -7573,149 +8189,39 @@ "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/electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="], "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=="], "svgo/css-select/domutils": ["domutils@2.8.0", "", { "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", "domhandler": "^4.2.0" } }, "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A=="], - "tailwindcss/postcss-load-config/lilconfig": ["lilconfig@3.0.0", "", {}, "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g=="], + "tailwindcss/postcss/nanoid": ["nanoid@3.3.8", "", { "bin": "bin/nanoid.cjs" }, "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w=="], - "terser-webpack-plugin/jest-worker/supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="], + "tailwindcss/postcss-load-config/lilconfig": ["lilconfig@3.0.0", "", {}, "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g=="], "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=="], - - "webpack/eslint-scope/estraverse": ["estraverse@4.3.0", "", {}, "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="], - - "webpack/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], - "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/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/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/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/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/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/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/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/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=="], + "winston-daily-rotate-file/winston-transport/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], "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 +8229,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 +8251,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 +8269,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 +8309,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,14 +8327,36 @@ "@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=="], + "@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@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/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@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/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@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/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@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/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@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/client-s3/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal/@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=="], + + "@aws-sdk/client-s3/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal/@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=="], + "@aws-sdk/client-sso-oidc/@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-sso-oidc/@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=="], @@ -7873,92 +8417,220 @@ "@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/middleware-flexible-checksums/@aws-sdk/core/@smithy/core/@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=="], - "@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/middleware-flexible-checksums/@aws-sdk/core/@smithy/smithy-client/@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=="], - "@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/middleware-flexible-checksums/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-s+eenEPW6RgliDk2IhjD2hWOxIx1NKrOHxEwNUaUXxYBxIyCcDfNULZ2Mu15E3kwcJWBedTET/kEASPV1A1Akg=="], - "@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/middleware-flexible-checksums/@smithy/util-stream/@smithy/fetch-http-handler/@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=="], - "@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/middleware-flexible-checksums/@smithy/util-stream/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-Hj4WoYWMJnSpM6/kchsm4bUNTL9XiSyhvoMb2KIq4VJzyDt7JpGHUZHkVNPZVC7YE1tf8tPeVauxpFBKGW4/KQ=="], - "@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/middleware-flexible-checksums/@smithy/util-stream/@smithy/node-http-handler/@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=="], - "@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/middleware-sdk-s3/@smithy/smithy-client/@smithy/middleware-endpoint/@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=="], - "@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/middleware-sdk-s3/@smithy/smithy-client/@smithy/middleware-endpoint/@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=="], - "@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/middleware-sdk-s3/@smithy/smithy-client/@smithy/middleware-endpoint/@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=="], - "@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/middleware-sdk-s3/@smithy/util-stream/@smithy/fetch-http-handler/@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=="], - "@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/middleware-sdk-s3/@smithy/util-stream/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-Hj4WoYWMJnSpM6/kchsm4bUNTL9XiSyhvoMb2KIq4VJzyDt7JpGHUZHkVNPZVC7YE1tf8tPeVauxpFBKGW4/KQ=="], - "@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/middleware-sdk-s3/@smithy/util-stream/@smithy/node-http-handler/@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=="], - "@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/@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-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/@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-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/@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-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/@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/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/@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/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/@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/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/@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/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/@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/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/@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/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/@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/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/@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/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/@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/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/@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/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/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/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/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/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/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/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=="], + "@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/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=="], + "@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/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=="], + "@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/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=="], + "@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/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=="], + "@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/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=="], + "@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/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=="], + "@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/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=="], + "@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/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/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/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/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=="], + + "@babel/core/@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], + + "@babel/helper-create-class-features-plugin/@babel/traverse/@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=="], + + "@babel/helper-member-expression-to-functions/@babel/traverse/@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=="], + + "@babel/helper-module-imports/@babel/traverse/@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=="], + + "@babel/helper-remap-async-to-generator/@babel/traverse/@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=="], + + "@babel/helper-replace-supers/@babel/traverse/@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=="], + + "@babel/helper-skip-transparent-expression-wrappers/@babel/traverse/@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=="], + + "@babel/helper-wrap-function/@babel/traverse/@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=="], + + "@babel/plugin-bugfix-firefox-class-in-computed-class-key/@babel/traverse/@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=="], + + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/@babel/traverse/@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=="], + + "@babel/plugin-transform-async-generator-functions/@babel/traverse/@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=="], + + "@babel/plugin-transform-classes/@babel/traverse/@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=="], + + "@babel/plugin-transform-destructuring/@babel/traverse/@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=="], + + "@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=="], + + "@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=="], + + "@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=="], + + "@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=="], + + "@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=="], + + "@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=="], + + "@babel/plugin-transform-function-name/@babel/traverse/@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=="], + + "@babel/plugin-transform-modules-amd/@babel/helper-module-transforms/@babel/traverse/@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=="], + + "@babel/plugin-transform-modules-amd/@babel/helper-module-transforms/@babel/traverse/@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/plugin-transform-modules-amd/@babel/helper-module-transforms/@babel/traverse/@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-transform-modules-amd/@babel/helper-module-transforms/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "@babel/plugin-transform-modules-amd/@babel/helper-module-transforms/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@babel/plugin-transform-modules-amd/@babel/helper-module-transforms/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + + "@babel/plugin-transform-modules-commonjs/@babel/helper-module-transforms/@babel/traverse/@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=="], + + "@babel/plugin-transform-modules-commonjs/@babel/helper-module-transforms/@babel/traverse/@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/plugin-transform-modules-commonjs/@babel/helper-module-transforms/@babel/traverse/@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-transform-modules-commonjs/@babel/helper-module-transforms/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "@babel/plugin-transform-modules-commonjs/@babel/helper-module-transforms/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@babel/plugin-transform-modules-commonjs/@babel/helper-module-transforms/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + + "@babel/plugin-transform-modules-systemjs/@babel/traverse/@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=="], + + "@babel/plugin-transform-modules-umd/@babel/helper-module-transforms/@babel/traverse/@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=="], + + "@babel/plugin-transform-modules-umd/@babel/helper-module-transforms/@babel/traverse/@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/plugin-transform-modules-umd/@babel/helper-module-transforms/@babel/traverse/@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-transform-modules-umd/@babel/helper-module-transforms/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "@babel/plugin-transform-modules-umd/@babel/helper-module-transforms/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + + "@babel/plugin-transform-modules-umd/@babel/helper-module-transforms/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + + "@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=="], + + "@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-object-rest-spread/@babel/traverse/@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=="], + + "@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=="], + + "@grpc/proto-loader/protobufjs/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + "@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 +8639,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 +8649,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 +8661,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 +8695,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 +8707,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 +8737,67 @@ "@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/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/eventstream-handler-node/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/token-providers/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/token-providers/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-browser/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@smithy/fetch-http-handler/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@smithy/middleware-endpoint/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0" } }, "sha512-HkMFJZJUhzU3HvND1+Yw/kYWXp4RPDLBWLcK1n+Vqw8xn4y2YiBhdww8IxhkQjP/QlZun5bwm3vcHc8AqIU3zw=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@smithy/node-config-provider/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-nE3IRNjDltvGcoThD2abTozI1dkSy8aX+a2N1Rs55en5UsdyyIXgGEmevUL3okZFoJC77JgRGe99xYohhsjivQ=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@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=="], - "@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/@aws-sdk/client-bedrock-runtime/@smithy/util-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0" } }, "sha512-HkMFJZJUhzU3HvND1+Yw/kYWXp4RPDLBWLcK1n+Vqw8xn4y2YiBhdww8IxhkQjP/QlZun5bwm3vcHc8AqIU3zw=="], "@librechat/frontend/@react-spring/web/@react-spring/shared/@react-spring/rafz": ["@react-spring/rafz@9.7.5", "", {}, "sha512-5ZenDQMC48wjUzPAm1EtwQ5Ot3bLIAwwqP2w2owG5KoNdNHpEJV263nGhCeKKmuA3vG2zLLOdu3or6kuDjA6Aw=="], @@ -8177,46 +8805,32 @@ "@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/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], + "@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/exporter-trace-otlp-http/@opentelemetry/otlp-transformer/protobufjs/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], + + "@opentelemetry/otlp-transformer/protobufjs/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + "@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=="], + "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 +8839,12 @@ "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-message-util/@jest/types/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], + + "expect/jest-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/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + "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,87 +8853,29 @@ "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=="], + + "istanbul-lib-instrument/@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=="], "jest-changed-files/execa/onetime/mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="], + "jest-config/@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=="], + "jest-config/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], "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=="], + "jwks-rsa/@types/express/@types/express-serve-static-core/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="], "mongodb-connection-string-url/whatwg-url/tr46/punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], @@ -8331,70 +8893,40 @@ "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/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/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/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/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/@rollup/plugin-replace/@rollup/pluginutils/@types/estree": ["@types/estree@0.0.39", "", {}, "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw=="], "workbox-build/@rollup/plugin-replace/@rollup/pluginutils/estree-walker": ["estree-walker@1.0.1", "", {}, "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg=="], "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 +8941,102 @@ "@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/middleware-flexible-checksums/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@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=="], - "@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/middleware-flexible-checksums/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@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=="], - "@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/middleware-flexible-checksums/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@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=="], - "@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/middleware-sdk-s3/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-nE3IRNjDltvGcoThD2abTozI1dkSy8aX+a2N1Rs55en5UsdyyIXgGEmevUL3okZFoJC77JgRGe99xYohhsjivQ=="], - "@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/@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/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/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/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/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/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/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/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/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-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/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-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-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-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/@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-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/@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-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/@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-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/@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-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/@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/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/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/@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/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/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/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/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/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/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="], + "@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/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/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/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/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/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/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/@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/@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/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/@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/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/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/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=="], + "@babel/plugin-transform-modules-amd/@babel/helper-module-transforms/@babel/traverse/@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=="], - "@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-modules-commonjs/@babel/helper-module-transforms/@babel/traverse/@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=="], + + "@babel/plugin-transform-modules-umd/@babel/helper-module-transforms/@babel/traverse/@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=="], + + "@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/electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="], "@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 +9049,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 +9067,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 +9093,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 +9103,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 +9155,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 +9173,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 +9185,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 +9237,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 +9255,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 +9267,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 +9287,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 +9339,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 +9357,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,413 +9367,85 @@ "@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/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@aws-sdk/util-format-url/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal/@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=="], - "@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/backend/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal/@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=="], "@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=="], + "@node-saml/passport-saml/@types/express/@types/express-serve-static-core/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], - "@librechat/frontend/jest-environment-jsdom/jsdom/cssstyle/cssom": ["cssom@0.3.8", "", {}, "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg=="], - - "@librechat/frontend/jest-environment-jsdom/jsdom/http-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], - - "@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=="], + "@opentelemetry/exporter-trace-otlp-http/@opentelemetry/otlp-transformer/protobufjs/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], "expect/jest-message-util/@jest/types/@jest/schemas/@sinclair/typebox": ["@sinclair/typebox@0.27.8", "", {}, "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="], + "expect/jest-message-util/@jest/types/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + + "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=="], + "jwks-rsa/@types/express/@types/express-serve-static-core/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], "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/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/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/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/source-map/whatwg-url/tr46/punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], "@aws-sdk/client-bedrock-agent-runtime/@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/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/middleware-flexible-checksums/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-nE3IRNjDltvGcoThD2abTozI1dkSy8aX+a2N1Rs55en5UsdyyIXgGEmevUL3okZFoJC77JgRGe99xYohhsjivQ=="], - "@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/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/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/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-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/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/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-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/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-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/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/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/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/abort-controller": ["@smithy/abort-controller@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g=="], - "@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/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/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-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/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 +9453,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 +9471,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 +9523,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 +9547,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 +9571,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 +9601,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 +9625,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 +9689,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 +9707,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 +9743,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 +9769,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 +9791,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 +9803,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 +9821,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 +9839,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 +9881,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 +9923,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 +9935,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 +9959,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 +9977,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 +10091,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 +10129,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 44acf8ea26..4d9087bff7 100644 --- a/client/jest.config.cjs +++ b/client/jest.config.cjs @@ -1,4 +1,4 @@ -/** v0.8.3-rc2 */ +/** v0.8.4 */ module.exports = { roots: ['/src'], testEnvironment: 'jsdom', diff --git a/client/package.json b/client/package.json index 0f7ffed04c..85d5a176f4 100644 --- a/client/package.json +++ b/client/package.json @@ -1,6 +1,6 @@ { "name": "@librechat/frontend", - "version": "v0.8.3-rc2", + "version": "v0.8.4", "description": "", "type": "module", "scripts": { @@ -32,12 +32,13 @@ "@ariakit/react": "^0.4.15", "@ariakit/react-core": "^0.4.17", "@codesandbox/sandpack-react": "^2.19.10", - "@dicebear/collection": "^9.2.2", - "@dicebear/core": "^9.2.2", + "@dicebear/collection": "^9.4.1", + "@dicebear/core": "^9.4.1", "@headlessui/react": "^2.1.2", "@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,9 +94,8 @@ "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-resizable-panels": "^4.7.4", "react-router-dom": "^6.30.3", "react-speech-recognition": "^3.10.0", "react-textarea-autosize": "^8.4.0", @@ -148,6 +148,7 @@ "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": "^11.2.0", "tailwindcss": "^3.4.1", diff --git a/client/src/Providers/ActivePanelContext.tsx b/client/src/Providers/ActivePanelContext.tsx index 4a8d6ccfc4..46b2a189b7 100644 --- a/client/src/Providers/ActivePanelContext.tsx +++ b/client/src/Providers/ActivePanelContext.tsx @@ -1,31 +1,31 @@ -import { createContext, useContext, useState, ReactNode } from 'react'; +import { createContext, useCallback, useContext, useMemo, useState, ReactNode } from 'react'; + +const STORAGE_KEY = 'side:active-panel'; +const DEFAULT_PANEL = 'conversations'; + +function getInitialActivePanel(): string { + const saved = localStorage.getItem(STORAGE_KEY); + return saved ? saved : DEFAULT_PANEL; +} interface ActivePanelContextType { - active: string | undefined; + active: string; setActive: (id: string) => void; } const ActivePanelContext = createContext(undefined); -export function ActivePanelProvider({ - children, - defaultActive, -}: { - children: ReactNode; - defaultActive?: string; -}) { - const [active, _setActive] = useState(defaultActive); +export function ActivePanelProvider({ children }: { children: ReactNode }) { + const [active, _setActive] = useState(getInitialActivePanel); - const setActive = (id: string) => { - localStorage.setItem('side:active-panel', id); + const setActive = useCallback((id: string) => { + localStorage.setItem(STORAGE_KEY, id); _setActive(id); - }; + }, []); - return ( - - {children} - - ); + const value = useMemo(() => ({ active, setActive }), [active, setActive]); + + return {children}; } export function useActivePanel() { @@ -35,3 +35,11 @@ export function useActivePanel() { } return context; } + +/** Returns `active` when it matches a known link, otherwise the first link's id. */ +export function resolveActivePanel(active: string, links: { id: string }[]): string { + if (links.length > 0 && links.some((l) => l.id === active)) { + return active; + } + return links[0]?.id ?? active; +} diff --git a/client/src/Providers/ChatContext.tsx b/client/src/Providers/ChatContext.tsx index 3d3acbcc42..8af75f90c0 100644 --- a/client/src/Providers/ChatContext.tsx +++ b/client/src/Providers/ChatContext.tsx @@ -2,5 +2,11 @@ import { createContext, useContext } from 'react'; import useChatHelpers from '~/hooks/Chat/useChatHelpers'; type TChatContext = ReturnType; -export const ChatContext = createContext({} as TChatContext); -export const useChatContext = () => useContext(ChatContext); +export const ChatContext = createContext(null); +export const useChatContext = () => { + const ctx = useContext(ChatContext); + if (!ctx) { + throw new Error('useChatContext must be used within a ChatContext.Provider'); + } + return ctx; +}; 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/PromptGroupsContext.tsx b/client/src/Providers/PromptGroupsContext.tsx index 7c9dbe8258..3df373b165 100644 --- a/client/src/Providers/PromptGroupsContext.tsx +++ b/client/src/Providers/PromptGroupsContext.tsx @@ -2,9 +2,9 @@ import React, { createContext, useContext, ReactNode, useMemo } from 'react'; import { PermissionTypes, Permissions } from 'librechat-data-provider'; import type { TPromptGroup } from 'librechat-data-provider'; import type { PromptOption } from '~/common'; -import CategoryIcon from '~/components/Prompts/Groups/CategoryIcon'; import { usePromptGroupsNav, useHasAccess } from '~/hooks'; import { useGetAllPromptGroups } from '~/data-provider'; +import { CategoryIcon } from '~/components/Prompts'; import { mapPromptGroups } from '~/utils'; type AllPromptGroupsData = diff --git a/client/src/Providers/SidePanelContext.tsx b/client/src/Providers/SidePanelContext.tsx deleted file mode 100644 index 3ce7834ccc..0000000000 --- a/client/src/Providers/SidePanelContext.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import React, { createContext, useContext, useMemo } from 'react'; -import type { EModelEndpoint } from 'librechat-data-provider'; -import { useChatContext } from './ChatContext'; - -interface SidePanelContextValue { - endpoint?: EModelEndpoint | null; -} - -const SidePanelContext = createContext(undefined); - -export function SidePanelProvider({ children }: { children: React.ReactNode }) { - const { conversation } = useChatContext(); - - /** Context value only created when endpoint changes */ - const contextValue = useMemo( - () => ({ - endpoint: conversation?.endpoint, - }), - [conversation?.endpoint], - ); - - return {children}; -} - -export function useSidePanelContext() { - const context = useContext(SidePanelContext); - if (!context) { - throw new Error('useSidePanelContext must be used within SidePanelProvider'); - } - return context; -} diff --git a/client/src/Providers/__tests__/ActivePanelContext.spec.tsx b/client/src/Providers/__tests__/ActivePanelContext.spec.tsx new file mode 100644 index 0000000000..0f2f89e8f7 --- /dev/null +++ b/client/src/Providers/__tests__/ActivePanelContext.spec.tsx @@ -0,0 +1,84 @@ +import React from 'react'; +import { render, fireEvent, screen } from '@testing-library/react'; +import '@testing-library/jest-dom/extend-expect'; +import { + ActivePanelProvider, + resolveActivePanel, + useActivePanel, +} from '~/Providers/ActivePanelContext'; + +const STORAGE_KEY = 'side:active-panel'; + +function TestConsumer() { + const { active, setActive } = useActivePanel(); + return ( +
+ {active} +
+ ); +} + +describe('ActivePanelContext', () => { + beforeEach(() => { + localStorage.clear(); + }); + + it('defaults to conversations when no localStorage value exists', () => { + render( + + + , + ); + expect(screen.getByTestId('active')).toHaveTextContent('conversations'); + }); + + it('reads initial value from localStorage', () => { + localStorage.setItem(STORAGE_KEY, 'memories'); + render( + + + , + ); + expect(screen.getByTestId('active')).toHaveTextContent('memories'); + }); + + it('setActive updates state and writes to localStorage', () => { + render( + + + , + ); + fireEvent.click(screen.getByTestId('switch-btn')); + expect(screen.getByTestId('active')).toHaveTextContent('bookmarks'); + expect(localStorage.getItem(STORAGE_KEY)).toBe('bookmarks'); + }); + + it('throws when useActivePanel is called outside provider', () => { + const spy = jest.spyOn(console, 'error').mockImplementation(() => {}); + expect(() => render()).toThrow( + 'useActivePanel must be used within an ActivePanelProvider', + ); + spy.mockRestore(); + }); +}); + +describe('resolveActivePanel', () => { + const links = [{ id: 'conversations' }, { id: 'prompts' }, { id: 'files' }]; + + it('returns active when it matches a link', () => { + expect(resolveActivePanel('prompts', links)).toBe('prompts'); + }); + + it('falls back to first link when active does not match', () => { + expect(resolveActivePanel('hide-panel', links)).toBe('conversations'); + }); + + it('returns active unchanged when links is empty', () => { + expect(resolveActivePanel('agents', [])).toBe('agents'); + }); + + it('falls back to the only link when active is stale', () => { + expect(resolveActivePanel('agents', [{ id: 'conversations' }])).toBe('conversations'); + }); +}); diff --git a/client/src/Providers/__tests__/ChatContext.spec.tsx b/client/src/Providers/__tests__/ChatContext.spec.tsx new file mode 100644 index 0000000000..0ed00bf580 --- /dev/null +++ b/client/src/Providers/__tests__/ChatContext.spec.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import '@testing-library/jest-dom/extend-expect'; +import { ChatContext, useChatContext } from '~/Providers/ChatContext'; + +function TestConsumer() { + const ctx = useChatContext(); + return {ctx.index}; +} + +describe('ChatContext', () => { + it('throws when useChatContext is called outside a provider', () => { + const spy = jest.spyOn(console, 'error').mockImplementation(() => {}); + expect(() => render()).toThrow( + 'useChatContext must be used within a ChatContext.Provider', + ); + spy.mockRestore(); + }); + + it('provides context value when wrapped in provider', () => { + const mockHelpers = { index: 0 } as ReturnType< + typeof import('~/hooks/Chat/useChatHelpers').default + >; + render( + + + , + ); + expect(screen.getByTestId('index')).toHaveTextContent('0'); + }); +}); 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/Providers/index.ts b/client/src/Providers/index.ts index 43a16fa976..3ae90e189c 100644 --- a/client/src/Providers/index.ts +++ b/client/src/Providers/index.ts @@ -22,7 +22,6 @@ export * from './ToolCallsMapContext'; export * from './SetConvoContext'; export * from './SearchContext'; export * from './BadgeRowContext'; -export * from './SidePanelContext'; export * from './DragDropContext'; export * from './ArtifactsContext'; export * from './PromptGroupsContext'; diff --git a/client/src/a11y/LiveAnnouncer.tsx b/client/src/a11y/LiveAnnouncer.tsx index 0eac8089bc..ac83ff2962 100644 --- a/client/src/a11y/LiveAnnouncer.tsx +++ b/client/src/a11y/LiveAnnouncer.tsx @@ -21,6 +21,9 @@ const LiveAnnouncer: React.FC = ({ children }) => { start: localize('com_a11y_start'), end: localize('com_a11y_end'), composing: localize('com_a11y_ai_composing'), + summarize_started: localize('com_a11y_summarize_started'), + summarize_completed: localize('com_a11y_summarize_completed'), + summarize_failed: localize('com_a11y_summarize_failed'), }), [localize], ); diff --git a/client/src/common/types.ts b/client/src/common/types.ts index d47ff02bd8..85044bb2bc 100644 --- a/client/src/common/types.ts +++ b/client/src/common/types.ts @@ -132,13 +132,6 @@ export type NavLink = { id: string; }; -export interface NavProps { - isCollapsed: boolean; - links: NavLink[]; - resize?: (size: number) => void; - defaultActive?: string; -} - export interface DataColumnMeta { meta: | { @@ -561,11 +554,6 @@ export interface ModelItemProps { className?: string; } -export type ContextType = { - navVisible: boolean; - setNavVisible: React.Dispatch>; -}; - export interface SwitcherProps { endpoint?: t.EModelEndpoint | null; endpointKeyProvided: boolean; diff --git a/client/src/components/Agents/Marketplace.tsx b/client/src/components/Agents/Marketplace.tsx index 69db9fc630..816705a0db 100644 --- a/client/src/components/Agents/Marketplace.tsx +++ b/client/src/components/Agents/Marketplace.tsx @@ -1,23 +1,16 @@ import React, { useState, useEffect, useMemo, useRef, useCallback } from 'react'; -import { useRecoilState } from 'recoil'; -import { useOutletContext } from 'react-router-dom'; -import { useQueryClient } from '@tanstack/react-query'; import { useSearchParams, useParams, useNavigate } from 'react-router-dom'; -import { TooltipAnchor, Button, NewChatIcon, useMediaQuery } from '@librechat/client'; -import { PermissionTypes, Permissions, QueryKeys } from 'librechat-data-provider'; +import { useMediaQuery } from '@librechat/client'; +import { PermissionTypes, Permissions } from 'librechat-data-provider'; import type t from 'librechat-data-provider'; -import type { ContextType } from '~/common'; import { useDocumentTitle, useHasAccess, useLocalize, TranslationKeys } from '~/hooks'; import { useGetEndpointsQuery, useGetAgentCategoriesQuery } from '~/data-provider'; import MarketplaceAdminSettings from './MarketplaceAdminSettings'; -import { SidePanelProvider, useChatContext } from '~/Providers'; import { SidePanelGroup } from '~/components/SidePanel'; -import { OpenSidebar } from '~/components/Chat/Menus'; -import { cn, clearMessagesCache } from '~/utils'; import CategoryTabs from './CategoryTabs'; import SearchBar from './SearchBar'; import AgentGrid from './AgentGrid'; -import store from '~/store'; +import { cn } from '~/utils'; interface AgentMarketplaceProps { className?: string; @@ -34,13 +27,9 @@ const AgentMarketplace: React.FC = ({ className = '' }) = const localize = useLocalize(); const navigate = useNavigate(); const { category } = useParams(); - const queryClient = useQueryClient(); const [searchParams, setSearchParams] = useSearchParams(); - const { conversation, newConversation } = useChatContext(); const isSmallScreen = useMediaQuery('(max-width: 768px)'); - const { navVisible, setNavVisible } = useOutletContext(); - const [hideSidePanel, setHideSidePanel] = useRecoilState(store.hideSidePanel); // Get URL parameters const searchQuery = searchParams.get('q') || ''; @@ -59,15 +48,6 @@ const AgentMarketplace: React.FC = ({ className = '' }) = // Set page title useDocumentTitle(`${localize('com_agents_marketplace')} | LibreChat`); - // Ensure right sidebar is always visible in marketplace - useEffect(() => { - setHideSidePanel(false); - - // Also try to force expand via localStorage - localStorage.setItem('hideSidePanel', 'false'); - localStorage.setItem('fullPanelCollapse', 'false'); - }, [setHideSidePanel, hideSidePanel]); - // Ensure endpoints config is loaded first (required for agent queries) useGetEndpointsQuery(); @@ -193,33 +173,6 @@ const AgentMarketplace: React.FC = ({ className = '' }) = } }; - /** - * Handle new chat button click - */ - - const handleNewChat = (e: React.MouseEvent) => { - if (e.button === 0 && (e.ctrlKey || e.metaKey)) { - window.open('/c/new', '_blank'); - return; - } - clearMessagesCache(queryClient, conversation?.conversationId); - queryClient.invalidateQueries([QueryKeys.messages]); - newConversation(); - }; - - // Layout configuration for SidePanelGroup - const defaultLayout = useMemo(() => { - const resizableLayout = localStorage.getItem('react-resizable-panels:layout'); - return typeof resizableLayout === 'string' ? JSON.parse(resizableLayout) : undefined; - }, []); - - const defaultCollapsed = useMemo(() => { - const collapsedPanels = localStorage.getItem('react-resizable-panels:collapsed'); - return typeof collapsedPanels === 'string' ? JSON.parse(collapsedPanels) : true; - }, []); - - const fullCollapse = useMemo(() => localStorage.getItem('fullPanelCollapse') === 'true', []); - const hasAccessToMarketplace = useHasAccess({ permissionType: PermissionTypes.MARKETPLACE, permission: Permissions.USE, @@ -241,99 +194,136 @@ const AgentMarketplace: React.FC = ({ className = '' }) = } return (
- - -
- {/* Scrollable container */} -
- {/* Simplified header for agents marketplace - only show nav controls when needed */} - {!isSmallScreen && ( -
-
- {!navVisible ? ( - <> - - - - - } - /> - - ) : ( - // Invisible placeholder to maintain height -
- )} -
-
- )} - {/* Hero Section - scrolls away */} - {!isSmallScreen && ( -
-
-

- {localize('com_agents_marketplace')} -

-

- {localize('com_agents_marketplace_subtitle')} -

-
-
- )} - {/* Sticky wrapper for search bar and categories */} -
-
- {/* Search bar */} -
- - {/* TODO: Remove this once we have a better way to handle admin settings */} - {/* Admin Settings */} - -
- - {/* Category tabs */} - + +
+ {/* Scrollable container */} +
+ {/* Hero Section - scrolls away */} + {!isSmallScreen && ( +
+
+

+ {localize('com_agents_marketplace')} +

+

+ {localize('com_agents_marketplace_subtitle')} +

- {/* Scrollable content area */} -
- {/* Two-pane animated container wrapping category header + grid */} -
- {/* Current content pane */} + )} + {/* Sticky wrapper for search bar and categories */} +
+
+ {/* Search bar */} +
+ + {/* TODO: Remove this once we have a better way to handle admin settings */} + {/* Admin Settings */} + +
+ + {/* Category tabs */} + +
+
+ {/* Scrollable content area */} +
+ {/* Two-pane animated container wrapping category header + grid */} +
+ {/* Current content pane */} +
+ {/* Category header - only show when not searching */} + {!searchQuery && ( +
+ {(() => { + // Get category data for display + const getCategoryData = () => { + if (displayCategory === 'promoted') { + return { + name: localize('com_agents_top_picks'), + description: localize('com_agents_recommended'), + }; + } + if (displayCategory === 'all') { + return { + name: localize('com_agents_all'), + description: localize('com_agents_all_description'), + }; + } + + // Find the category in the API data + const categoryData = categoriesQuery.data?.find( + (cat) => cat.value === displayCategory, + ); + if (categoryData) { + return { + name: categoryData.label?.startsWith('com_') + ? localize(categoryData.label as TranslationKeys) + : categoryData.label, + description: categoryData.description?.startsWith('com_') + ? localize(categoryData.description as TranslationKeys) + : categoryData.description || '', + }; + } + + // Fallback for unknown categories + return { + name: + displayCategory.charAt(0).toUpperCase() + displayCategory.slice(1), + description: '', + }; + }; + + const { name, description } = getCategoryData(); + + return ( +
+

{name}

+ {description && ( +

{description}

+ )} +
+ ); + })()} +
+ )} + + {/* Agent grid */} + +
+ + {/* Next content pane, only during transition */} + {isTransitioning && nextCategory && (
{/* Category header - only show when not searching */} {!searchQuery && ( @@ -341,13 +331,13 @@ const AgentMarketplace: React.FC = ({ className = '' }) = {(() => { // Get category data for display const getCategoryData = () => { - if (displayCategory === 'promoted') { + if (nextCategory === 'promoted') { return { name: localize('com_agents_top_picks'), description: localize('com_agents_recommended'), }; } - if (displayCategory === 'all') { + if (nextCategory === 'all') { return { name: localize('com_agents_all'), description: localize('com_agents_all_description'), @@ -356,7 +346,7 @@ const AgentMarketplace: React.FC = ({ className = '' }) = // Find the category in the API data const categoryData = categoriesQuery.data?.find( - (cat) => cat.value === displayCategory, + (cat) => cat.value === nextCategory, ); if (categoryData) { return { @@ -364,7 +354,9 @@ const AgentMarketplace: React.FC = ({ className = '' }) = ? localize(categoryData.label as TranslationKeys) : categoryData.label, description: categoryData.description?.startsWith('com_') - ? localize(categoryData.description as TranslationKeys) + ? localize( + categoryData.description as Parameters[0], + ) : categoryData.description || '', }; } @@ -372,7 +364,8 @@ const AgentMarketplace: React.FC = ({ className = '' }) = // Fallback for unknown categories return { name: - displayCategory.charAt(0).toUpperCase() + displayCategory.slice(1), + (nextCategory || '').charAt(0).toUpperCase() + + (nextCategory || '').slice(1), description: '', }; }; @@ -393,102 +386,21 @@ const AgentMarketplace: React.FC = ({ className = '' }) = {/* Agent grid */}
+ )} - {/* Next content pane, only during transition */} - {isTransitioning && nextCategory && ( -
- {/* Category header - only show when not searching */} - {!searchQuery && ( -
- {(() => { - // Get category data for display - const getCategoryData = () => { - if (nextCategory === 'promoted') { - return { - name: localize('com_agents_top_picks'), - description: localize('com_agents_recommended'), - }; - } - if (nextCategory === 'all') { - return { - name: localize('com_agents_all'), - description: localize('com_agents_all_description'), - }; - } - - // Find the category in the API data - const categoryData = categoriesQuery.data?.find( - (cat) => cat.value === nextCategory, - ); - if (categoryData) { - return { - name: categoryData.label?.startsWith('com_') - ? localize(categoryData.label as TranslationKeys) - : categoryData.label, - description: categoryData.description?.startsWith('com_') - ? localize( - categoryData.description as Parameters[0], - ) - : categoryData.description || '', - }; - } - - // Fallback for unknown categories - return { - name: - (nextCategory || '').charAt(0).toUpperCase() + - (nextCategory || '').slice(1), - description: '', - }; - }; - - const { name, description } = getCategoryData(); - - return ( -
-

{name}

- {description && ( -

{description}

- )} -
- ); - })()} -
- )} - - {/* Agent grid */} - -
- )} - - {/* Note: Using Tailwind keyframes for slide in/out animations */} -
+ {/* Note: Using Tailwind keyframes for slide in/out animations */}
-
-
- +
+
+
); }; diff --git a/client/src/components/Agents/MarketplaceContext.tsx b/client/src/components/Agents/MarketplaceContext.tsx index 09c88e3291..9193cbb82b 100644 --- a/client/src/components/Agents/MarketplaceContext.tsx +++ b/client/src/components/Agents/MarketplaceContext.tsx @@ -13,5 +13,5 @@ interface MarketplaceProviderProps { export const MarketplaceProvider: React.FC = ({ children }) => { const chatHelpers = useChatHelpers(0, 'new'); - return {children}; + return {children}; }; 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); @@ -217,7 +216,7 @@ export default function Artifacts() { {/* Header */}
@@ -235,6 +234,7 @@ export default function Artifacts() { value={activeTab} onChange={setActiveTab} disabled={isMutating && activeTab !== 'code'} + buttonClassName="h-9 px-3 gap-1.5" />
)} @@ -250,6 +250,7 @@ export default function Artifacts() { - ))} -
- )} - - ); - }, - 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) => ( - - ), -})); +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/MCPSelect.tsx b/client/src/components/Chat/Input/MCPSelect.tsx index a5356f5094..13a86c856a 100644 --- a/client/src/components/Chat/Input/MCPSelect.tsx +++ b/client/src/components/Chat/Input/MCPSelect.tsx @@ -1,4 +1,4 @@ -import React, { memo, useMemo, useCallback, useRef } from 'react'; +import React, { memo, useMemo } from 'react'; import * as Ariakit from '@ariakit/react'; import { ChevronDown } from 'lucide-react'; import { PermissionTypes, Permissions } from 'librechat-data-provider'; @@ -27,24 +27,9 @@ function MCPSelectContent() { const menuStore = Ariakit.useMenuStore({ focusLoop: true }); const isOpen = menuStore.useState('open'); - const focusedElementRef = useRef(null); const selectedCount = mcpValues?.length ?? 0; - // Wrap toggleServerSelection to preserve focus after state update - const handleToggle = useCallback( - (serverName: string) => { - // Save currently focused element - focusedElementRef.current = document.activeElement as HTMLElement; - toggleServerSelection(serverName); - // Restore focus after React re-renders - requestAnimationFrame(() => { - focusedElementRef.current?.focus(); - }); - }, - [toggleServerSelection], - ); - const selectedServers = useMemo(() => { if (!mcpValues || mcpValues.length === 0) { return []; @@ -103,6 +88,8 @@ function MCPSelectContent() { ))} diff --git a/client/src/components/Chat/Input/MCPSubMenu.tsx b/client/src/components/Chat/Input/MCPSubMenu.tsx index b0b8fad1bb..f8e617cba3 100644 --- a/client/src/components/Chat/Input/MCPSubMenu.tsx +++ b/client/src/components/Chat/Input/MCPSubMenu.tsx @@ -35,7 +35,6 @@ const MCPSubMenu = React.forwardRef( placement: 'right', }); - // Don't render if no MCP servers are configured if (!selectableServers || selectableServers.length === 0) { return null; } diff --git a/client/src/components/Chat/Input/PromptsCommand.tsx b/client/src/components/Chat/Input/PromptsCommand.tsx index 1740ed43a2..f05a46f6ac 100644 --- a/client/src/components/Chat/Input/PromptsCommand.tsx +++ b/client/src/components/Chat/Input/PromptsCommand.tsx @@ -4,8 +4,9 @@ import { Spinner, useCombobox } from '@librechat/client'; import { useSetRecoilState, useRecoilValue } from 'recoil'; import type { TPromptGroup } from 'librechat-data-provider'; import type { PromptOption } from '~/common'; -import VariableDialog from '~/components/Prompts/Groups/VariableDialog'; import { removeCharIfLast, detectVariables } from '~/utils'; +import { useRecordPromptUsage } from '~/data-provider'; +import { VariableDialog } from '~/components/Prompts'; import { usePromptGroupsContext } from '~/Providers'; import MentionItem from './MentionItem'; import { useLocalize } from '~/hooks'; @@ -60,6 +61,7 @@ function PromptsCommand({ submitPrompt: (textPrompt: string) => void; }) { const localize = useLocalize(); + const { mutate: recordUsage } = useRecordPromptUsage(); const { allPromptGroups, hasAccess } = usePromptGroupsContext(); const { data, isLoading } = allPromptGroups; @@ -107,9 +109,20 @@ function PromptsCommand({ return; } else { submitPrompt(group.productionPrompt?.prompt ?? ''); + if (group._id) { + recordUsage(group._id); + } } }, - [setSearchValue, setOpen, setShowPromptsPopover, textAreaRef, promptsMap, submitPrompt], + [ + setSearchValue, + setOpen, + setShowPromptsPopover, + textAreaRef, + promptsMap, + submitPrompt, + recordUsage, + ], ); useEffect(() => { diff --git a/client/src/components/Chat/Input/__tests__/MCPSelect.spec.tsx b/client/src/components/Chat/Input/__tests__/MCPSelect.spec.tsx new file mode 100644 index 0000000000..7662ee5e6e --- /dev/null +++ b/client/src/components/Chat/Input/__tests__/MCPSelect.spec.tsx @@ -0,0 +1,142 @@ +import React from 'react'; +import userEvent from '@testing-library/user-event'; +import { render, screen, within } from '@testing-library/react'; +import MCPSelect from '../MCPSelect'; + +const mockToggleServerSelection = jest.fn(); + +const defaultMcpServerManager = { + localize: (key: string) => key, + isPinned: true, + mcpValues: [] as string[], + placeholderText: 'MCP Servers', + selectableServers: [ + { serverName: 'server-a', config: { title: 'Server A' } }, + { serverName: 'server-b', config: { title: 'Server B' } }, + ], + connectionStatus: {}, + isInitializing: () => false, + getConfigDialogProps: () => null, + toggleServerSelection: mockToggleServerSelection, + getServerStatusIconProps: () => null, +}; + +let mockCanUseMcp = true; +let mockMcpServerManager = { ...defaultMcpServerManager }; + +jest.mock('~/Providers', () => ({ + useBadgeRowContext: () => ({ + conversationId: 'test-conv', + storageContextKey: undefined, + mcpServerManager: mockMcpServerManager, + }), +})); + +jest.mock('~/hooks', () => ({ + useLocalize: () => (key: string) => key, + useHasAccess: () => mockCanUseMcp, +})); + +jest.mock('@librechat/client', () => { + // eslint-disable-next-line @typescript-eslint/no-require-imports + const R = require('react'); + return { + TooltipAnchor: ({ + children, + render, + }: { + children: React.ReactNode; + render: React.ReactElement; + }) => R.cloneElement(render, {}, ...(Array.isArray(children) ? children : [children])), + MCPIcon: ({ className }: { className?: string }) => R.createElement('span', { className }), + Spinner: ({ className }: { className?: string }) => R.createElement('span', { className }), + }; +}); + +jest.mock('~/components/MCP/MCPConfigDialog', () => ({ + __esModule: true, + default: () => null, +})); + +describe('MCPSelect', () => { + beforeEach(() => { + jest.clearAllMocks(); + mockCanUseMcp = true; + mockMcpServerManager = { ...defaultMcpServerManager }; + }); + + it('renders the menu button', () => { + render(); + expect(screen.getByRole('button', { name: /MCP Servers/i })).toBeInTheDocument(); + }); + + it('opens menu on button click and shows server items', async () => { + const user = userEvent.setup(); + render(); + + await user.click(screen.getByRole('button', { name: /MCP Servers/i })); + + const menu = screen.getByRole('menu', { name: /com_ui_mcp_servers/i }); + expect(menu).toBeVisible(); + expect(within(menu).getByRole('menuitemcheckbox', { name: /Server A/i })).toBeInTheDocument(); + expect(within(menu).getByRole('menuitemcheckbox', { name: /Server B/i })).toBeInTheDocument(); + }); + + it('closes menu on Escape', async () => { + const user = userEvent.setup(); + render(); + + await user.click(screen.getByRole('button', { name: /MCP Servers/i })); + expect(screen.getByRole('menu', { name: /com_ui_mcp_servers/i })).toBeVisible(); + + await user.keyboard('{Escape}'); + expect(screen.getByRole('button', { name: /MCP Servers/i })).toHaveAttribute( + 'aria-expanded', + 'false', + ); + }); + + it('keeps menu open after toggling a server item', async () => { + const user = userEvent.setup(); + render(); + + await user.click(screen.getByRole('button', { name: /MCP Servers/i })); + await user.click(screen.getByRole('menuitemcheckbox', { name: /Server A/i })); + + expect(mockToggleServerSelection).toHaveBeenCalledWith('server-a'); + expect(screen.getByRole('menu', { name: /com_ui_mcp_servers/i })).toBeVisible(); + }); + + it('arrow-key navigation wraps from last item to first', async () => { + const user = userEvent.setup(); + render(); + + await user.click(screen.getByRole('button', { name: /MCP Servers/i })); + const items = screen.getAllByRole('menuitemcheckbox'); + expect(items).toHaveLength(2); + + await user.keyboard('{ArrowDown}'); + await user.keyboard('{ArrowDown}'); + await user.keyboard('{ArrowDown}'); + expect(items[0]).toHaveFocus(); + }); + + it('renders nothing when user lacks MCP access', () => { + mockCanUseMcp = false; + const { container } = render(); + expect(container.firstChild).toBeNull(); + expect(screen.queryByRole('button')).not.toBeInTheDocument(); + }); + + it('renders nothing when selectableServers is empty', () => { + mockMcpServerManager = { ...defaultMcpServerManager, selectableServers: [] }; + const { container } = render(); + expect(container.firstChild).toBeNull(); + }); + + it('renders nothing when not pinned and no servers selected', () => { + mockMcpServerManager = { ...defaultMcpServerManager, isPinned: false, mcpValues: [] }; + const { container } = render(); + expect(container.firstChild).toBeNull(); + }); +}); diff --git a/client/src/components/Chat/Input/__tests__/MCPSubMenu.spec.tsx b/client/src/components/Chat/Input/__tests__/MCPSubMenu.spec.tsx new file mode 100644 index 0000000000..be8fb5d9c2 --- /dev/null +++ b/client/src/components/Chat/Input/__tests__/MCPSubMenu.spec.tsx @@ -0,0 +1,156 @@ +import React from 'react'; +import * as Ariakit from '@ariakit/react'; +import userEvent from '@testing-library/user-event'; +import { render, screen, within } from '@testing-library/react'; +import MCPSubMenu from '../MCPSubMenu'; + +const mockToggleServerSelection = jest.fn(); +const mockSetIsPinned = jest.fn(); + +const defaultMcpServerManager = { + isPinned: true, + mcpValues: [] as string[], + setIsPinned: mockSetIsPinned, + placeholderText: 'MCP Servers', + selectableServers: [ + { serverName: 'server-a', config: { title: 'Server A' } }, + { serverName: 'server-b', config: { title: 'Server B', description: 'Second server' } }, + ], + connectionStatus: {}, + isInitializing: () => false, + getConfigDialogProps: () => null, + toggleServerSelection: mockToggleServerSelection, + getServerStatusIconProps: () => null, +}; + +let mockMcpServerManager = { ...defaultMcpServerManager }; + +jest.mock('~/Providers', () => ({ + useBadgeRowContext: () => ({ + storageContextKey: undefined, + mcpServerManager: mockMcpServerManager, + }), +})); + +jest.mock('~/hooks', () => ({ + useLocalize: () => (key: string) => key, + useHasAccess: () => true, +})); + +jest.mock('@librechat/client', () => { + // eslint-disable-next-line @typescript-eslint/no-require-imports + const R = require('react'); + return { + MCPIcon: ({ className }: { className?: string }) => R.createElement('span', { className }), + PinIcon: ({ unpin }: { unpin?: boolean }) => + R.createElement('span', { 'data-testid': unpin ? 'unpin-icon' : 'pin-icon' }), + Spinner: ({ className }: { className?: string }) => R.createElement('span', { className }), + }; +}); + +jest.mock('~/components/MCP/MCPConfigDialog', () => ({ + __esModule: true, + default: () => null, +})); + +function ParentMenu({ children }: { children: React.ReactNode }) { + return ( + + {/* eslint-disable-next-line i18next/no-literal-string */} + Parent + {children} + + ); +} + +function renderSubMenu(props: React.ComponentProps = {}) { + return render( + + + , + ); +} + +describe('MCPSubMenu', () => { + beforeEach(() => { + jest.clearAllMocks(); + mockMcpServerManager = { ...defaultMcpServerManager }; + }); + + it('renders nothing when selectableServers is empty', () => { + mockMcpServerManager = { ...defaultMcpServerManager, selectableServers: [] }; + renderSubMenu(); + expect(screen.queryByText('MCP Servers')).not.toBeInTheDocument(); + }); + + it('renders the submenu trigger with default placeholder', () => { + renderSubMenu(); + expect(screen.getByText('MCP Servers')).toBeInTheDocument(); + }); + + it('renders custom placeholder when provided', () => { + renderSubMenu({ placeholder: 'Custom Label' }); + expect(screen.getByText('Custom Label')).toBeInTheDocument(); + expect(screen.queryByText('MCP Servers')).not.toBeInTheDocument(); + }); + + it('opens submenu and shows real server items', async () => { + const user = userEvent.setup(); + renderSubMenu(); + + await user.click(screen.getByText('MCP Servers')); + + const menu = screen.getByRole('menu', { name: /com_ui_mcp_servers/i }); + expect(menu).toBeVisible(); + expect(within(menu).getByRole('menuitemcheckbox', { name: /Server A/i })).toBeInTheDocument(); + expect(within(menu).getByRole('menuitemcheckbox', { name: /Server B/i })).toBeInTheDocument(); + }); + + it('keeps menu open after toggling a server item', async () => { + const user = userEvent.setup(); + renderSubMenu(); + + await user.click(screen.getByText('MCP Servers')); + await user.click(screen.getByRole('menuitemcheckbox', { name: /Server A/i })); + + expect(mockToggleServerSelection).toHaveBeenCalledWith('server-a'); + expect(screen.getByRole('menu', { name: /com_ui_mcp_servers/i })).toBeVisible(); + }); + + it('calls setIsPinned with toggled value when pin button is clicked', async () => { + const user = userEvent.setup(); + mockMcpServerManager = { ...defaultMcpServerManager, isPinned: false }; + renderSubMenu(); + + await user.click(screen.getByRole('button', { name: /com_ui_pin/i })); + + expect(mockSetIsPinned).toHaveBeenCalledWith(true); + }); + + it('arrow-key navigation wraps from last item to first', async () => { + const user = userEvent.setup(); + renderSubMenu(); + + await user.click(screen.getByText('MCP Servers')); + const items = screen.getAllByRole('menuitemcheckbox'); + expect(items).toHaveLength(2); + + await user.click(items[1]); + expect(items[1]).toHaveFocus(); + + await user.keyboard('{ArrowDown}'); + expect(items[0]).toHaveFocus(); + }); + + it('pin button shows unpin label when pinned', () => { + mockMcpServerManager = { ...defaultMcpServerManager, isPinned: true }; + renderSubMenu(); + expect(screen.getByRole('button', { name: /com_ui_unpin/i })).toBeInTheDocument(); + }); + + it('pin button shows pin label when not pinned', () => { + mockMcpServerManager = { ...defaultMcpServerManager, isPinned: false }; + renderSubMenu(); + expect(screen.getByRole('button', { name: /com_ui_pin/i })).toBeInTheDocument(); + }); +}); diff --git a/client/src/components/Chat/Menus/BookmarkMenu.tsx b/client/src/components/Chat/Menus/BookmarkMenu.tsx index ac7b17985e..d66fccd24b 100644 --- a/client/src/components/Chat/Menus/BookmarkMenu.tsx +++ b/client/src/components/Chat/Menus/BookmarkMenu.tsx @@ -157,9 +157,9 @@ const BookmarkMenu: FC = () => { return ; } if (hasBookmarks) { - return