diff --git a/README-en.md b/README-en.md new file mode 100644 index 0000000..7315ee3 --- /dev/null +++ b/README-en.md @@ -0,0 +1,609 @@ +
+ +# Open-WebSearch MCP Server + +[![ModelScope](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/Aas-ee/3af09e0f4c7821fb2e9acb96483a5ff0/raw/badge.json&color=%23de5a16)](https://www.modelscope.cn/mcp/servers/Aasee1/open-webSearch) +[![Trust Score](https://archestra.ai/mcp-catalog/api/badge/quality/Aas-ee/open-webSearch)](https://archestra.ai/mcp-catalog/aas-ee__open-websearch) +[![smithery badge](https://smithery.ai/badge/@Aas-ee/open-websearch)](https://smithery.ai/server/@Aas-ee/open-websearch) +![Version](https://img.shields.io/github/v/release/Aas-ee/open-websearch) +![License](https://img.shields.io/github/license/Aas-ee/open-websearch) +![Issues](https://img.shields.io/github/issues/Aas-ee/open-websearch) + +**[🇨🇳 中文](./README.md) | 🇺🇸 English** + +
+ +A Model Context Protocol (MCP) server based on multi-engine search results, supporting free web search without API keys. + + +
+ Click to expand simple demo (deepseek-v3) + +--- + +### 🧩 Demo Start + +### prompt: + +> Use the websearch tool to search "Open-WebSearch MCP", using the csdn engine, query 20 records, tell me the engine returned by the tool, along with related info, then use the URL to fetch articles by author Aasee (if there are multiple, query them sequentially, not simultaneously). Format the output properly. + +--- + +### assistant: + +I will use the MCP_search tool to query "Open-WebSearch MCP" using the CSDN engine to fetch 20 records. + + + +### Query Result Analysis + +1. **Search Engine Used**: CSDN +2. **Total Records**: 20 + +### Articles by Author Aasee +The search results show 2 articles by author "Aasee.": + +1. **Article Title**: "开源 AI 联网搜索工具:Open-WebSearch MCP 全新升级,支持多引擎 + 流式响应!" + **URL**: https://blog.csdn.net/weixin_45801664/article/details/149000138 + **Summary**: This project provides free, controllable web search capabilities for AI plugin development, supporting Bing, Baidu, CSDN multi-engine combined search... + +2. **Article Title**: "Web Seach 搜索 MCP 启动!" + **URL**: https://blog.csdn.net/weixin_45801664/article/details/148813614 + **Summary**: Open-source Web Search MCP server Open-WebSearch launched, solving the problem of AI models unable to access latest web information... + +### Fetching First Article Content +I will first fetch the full content of the first article: + + + +# Search Result Analysis + +## Engine Info Returned by Tool +Used the CSDN search engine for the query, returning 20 related records. + +## Articles by Author Aasee + +### Article 1: "开源 AI 联网搜索工具:Open-WebSearch MCP 全新升级,支持多引擎 + 流式响应!" +``` +🚀 Open-source AI Web Search Tool: Open-WebSearch MCP New Upgrade, Multi-engine + Streaming Response! + +💡 "Let your AI plugins truly access the web" — No API Key needed, controllable search results, ready to use! + +Project Highlights: +✅ Multi-engine Real-time Search: Supports Bing, Baidu, CSDN, DuckDuckGo, Exa, Brave +✅ Streaming Response (MCP Protocol): Compatible with Claude plugin (MCP) protocol +✅ Article Content Extraction: Supports extracting full CSDN blog articles +✅ Completely Free & No API Key Required +✅ One-click Docker Deployment + +Installation: +- Git clone: git clone https://github.com/Aas-ee/open-webSearch +- Or use Docker: docker run -d --name web-search -p 3000:3000 -e ENABLE_CORS=true -e CORS_ORIGIN=* ghcr.io/aas-ee/open-web-search:latest + +MCP Tool Support: +🔍 search: Multi-engine search tool +📄 fetchCsdnArticle: Extract CSDN article full text +🧪 fetchLinuxDoArticle: Fetch Linux.do articles (in development) + +Project Links: +🧩 GitHub: https://github.com/Aas-ee/open-webSearch +📦 Docker: ghcr.io/aas-ee/open-web-search:latest +``` + +### Article 2: "Web Seach 搜索 MCP 启动!" +``` +Open-source Web Search MCP server Open-WebSearch launched, solving the problem of AI models +unable to access latest web information. +The project provides free Baidu search results API, supports structured JSON return format, +compatible with Claude and other AI tools' MCP protocol. +Users only need simple installation to use, no API keys required... +``` + +Would you like me to look up other articles by author Aasee? I can continue searching for you. + +### ✅ Demo End + +--- +
+ +## Features + +- Web search using multi-engine results + - bing + - baidu + - linux.do + - csdn + - duckduckgo + - exa + - brave + - juejin +- HTTP proxy configuration support for accessing restricted resources +- No API keys or authentication required +- Returns structured results with titles, URLs, and descriptions +- Configurable number of results per search +- Customizable default search engine +- Support for fetching individual article content + - csdn + - github (README files) + - juejin + - linux.do + +## TODO +- Support for ~~Bing~~ (already supported), ~~DuckDuckGo~~ (already supported), ~~Exa~~ (already supported), ~~Brave~~ (already supported), Google and other search engines +- Support for more blogs, forums, and social platforms +- Optimize article content extraction, add support for more sites +- ~~Support for GitHub README fetching~~ (already supported) + +## Installation Guide + +### NPX Quick Start (Recommended) + +The fastest way to get started: + +```bash +# Basic usage +npx open-websearch@latest + +# With environment variables (Linux/macOS) +DEFAULT_SEARCH_ENGINE=duckduckgo ENABLE_CORS=true npx open-websearch@latest + +# Windows PowerShell +$env:DEFAULT_SEARCH_ENGINE="duckduckgo"; $env:ENABLE_CORS="true"; npx open-websearch@latest + +# Windows CMD +set MODE=stdio && set DEFAULT_SEARCH_ENGINE=duckduckgo && npx open-websearch@latest + +# Cross-platform (requires cross-env, Used for local development) +# Global install +npm install -g open-websearch +npx cross-env DEFAULT_SEARCH_ENGINE=duckduckgo ENABLE_CORS=true open-websearch +``` + +**Environment Variables:** + +| Variable | Default | Options | Description | +|----------|-------------------------|---------|-------------| +| `ENABLE_CORS` | `false` | `true`, `false` | Enable CORS | +| `CORS_ORIGIN` | `*` | Any valid origin | CORS origin configuration | +| `DEFAULT_SEARCH_ENGINE` | `bing` | `bing`, `duckduckgo`, `exa`, `brave`, `baidu`, `csdn`, `juejin`, `linuxdo` | Default search engine | +| `USE_PROXY` | `false` | `true`, `false` | Enable HTTP proxy | +| `PROXY_URL` | `http://127.0.0.1:10809` | Any valid URL | Proxy server URL | +| `MODE` | `both` | `both`, `http`, `stdio` | Server mode: both HTTP+STDIO, HTTP only, or STDIO only | +| `PORT` | `3000` | 1-65535 | Server port | +| `ALLOWED_SEARCH_ENGINES` | empty (all available) | Comma-separated engine names | Limit which search engines can be used; if the default engine is not in this list, the first allowed engine becomes the default | +| `MAX_DESCRIPTION_LENGTH` | unlimited | Positive integer | Global max length for search result descriptions, excess will be truncated | +| `MCP_TOOL_SEARCH_NAME` | `search` | Valid MCP tool name | Custom name for the search tool | +| `MCP_TOOL_FETCH_LINUXDO_NAME` | `fetchLinuxDoArticle` | Valid MCP tool name | Custom name for the Linux.do article fetch tool | +| `MCP_TOOL_FETCH_CSDN_NAME` | `fetchCsdnArticle` | Valid MCP tool name | Custom name for the CSDN article fetch tool | +| `MCP_TOOL_FETCH_GITHUB_NAME` | `fetchGithubReadme` | Valid MCP tool name | Custom name for the GitHub README fetch tool | +| `MCP_TOOL_FETCH_JUEJIN_NAME` | `fetchJuejinArticle` | Valid MCP tool name | Custom name for the Juejin article fetch tool | + +**Common configurations:** +```bash +# Enable proxy for restricted regions +USE_PROXY=true PROXY_URL=http://127.0.0.1:7890 npx open-websearch@latest + +# Full configuration +DEFAULT_SEARCH_ENGINE=duckduckgo ENABLE_CORS=true USE_PROXY=true PROXY_URL=http://127.0.0.1:7890 PORT=8080 npx open-websearch@latest +``` + +**Windows Users Note:** +- In PowerShell, use `$env:VAR="value"; ` syntax +- For local development, it's recommended to use `npx cross-env` for cross-platform compatibility + +### Local Installation + +1. Clone or download this repository +2. Install dependencies: +```bash +npm install +``` +3. Build the server: +```bash +npm run build +``` +4. Add the server to your MCP configuration: + +**Cherry Studio:** +```json +{ + "mcpServers": { + "web-search": { + "name": "Web Search MCP", + "type": "streamableHttp", + "description": "Multi-engine web search with article fetching", + "isActive": true, + "baseUrl": "http://localhost:3000/mcp" + } + } +} +``` + +**VSCode (Claude Dev Extension):** +```json +{ + "mcpServers": { + "web-search": { + "transport": { + "type": "streamableHttp", + "url": "http://localhost:3000/mcp" + } + }, + "web-search-sse": { + "transport": { + "type": "sse", + "url": "http://localhost:3000/sse" + } + } + } +} +``` + +**Claude Desktop:** +```json +{ + "mcpServers": { + "web-search": { + "type": "http", + "url": "http://localhost:3000/mcp" + }, + "web-search-sse": { + "type": "sse", + "url": "http://localhost:3000/sse" + } + } +} +``` + +**NPX Command Line Configuration:** +```json +{ + "mcpServers": { + "web-search": { + "args": [ + "open-websearch@latest" + ], + "command": "npx", + "env": { + "MODE": "stdio", + "DEFAULT_SEARCH_ENGINE": "duckduckgo", + "ALLOWED_SEARCH_ENGINES": "duckduckgo,bing,exa" + } + } + } +} +``` + +**Local STDIO Configuration for Cherry Studio (Windows):** +```json +{ + "mcpServers": { + "open-websearch-local": { + "command": "node", + "args": ["C:/path/to/your/project/build/index.js"], + "env": { + "MODE": "stdio", + "DEFAULT_SEARCH_ENGINE": "duckduckgo", + "ALLOWED_SEARCH_ENGINES": "duckduckgo,bing,exa" + } + } + } +} +``` + +### Docker Deployment + +Quick deployment using Docker Compose: + +```bash +docker-compose up -d +``` + +Or use Docker directly: +```bash +docker run -d --name web-search -p 3000:3000 -e ENABLE_CORS=true -e CORS_ORIGIN=* ghcr.io/aas-ee/open-web-search:latest +``` + +Environment variable configuration: + +| Variable | Default | Options | Description | +|----------|-------------------------|---------|-------------| +| `ENABLE_CORS` | `false` | `true`, `false` | Enable CORS | +| `CORS_ORIGIN` | `*` | Any valid origin | CORS origin configuration | +| `DEFAULT_SEARCH_ENGINE` | `bing` | `bing`, `duckduckgo`, `exa`, `brave`, `baidu`, `csdn`, `juejin`, `linuxdo` | Default search engine | +| `USE_PROXY` | `false` | `true`, `false` | Enable HTTP proxy | +| `PROXY_URL` | `http://127.0.0.1:10809` | Any valid URL | Proxy server URL | +| `MODE` | `both` | `both`, `http`, `stdio` | Server mode | +| `PORT` | `3000` | 1-65535 | Server port | +| `ALLOWED_SEARCH_ENGINES` | empty (all available) | Comma-separated engine names | Limit which search engines can be used | +| `MAX_DESCRIPTION_LENGTH` | unlimited | Positive integer | Global max length for search result descriptions | + +Then configure in your MCP client: +```json +{ + "mcpServers": { + "web-search": { + "name": "Web Search MCP", + "type": "streamableHttp", + "description": "Multi-engine web search with article fetching", + "isActive": true, + "baseUrl": "http://localhost:3000/mcp" + }, + "web-search-sse": { + "transport": { + "name": "Web Search MCP", + "type": "sse", + "description": "Multi-engine web search with article fetching", + "isActive": true, + "url": "http://localhost:3000/sse" + } + } + } +} +``` + +## Usage Guide + +The server provides five tools: `search`, `fetchCsdnArticle`, `fetchGithubReadme`, `fetchJuejinArticle`, and `fetchLinuxDoArticle`. + +### search Tool Usage + +```typescript +{ + "query": string, // Search query + "limit": number, // Optional: Number of results to return (default: 10, range: 1-50) + "engines": string[], // Optional: Engines to use (bing,baidu,linuxdo,csdn,duckduckgo,exa,brave,juejin) default bing, case-insensitive + "maxDescriptionLength": number // Optional: Max description length per call, overrides global MAX_DESCRIPTION_LENGTH +} +``` + +Usage example: +```typescript +use_mcp_tool({ + server_name: "web-search", + tool_name: "search", + arguments: { + query: "search content", + limit: 3, // Optional parameter + engines: ["bing", "csdn", "duckduckgo", "exa", "brave", "juejin"] // Optional parameter, supports multi-engine combined search + } +}) +``` + +Response example: +```json +[ + { + "title": "Example Search Result", + "url": "https://example.com", + "description": "Description text of the search result...", + "source": "Source", + "engine": "Engine used" + } +] +``` + +### fetchCsdnArticle Tool Usage + +Used to fetch complete content of CSDN blog articles. + +```typescript +{ + "url": string // URL from CSDN search results using the search tool +} +``` + +Usage example: +```typescript +use_mcp_tool({ + server_name: "web-search", + tool_name: "fetchCsdnArticle", + arguments: { + url: "https://blog.csdn.net/xxx/article/details/xxx" + } +}) +``` + +Response example: +```json +[ + { + "content": "Example search result" + } +] +``` + +### fetchLinuxDoArticle Tool Usage + +Used to fetch complete content of Linux.do forum articles. + +```typescript +{ + "url": string // URL from linuxdo search results using the search tool +} +``` + +Usage example: +```typescript +use_mcp_tool({ + server_name: "web-search", + tool_name: "fetchLinuxDoArticle", + arguments: { + url: "https://xxxx.json" + } +}) +``` + +Response example: +```json +[ + { + "content": "Example search result" + } +] +``` + +### fetchGithubReadme Tool Usage + +Used to fetch README content from GitHub repositories. + +```typescript +{ + "url": string // GitHub repository URL (supports HTTPS, SSH formats) +} +``` + +Usage example: +```typescript +use_mcp_tool({ + server_name: "web-search", + tool_name: "fetchGithubReadme", + arguments: { + url: "https://github.com/Aas-ee/open-webSearch" + } +}) +``` + +Supported URL formats: +- HTTPS: `https://github.com/owner/repo` +- HTTPS with .git: `https://github.com/owner/repo.git` +- SSH: `git@github.com:owner/repo.git` +- URLs with parameters: `https://github.com/owner/repo?tab=readme` + +Response example: +```json +[ + { + "content": "
\n\n# Open-WebSearch MCP Server..." + } +] +``` + +### fetchJuejinArticle Tool Usage + +Used to fetch complete content of Juejin articles. + +```typescript +{ + "url": string // Juejin article URL from search results +} +``` + +Usage example: +```typescript +use_mcp_tool({ + server_name: "web-search", + tool_name: "fetchJuejinArticle", + arguments: { + url: "https://juejin.cn/post/7520959840199360563" + } +}) +``` + +Supported URL format: +- `https://juejin.cn/post/{article_id}` + +Response example: +```json +[ + { + "content": "🚀 开源 AI 联网搜索工具:Open-WebSearch MCP 全新升级,支持多引擎 + 流式响应..." + } +] +``` + +## Usage Limitations + +Since this tool works by scraping multi-engine search results, please note the following important limitations: + +1. **Rate Limiting**: + - Too many searches in a short time may cause the used engines to temporarily block requests + - Recommendations: + - Maintain reasonable search frequency + - Use the limit parameter judiciously + - Add delays between searches when necessary + +2. **Result Accuracy**: + - Depends on the HTML structure of corresponding engines, may fail when engines update + - Some results may lack metadata like descriptions + - Complex search operators may not work as expected + +3. **Legal Terms**: + - This tool is for personal use only + - Please comply with the terms of service of corresponding engines + - Implement appropriate rate limiting based on your actual use case + +4. **Search Engine Configuration**: + - Default search engine can be set via the `DEFAULT_SEARCH_ENGINE` environment variable + - Supported engines: bing, duckduckgo, exa, brave + - The default engine is used when searching specific websites + +5. **Proxy Configuration**: + - HTTP proxy can be configured when certain search engines are unavailable in specific regions + - Enable proxy with environment variable `USE_PROXY=true` + - Configure proxy server address with `PROXY_URL` + +## Contributing + +Welcome to submit issue reports and feature improvement suggestions! + +### Contributor Guide + +If you want to fork this repository and publish your own Docker image, you need to make the following configurations: + +#### GitHub Secrets Configuration + +To enable automatic Docker image building and publishing, please add the following secrets in your GitHub repository settings (Settings → Secrets and variables → Actions): + +**Required Secrets:** +- `GITHUB_TOKEN`: Automatically provided by GitHub (no setup needed) + +**Optional Secrets (for Alibaba Cloud ACR):** +- `ACR_REGISTRY`: Your Alibaba Cloud Container Registry URL (e.g., `registry.cn-hangzhou.aliyuncs.com`) +- `ACR_USERNAME`: Your Alibaba Cloud ACR username +- `ACR_PASSWORD`: Your Alibaba Cloud ACR password +- `ACR_IMAGE_NAME`: Your image name in ACR (e.g., `your-namespace/open-web-search`) + +#### CI/CD Workflow + +The repository includes a GitHub Actions workflow (`.github/workflows/docker.yml`) that automatically: + +1. **Trigger Conditions**: + - Push to `main` branch + - Push version tags (`v*`) + - Manual workflow trigger + +2. **Build and Push to**: + - GitHub Container Registry (ghcr.io) - always enabled + - Alibaba Cloud Container Registry - only enabled when ACR secrets are configured + +3. **Image Tags**: + - `ghcr.io/your-username/open-web-search:latest` + - `your-acr-address/your-image-name:latest` (if ACR is configured) + +#### Fork and Publish Steps: + +1. **Fork the repository** to your GitHub account +2. **Configure secrets** (if you need ACR publishing): + - Go to Settings → Secrets and variables → Actions in your forked repository + - Add the ACR-related secrets listed above +3. **Push changes** to the `main` branch or create version tags +4. **GitHub Actions will automatically build and push** your Docker image +5. **Use your image**, update the Docker command: + ```bash + docker run -d --name web-search -p 3000:3000 -e ENABLE_CORS=true -e CORS_ORIGIN=* ghcr.io/your-username/open-web-search:latest + ``` + +#### Notes: +- If you don't configure ACR secrets, the workflow will only publish to GitHub Container Registry +- Make sure your GitHub repository has Actions enabled +- The workflow will use your GitHub username (converted to lowercase) as the GHCR image name + +
+ +## Star History +If you find this project helpful, please consider giving it a ⭐ Star! + +[![Star History Chart](https://api.star-history.com/svg?repos=Aas-ee/open-webSearch&type=Date)](https://www.star-history.com/#Aas-ee/open-webSearch&Date) + +
diff --git a/README-zh.md b/README-zh.md deleted file mode 100644 index 384947f..0000000 --- a/README-zh.md +++ /dev/null @@ -1,608 +0,0 @@ -
- -# Open-WebSearch MCP 服务器 - -[![ModelScope](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/Aas-ee/3af09e0f4c7821fb2e9acb96483a5ff0/raw/badge.json&color=%23de5a16)](https://www.modelscope.cn/mcp/servers/Aasee1/open-webSearch) -[![smithery badge](https://smithery.ai/badge/@Aas-ee/open-websearch)](https://smithery.ai/server/@Aas-ee/open-websearch) -![Version](https://img.shields.io/github/v/release/Aas-ee/open-websearch) -![License](https://img.shields.io/github/license/Aas-ee/open-websearch) -![Issues](https://img.shields.io/github/issues/Aas-ee/open-websearch) - -**🇨🇳 中文 | [🇺🇸 English](./README.md)** - -
- -一个基于多引擎搜索结果的模型上下文协议(MCP)服务器,支持免费网络搜索,无需API密钥。 - - -
- 点击展开查看简单示例效果(deepseek-v3) - ---- - -### 🧩 示例开始 - -### prompt: - -> 使用websearch工具查询 《Open-WebSearch MCP》,用csdn引擎,查20条记录,告诉我工具返回的engine,以及相关信息,再通过url查询作者是Aasee的文章内容(如果有多篇顺序查询,不要同时查询)。规范输出 - ---- - -### assistant: - -我将使用MCP_search工具查询《Open-WebSearch MCP》并使用CSDN引擎获取20条记录。 - - - -### 查询结果分析 - -1. **使用的搜索引擎**: CSDN -2. **总记录数**: 20条 - -### 作者Aasee的文章列表 -搜索结果显示有2篇作者是"Aasee."的文章: - -1. **文章标题**: "开源 AI 联网搜索工具:Open-WebSearch MCP 全新升级,支持多引擎 + 流式响应!" - **URL**: https://blog.csdn.net/weixin_45801664/article/details/149000138?ops_request_misc=%257B%2522request%255Fid%2522%253A%252203ceec270907178223ab139631d9a81f%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=03ceec270907178223ab139631d9a81f&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-1-149000138-null-null.142^v102^pc_search_result_base6&utm_term=Open-WebSearch%20MCP - **简介**: 该项目为AI插件开发提供免费、可控的联网搜索能力,支持Bing、百度、CSDN多引擎组合搜索... - -2. **文章标题**: "Web Seach 搜索 MCP 启动!" - **URL**: https://blog.csdn.net/weixin_45801664/article/details/148813614?ops_request_misc=%257B%2522request%255Fid%2522%253A%252203ceec270907178223ab139631d9a81f%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=03ceec270907178223ab139631d9a81f&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-4-148813614-null-null.142^v102^pc_search_result_base6&utm_term=Open-WebSearch%20MCP - **简介**: 开源Web搜索MCP服务器Open-WebSearch上线,解决AI模型无法获取最新网络信息的问题... - -### 开始查询第一篇文章内容 -我将先查询第一篇文章的全文内容: - - - -# 搜索结果分析 - -## 工具返回的引擎信息 -使用了CSDN搜索引擎进行查询,返回了20条相关记录。 - -## 作者Aasee的相关文章内容 - -### 文章1: "开源 AI 联网搜索工具:Open-WebSearch MCP 全新升级,支持多引擎 + 流式响应!" -``` -🚀 开源 AI 联网搜索工具:Open-WebSearch MCP 全新升级,支持多引擎 + 流式响应! - -💡「让你的 AI 插件真正能联网」—— 不需要 API Key,搜索结果可控、开箱即用! - -项目亮点一览: -✅ 多引擎实时搜索:支持 Bing、百度、CSDN、DuckDuckGo、Exa、Brave -✅ 流式响应(MCP协议):兼容 Claude 插件(MCP)协议 -✅ 文章正文抓取:支持提取 CSDN 博客文章全文 -✅ 完全免费 & 无需 API Key -✅ Docker 一键部署 - -安装方法: -- Git克隆项目: git clone https://github.com/Aas-ee/open-webSearch -- 或使用Docker: docker run -d --name web-search -p 3000:3000 -e ENABLE_CORS=true -e CORS_ORIGIN=* ghcr.io/aas-ee/open-web-search:latest - -MCP工具支持: -🔍 search:多引擎搜索工具 -📄 fetchCsdnArticle:提取 CSDN 文章全文 -🧪 fetchLinuxDoArticle:抓取 Linux.do 文章(开发中) - -项目地址: -🧩 GitHub: https://github.com/Aas-ee/open-webSearch -📦 Docker: ghcr.io/aas-ee/open-web-search:latest -``` - -### 文章2: "Web Seach 搜索 MCP 启动!" -``` -开源Web搜索MCP服务器Open-WebSearch上线,解决AI模型无法获取最新网络信息的问题。 -该项目免费提供百度搜索结果API,支持结构化JSON返回格式,兼容Claude等AI工具的MCP协议。 -用户仅需简单安装即可使用,无需API密钥... -``` - -需要查询其他Aasee作者的文章内容吗?我可以继续为您检索。 - -### ✅ 示例结束 - ---- -
- -## 功能特性 - -- 使用多引擎搜索结果进行网络检索 - - bing - - baidu - - ~~linux.do~~ 暂不支持 - - csdn - - duckduckgo - - exa - - brave - - juejin -- 支持HTTP代理配置,轻松解决网络访问限制 -- 无需API密钥或身份验证 -- 返回带标题、URL和描述的结构化结果 -- 可配置每次搜索返回的结果数量 -- 可自定义默认搜索引擎 -- 支持获取单篇文章内容 - - csdn - - github(README文件) - -## TODO -- 支持~~Bing~~(已支持),~~DuckDuckGo~~(已支持),~~Exa~~(已支持),~~Brave~~(已支持),Google等搜索引擎 -- 支持更多博客论坛、社交软件 -- 优化文章内容提取功能,增加更多站点支持 -- ~~支持GitHub README获取~~(已支持) - -## 安装指南 - -### NPX 快速启动(推荐) - -最快的使用方式: - -```bash -# 基本使用 -npx open-websearch@latest - -# 带环境变量(Linux/macOS) -DEFAULT_SEARCH_ENGINE=duckduckgo ENABLE_CORS=true npx open-websearch@latest - -# Windows PowerShell -$env:DEFAULT_SEARCH_ENGINE="duckduckgo"; $env:ENABLE_CORS="true"; npx open-websearch@latest - -# Windows CMD -set MODE=stdio && set DEFAULT_SEARCH_ENGINE=duckduckgo && npx open-websearch@latest - -# 跨平台(需要 cross-env,用于本地开发) -# 全局安装 -npm install -g open-websearch -npx cross-env DEFAULT_SEARCH_ENGINE=duckduckgo ENABLE_CORS=true open-websearch -``` - -**环境变量说明:** - -| 变量名 | 默认值 | 可选值 | 说明 | -|--------|-------------------------|--------|--------------------------------------| -| `ENABLE_CORS` | `false` | `true`, `false` | 启用CORS | -| `CORS_ORIGIN` | `*` | 任何有效来源 | CORS来源配置 | -| `DEFAULT_SEARCH_ENGINE` | `bing` | `bing`, `duckduckgo`, `exa`, `brave`, `baidu`, `csdn`, `juejin` | 默认搜索引擎 | -| `USE_PROXY` | `false` | `true`, `false` | 启用HTTP代理 | -| `PROXY_URL` | `http://127.0.0.1:7890` | 任何有效URL | 代理服务器URL | -| `MODE` | `both` | `both`, `http`, `stdio` | 服务器模式:同时支持HTTP+STDIO、仅HTTP或仅STDIO | -| `PORT` | `3000` | 1-65535 | 服务器端口 | -| `ALLOWED_SEARCH_ENGINES` | 空(全部可用) | 逗号分隔的引擎名称 | 限制可使用的搜索引擎,如默认搜索引擎不在范围,则默认第一个为默认搜索引擎 | -| `MCP_TOOL_SEARCH_NAME` | `search` | 有效的MCP工具名称 | 搜索工具的自定义名称 | -| `MCP_TOOL_FETCH_LINUXDO_NAME` | `fetchLinuxDoArticle` | 有效的MCP工具名称 | Linux.do文章获取工具的自定义名称 | -| `MCP_TOOL_FETCH_CSDN_NAME` | `fetchCsdnArticle` | 有效的MCP工具名称 | CSDN文章获取工具的自定义名称 | -| `MCP_TOOL_FETCH_GITHUB_NAME` | `fetchGithubReadme` | 有效的MCP工具名称 | GitHub README获取工具的自定义名称 | -| `MCP_TOOL_FETCH_JUEJIN_NAME` | `fetchJuejinArticle` | 有效的MCP工具名称 | 掘金文章获取工具的自定义名称 | - -**常用配置示例:** -```bash -# 启用代理(适用于网络受限地区) -USE_PROXY=true PROXY_URL=http://127.0.0.1:7890 npx open-websearch@latest - -# 完整配置 -DEFAULT_SEARCH_ENGINE=duckduckgo ENABLE_CORS=true USE_PROXY=true PROXY_URL=http://127.0.0.1:7890 PORT=8080 npx open-websearch@latest -``` - -**Windows 用户注意事项:** -- 在 PowerShell 中使用 `$env:VAR="value"; ` 语法 -- 本地开发推荐使用 `npx cross-env` 实现跨平台兼容 - -### 本地安装 - -1. 克隆或下载本仓库 -2. 安装依赖项: -```bash -npm install -``` -3. 构建服务器: -```bash -npm run build -``` -4. 将服务器添加到您的MCP配置中: - -**Cherry Studio:** -```json -{ - "mcpServers": { - "web-search": { - "name": "Web Search MCP", - "type": "streamableHttp", - "description": "Multi-engine web search with article fetching", - "isActive": true, - "baseUrl": "http://localhost:3000/mcp" - } - } -} -``` - -**VSCode版(Claude开发扩展):** -```json -{ - "mcpServers": { - "web-search": { - "transport": { - "type": "streamableHttp", - "url": "http://localhost:3000/mcp" - } - }, - "web-search-sse": { - "transport": { - "type": "sse", - "url": "http://localhost:3000/sse" - } - } - } -} -``` - -**Claude桌面版:** -```json -{ - "mcpServers": { - "web-search": { - "transport": { - "type": "streamableHttp", - "url": "http://localhost:3000/mcp" - } - }, - "web-search-sse": { - "transport": { - "type": "sse", - "url": "http://localhost:3000/sse" - } - } - } -} -``` - -**NPX命令行配置示例:** -```json -{ - "mcpServers": { - "web-search": { - "args": [ - "open-websearch@latest" - ], - "command": "npx", - "env": { - "MODE": "stdio", - "DEFAULT_SEARCH_ENGINE": "duckduckgo", - "ALLOWED_SEARCH_ENGINES": "duckduckgo,bing,exa" - } - } - } -} -``` - -**Cherry Studio 本地 STDIO 配置 (Windows):** -```json -{ - "mcpServers": { - "open-websearch-local": { - "command": "node", - "args": ["C:/你的项目路径/build/index.js"], - "env": { - "MODE": "stdio", - "DEFAULT_SEARCH_ENGINE": "duckduckgo", - "ALLOWED_SEARCH_ENGINES": "duckduckgo,bing,exa" - } - } - } -} -``` - -### Docker部署 - -使用Docker Compose快速部署: - -```bash -docker-compose up -d -``` - -或者直接使用Docker: -```bash -docker run -d --name web-search -p 3000:3000 -e ENABLE_CORS=true -e CORS_ORIGIN=* ghcr.io/aas-ee/open-web-search:latest -``` - -配置环境变量说明: - -| 变量名 | 默认值 | 可选值 | 说明 | -|--------|-------------------------|--------|------| -| `ENABLE_CORS` | `false` | `true`, `false` | 启用CORS | -| `CORS_ORIGIN` | `*` | 任何有效来源 | CORS来源配置 | -| `DEFAULT_SEARCH_ENGINE` | `bing` | `bing`, `duckduckgo`, `exa`, `brave` | 默认搜索引擎 | -| `USE_PROXY` | `false` | `true`, `false` | 启用HTTP代理 | -| `PROXY_URL` | `http://127.0.0.1:7890` | 任何有效URL | 代理服务器URL | -| `PORT` | `3000` | 1-65535 | 服务器端口 | - -然后在MCP客户端中配置: -```json -{ - "mcpServers": { - "web-search": { - "name": "Web Search MCP", - "type": "streamableHttp", - "description": "Multi-engine web search with article fetching", - "isActive": true, - "baseUrl": "http://localhost:3000/mcp" - }, - "web-search-sse": { - "transport": { - "name": "Web Search MCP", - "type": "sse", - "description": "Multi-engine web search with article fetching", - "isActive": true, - "url": "http://localhost:3000/sse" - } - } - } -} -``` - -## 使用说明 - -服务器提供四个工具:`search`、`fetchLinuxDoArticle`、`fetchCsdnArticle` 和 `fetchGithubReadme`。 - -### search工具使用说明 - -```typescript -{ - "query": string, // 搜索查询词 - "limit": number, // 可选:返回结果数量(默认:10) - "engines": string[] // 可选:使用的引擎 (bing,baidu,linuxdo,csdn,duckduckgo,exa,brave,juejin) 默认bing -} -``` - -使用示例: -```typescript -use_mcp_tool({ - server_name: "web-search", - tool_name: "search", - arguments: { - query: "搜索内容", - limit: 3, // 可选参数 - engines: ["bing", "csdn", "duckduckgo", "exa", "brave", "juejin"] // 可选参数,支持多引擎组合搜索 - } -}) -``` - -返回示例: -```json -[ - { - "title": "示例搜索结果", - "url": "https://example.com", - "description": "搜索结果的描述文本...", - "source": "来源", - "engine": "使用的引擎" - } -] -``` - - -### fetchCsdnArticle工具使用说明 - -用于获取CSDN博客文章的完整内容。 - -```typescript -{ - "url": string // search 工具使用csdn查询出的url -} -``` - -使用示例: -```typescript -use_mcp_tool({ - server_name: "web-search", - tool_name: "fetchCsdnArticle", - arguments: { - url: "https://blog.csdn.net/xxx/article/details/xxx" - } -}) -``` - -返回示例: -```json -[ - { - "content": "示例搜索结果" - } -] -``` - -### fetchLinuxDoArticle工具使用说明 - -用于获取Linux.do论坛文章的完整内容。 - -```typescript -{ - "url": string // search 工具使用linuxdo查询出的url -} -``` - -使用示例: -```typescript -use_mcp_tool({ - server_name: "web-search", - tool_name: "fetchLinuxDoArticle", - arguments: { - url: "https://xxxx.json" - } -}) -``` - -返回示例: -```json -[ - { - "content": "示例搜索结果" - } -] - -``` - - -### fetchGithubReadme工具使用说明 - -用于获取GitHub仓库的README文件内容。 - -```typescript -{ - "url": string // GitHub仓库URL(支持HTTPS、SSH格式) -} -``` - -使用示例: -```typescript -use_mcp_tool({ - server_name: "web-search", - tool_name: "fetchGithubReadme", - arguments: { - url: "https://github.com/Aas-ee/open-webSearch" - } -}) -``` - -支持的URL格式: -- HTTPS: `https://github.com/owner/repo` -- HTTPS with .git: `https://github.com/owner/repo.git` -- SSH: `git@github.com:owner/repo.git` -- 带参数的URL: `https://github.com/owner/repo?tab=readme` - -返回示例: -```json -[ - { - "content": "
\n\n# Open-WebSearch MCP Server..." - } -] -``` - - -### fetchJuejinArticle工具使用说明 - -用于获取掘金文章的完整内容。 - -```typescript -{ - "url": string // 掘金文章URL -} -``` - -使用示例: -```typescript -use_mcp_tool({ - server_name: "web-search", - tool_name: "fetchJuejinArticle", - arguments: { - url: "https://juejin.cn/post/7520959840199360563" - } -}) -``` - -支持的URL格式: -- `https://juejin.cn/post/{文章ID}` - -返回示例: -```json -[ - { - "content": "🚀 开源 AI 联网搜索工具:Open-WebSearch MCP 全新升级,支持多引擎 + 流式响应..." - } -] -``` - - -## 使用限制 - -由于本工具通过爬取多引擎搜索结果实现,请注意以下重要限制: - -1. **频率限制**: - - 短时间内搜索次数过多可能导致使用的引擎暂时屏蔽请求 - - 建议: - - 保持合理的搜索频率 - - 审慎使用limit参数 - - 必要时可在搜索间设置延迟 - -2. **结果准确性**: - - 依赖对应引擎的HTML结构,可能随引擎改版失效 - - 部分结果可能缺失描述等元数据 - - 复杂搜索运算符可能无法按预期工作 - -3. **法律条款**: - - 本工具仅限个人使用 - - 请遵守对应引擎的服务条款 - - 建议根据实际使用场景实施适当的频率限制 - -4. **搜索引擎配置**: - - 可通过环境变量`DEFAULT_SEARCH_ENGINE`设置默认搜索引擎 - - 支持的引擎有:bing, duckduckgo, exa, brave - - 当搜索特定网站内容时,会自动使用默认搜索引擎 - -5. **代理服务配置**: - - 当某些搜索引擎在特定地区不可用时,可配置HTTP代理 - - 通过环境变量`USE_PROXY=true`启用代理 - - 使用`PROXY_URL`配置代理服务器地址 - -## 贡献指南 - -欢迎提交问题报告和功能改进建议! - -### 贡献者指南 - -如果您想要fork本仓库并发布自己的Docker镜像,需要进行以下配置: - -#### GitHub Secrets配置 - -要启用自动Docker镜像构建和发布功能,请在您的GitHub仓库设置中添加以下secrets(Settings → Secrets and variables → Actions): - -**必需的Secrets:** -- `GITHUB_TOKEN`: GitHub自动提供(无需设置) - -**可选的Secrets(用于阿里云ACR):** -- `ACR_REGISTRY`: 您的阿里云容器镜像服务URL(例如:`registry.cn-hangzhou.aliyuncs.com`) -- `ACR_USERNAME`: 您的阿里云ACR用户名 -- `ACR_PASSWORD`: 您的阿里云ACR密码 -- `ACR_IMAGE_NAME`: 您在ACR中的镜像名称(例如:`your-namespace/open-web-search`) - -#### CI/CD工作流程 - -仓库包含一个GitHub Actions工作流程(`.github/workflows/docker.yml`),会自动: - -1. **触发条件**: - - 推送到`main`分支 - - 推送版本标签(`v*`) - - 手动触发workflow - -2. **构建并推送到**: - - GitHub Container Registry (ghcr.io) - 始终启用 - - 阿里云容器镜像服务 - 仅在配置ACR secrets时启用 - -3. **镜像标签**: - - `ghcr.io/您的用户名/open-web-search:latest` - - `您的ACR地址/您的镜像名:latest`(如果配置了ACR) - -#### Fork和发布步骤: - -1. **Fork仓库**到您的GitHub账户 -2. **配置secrets**(如果需要ACR发布): - - 进入您fork的仓库的Settings → Secrets and variables → Actions - - 添加上面列出的ACR相关secrets -3. **推送更改**到`main`分支或创建版本标签 -4. **GitHub Actions将自动构建并推送**您的Docker镜像 -5. **使用您的镜像**,更新Docker命令: - ```bash - docker run -d --name web-search -p 3000:3000 -e ENABLE_CORS=true -e CORS_ORIGIN=* ghcr.io/您的用户名/open-web-search:latest - ``` - -#### 注意事项: -- 如果您不配置ACR secrets,工作流程将只发布到GitHub Container Registry -- 确保您的GitHub仓库已启用Actions功能 -- 工作流程会使用您的GitHub用户名(转换为小写)作为GHCR镜像名称 - -
- -## Star History -如果项目对你有帮助,请考虑给个⭐ Star! - -[![Star History Chart](https://api.star-history.com/svg?repos=Aas-ee/open-webSearch&type=Date)](https://www.star-history.com/#Aas-ee/open-webSearch&Date) - -
diff --git a/README.md b/README.md index 7c6328a..995bf3f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@
-# Open-WebSearch MCP Server +# Open-WebSearch MCP 服务器 [![ModelScope](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/Aas-ee/3af09e0f4c7821fb2e9acb96483a5ff0/raw/badge.json&color=%23de5a16)](https://www.modelscope.cn/mcp/servers/Aasee1/open-webSearch) [![Trust Score](https://archestra.ai/mcp-catalog/api/badge/quality/Aas-ee/open-webSearch)](https://archestra.ai/mcp-catalog/aas-ee__open-websearch) @@ -9,49 +9,140 @@ ![License](https://img.shields.io/github/license/Aas-ee/open-websearch) ![Issues](https://img.shields.io/github/issues/Aas-ee/open-websearch) -**[🇨🇳 中文](./README-zh.md) | 🇺🇸 English** +**🇨🇳 中文 | [🇺🇸 English](./README-en.md)**
-A Model Context Protocol (MCP) server based on multi-engine search results, supporting free web search without API keys. +一个基于多引擎搜索结果的模型上下文协议(MCP)服务器,支持免费网络搜索,无需API密钥。 -## Features -- Web search using multi-engine results +
+ 点击展开查看简单示例效果(deepseek-v3) + +--- + +### 🧩 示例开始 + +### prompt: + +> 使用websearch工具查询 《Open-WebSearch MCP》,用csdn引擎,查20条记录,告诉我工具返回的engine,以及相关信息,再通过url查询作者是Aasee的文章内容(如果有多篇顺序查询,不要同时查询)。规范输出 + +--- + +### assistant: + +我将使用MCP_search工具查询《Open-WebSearch MCP》并使用CSDN引擎获取20条记录。 + + + +### 查询结果分析 + +1. **使用的搜索引擎**: CSDN +2. **总记录数**: 20条 + +### 作者Aasee的文章列表 +搜索结果显示有2篇作者是"Aasee."的文章: + +1. **文章标题**: "开源 AI 联网搜索工具:Open-WebSearch MCP 全新升级,支持多引擎 + 流式响应!" + **URL**: https://blog.csdn.net/weixin_45801664/article/details/149000138?ops_request_misc=%257B%2522request%255Fid%2522%253A%252203ceec270907178223ab139631d9a81f%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=03ceec270907178223ab139631d9a81f&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-1-149000138-null-null.142^v102^pc_search_result_base6&utm_term=Open-WebSearch%20MCP + **简介**: 该项目为AI插件开发提供免费、可控的联网搜索能力,支持Bing、百度、CSDN多引擎组合搜索... + +2. **文章标题**: "Web Seach 搜索 MCP 启动!" + **URL**: https://blog.csdn.net/weixin_45801664/article/details/148813614?ops_request_misc=%257B%2522request%255Fid%2522%253A%252203ceec270907178223ab139631d9a81f%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=03ceec270907178223ab139631d9a81f&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-4-148813614-null-null.142^v102^pc_search_result_base6&utm_term=Open-WebSearch%20MCP + **简介**: 开源Web搜索MCP服务器Open-WebSearch上线,解决AI模型无法获取最新网络信息的问题... + +### 开始查询第一篇文章内容 +我将先查询第一篇文章的全文内容: + + + +# 搜索结果分析 + +## 工具返回的引擎信息 +使用了CSDN搜索引擎进行查询,返回了20条相关记录。 + +## 作者Aasee的相关文章内容 + +### 文章1: "开源 AI 联网搜索工具:Open-WebSearch MCP 全新升级,支持多引擎 + 流式响应!" +``` +🚀 开源 AI 联网搜索工具:Open-WebSearch MCP 全新升级,支持多引擎 + 流式响应! + +💡「让你的 AI 插件真正能联网」—— 不需要 API Key,搜索结果可控、开箱即用! + +项目亮点一览: +✅ 多引擎实时搜索:支持 Bing、百度、CSDN、DuckDuckGo、Exa、Brave +✅ 流式响应(MCP协议):兼容 Claude 插件(MCP)协议 +✅ 文章正文抓取:支持提取 CSDN 博客文章全文 +✅ 完全免费 & 无需 API Key +✅ Docker 一键部署 + +安装方法: +- Git克隆项目: git clone https://github.com/Aas-ee/open-webSearch +- 或使用Docker: docker run -d --name web-search -p 3000:3000 -e ENABLE_CORS=true -e CORS_ORIGIN=* ghcr.io/aas-ee/open-web-search:latest + +MCP工具支持: +🔍 search:多引擎搜索工具 +📄 fetchCsdnArticle:提取 CSDN 文章全文 +🧪 fetchLinuxDoArticle:抓取 Linux.do 文章(开发中) + +项目地址: +🧩 GitHub: https://github.com/Aas-ee/open-webSearch +📦 Docker: ghcr.io/aas-ee/open-web-search:latest +``` + +### 文章2: "Web Seach 搜索 MCP 启动!" +``` +开源Web搜索MCP服务器Open-WebSearch上线,解决AI模型无法获取最新网络信息的问题。 +该项目免费提供百度搜索结果API,支持结构化JSON返回格式,兼容Claude等AI工具的MCP协议。 +用户仅需简单安装即可使用,无需API密钥... +``` + +需要查询其他Aasee作者的文章内容吗?我可以继续为您检索。 + +### ✅ 示例结束 + +--- +
+ +## 功能特性 + +- 使用多引擎搜索结果进行网络检索 - bing - baidu - - ~~linux.do~~ temporarily unsupported + - linux.do - csdn - duckduckgo - exa - brave - juejin -- HTTP proxy configuration support for accessing restricted resources -- No API keys or authentication required -- Returns structured results with titles, URLs, and descriptions -- Configurable number of results per search -- Customizable default search engine -- Support for fetching individual article content +- 支持HTTP代理配置,轻松解决网络访问限制 +- 无需API密钥或身份验证 +- 返回带标题、URL和描述的结构化结果 +- 可配置每次搜索返回的结果数量 +- 可自定义默认搜索引擎 +- 支持获取单篇文章内容 - csdn - - github (README files) + - github(README文件) + - 掘金(juejin) + - linux.do ## TODO -- Support for ~~Bing~~ (already supported), ~~DuckDuckGo~~ (already supported), ~~Exa~~ (already supported), ~~Brave~~ (already supported), Google and other search engines -- Support for more blogs, forums, and social platforms -- Optimize article content extraction, add support for more sites -- ~~Support for GitHub README fetching~~ (already supported) +- 支持~~Bing~~(已支持),~~DuckDuckGo~~(已支持),~~Exa~~(已支持),~~Brave~~(已支持),Google等搜索引擎 +- 支持更多博客论坛、社交软件 +- 优化文章内容提取功能,增加更多站点支持 +- ~~支持GitHub README获取~~(已支持) -## Installation Guide +## 安装指南 -### NPX Quick Start (Recommended) +### NPX 快速启动(推荐) -The fastest way to get started: +最快的使用方式: ```bash -# Basic usage +# 基本使用 npx open-websearch@latest -# With environment variables (Linux/macOS) +# 带环境变量(Linux/macOS) DEFAULT_SEARCH_ENGINE=duckduckgo ENABLE_CORS=true npx open-websearch@latest # Windows PowerShell @@ -60,50 +151,56 @@ $env:DEFAULT_SEARCH_ENGINE="duckduckgo"; $env:ENABLE_CORS="true"; npx open-webse # Windows CMD set MODE=stdio && set DEFAULT_SEARCH_ENGINE=duckduckgo && npx open-websearch@latest -# Cross-platform (requires cross-env, Used for local development) +# 跨平台(需要 cross-env,用于本地开发) +# 全局安装 npm install -g open-websearch npx cross-env DEFAULT_SEARCH_ENGINE=duckduckgo ENABLE_CORS=true open-websearch ``` -**Environment Variables:** - -| Variable | Default | Options | Description | -|----------|-------------------------|---------|-------------| -| `ENABLE_CORS` | `false` | `true`, `false` | Enable CORS | -| `CORS_ORIGIN` | `*` | Any valid origin | CORS origin configuration | -| `DEFAULT_SEARCH_ENGINE` | `bing` | `bing`, `duckduckgo`, `exa`, `brave`, `baidu`, `csdn`, `juejin` | Default search engine | -| `USE_PROXY` | `false` | `true`, `false` | Enable HTTP proxy | -| `PROXY_URL` | `http://127.0.0.1:7890` | Any valid URL | Proxy server URL | -| `MODE` | `both` | `both`, `http`, `stdio` | Server mode: both HTTP+STDIO, HTTP only, or STDIO only | -| `PORT` | `3000` | 1-65535 | Server port | -| `ALLOWED_SEARCH_ENGINES` | empty (all available) | Comma-separated engine names | Limit which search engines can be used; if the default engine is not in this list, the first allowed engine becomes the default | -| `MCP_TOOL_SEARCH_NAME` | `search` | Valid MCP tool name | Custom name for the search tool | -| `MCP_TOOL_FETCH_LINUXDO_NAME` | `fetchLinuxDoArticle` | Valid MCP tool name | Custom name for the Linux.do article fetch tool | -| `MCP_TOOL_FETCH_CSDN_NAME` | `fetchCsdnArticle` | Valid MCP tool name | Custom name for the CSDN article fetch tool | -| `MCP_TOOL_FETCH_GITHUB_NAME` | `fetchGithubReadme` | Valid MCP tool name | Custom name for the GitHub README fetch tool | -| `MCP_TOOL_FETCH_JUEJIN_NAME` | `fetchJuejinArticle` | Valid MCP tool name | Custom name for the Juejin article fetch tool | - -**Common configurations:** +**环境变量说明:** + +| 变量名 | 默认值 | 可选值 | 说明 | +|--------|-------------------------|--------|--------------------------------------| +| `ENABLE_CORS` | `false` | `true`, `false` | 启用CORS | +| `CORS_ORIGIN` | `*` | 任何有效来源 | CORS来源配置 | +| `DEFAULT_SEARCH_ENGINE` | `bing` | `bing`, `duckduckgo`, `exa`, `brave`, `baidu`, `csdn`, `juejin`, `linuxdo` | 默认搜索引擎 | +| `USE_PROXY` | `false` | `true`, `false` | 启用HTTP代理 | +| `PROXY_URL` | `http://127.0.0.1:10809` | 任何有效URL | 代理服务器URL | +| `MODE` | `both` | `both`, `http`, `stdio` | 服务器模式:同时支持HTTP+STDIO、仅HTTP或仅STDIO | +| `PORT` | `3000` | 1-65535 | 服务器端口 | +| `ALLOWED_SEARCH_ENGINES` | 空(全部可用) | 逗号分隔的引擎名称 | 限制可使用的搜索引擎,如默认搜索引擎不在范围,则默认第一个为默认搜索引擎 | +| `MAX_DESCRIPTION_LENGTH` | 无限制 | 正整数 | 搜索结果描述的全局最大长度,超出部分将被截断 | +| `MCP_TOOL_SEARCH_NAME` | `search` | 有效的MCP工具名称 | 搜索工具的自定义名称 | +| `MCP_TOOL_FETCH_LINUXDO_NAME` | `fetchLinuxDoArticle` | 有效的MCP工具名称 | Linux.do文章获取工具的自定义名称 | +| `MCP_TOOL_FETCH_CSDN_NAME` | `fetchCsdnArticle` | 有效的MCP工具名称 | CSDN文章获取工具的自定义名称 | +| `MCP_TOOL_FETCH_GITHUB_NAME` | `fetchGithubReadme` | 有效的MCP工具名称 | GitHub README获取工具的自定义名称 | +| `MCP_TOOL_FETCH_JUEJIN_NAME` | `fetchJuejinArticle` | 有效的MCP工具名称 | 掘金文章获取工具的自定义名称 | + +**常用配置示例:** ```bash -# Enable proxy for restricted regions +# 启用代理(适用于网络受限地区) USE_PROXY=true PROXY_URL=http://127.0.0.1:7890 npx open-websearch@latest -# Full configuration +# 完整配置 DEFAULT_SEARCH_ENGINE=duckduckgo ENABLE_CORS=true USE_PROXY=true PROXY_URL=http://127.0.0.1:7890 PORT=8080 npx open-websearch@latest ``` -### Local Installation +**Windows 用户注意事项:** +- 在 PowerShell 中使用 `$env:VAR="value"; ` 语法 +- 本地开发推荐使用 `npx cross-env` 实现跨平台兼容 -1. Clone or download this repository -2. Install dependencies: +### 本地安装 + +1. 克隆或下载本仓库 +2. 安装依赖项: ```bash npm install ``` -3. Build the server: +3. 构建服务器: ```bash npm run build ``` -4. Add the server to your MCP configuration: +4. 将服务器添加到您的MCP配置中: **Cherry Studio:** ```json @@ -120,7 +217,7 @@ npm run build } ``` -**VSCode (Claude Dev Extension):** +**VSCode版(Claude开发扩展):** ```json { "mcpServers": { @@ -140,27 +237,23 @@ npm run build } ``` -**Claude Desktop:** +**Claude桌面版:** ```json { "mcpServers": { "web-search": { - "transport": { - "type": "streamableHttp", - "url": "http://localhost:3000/mcp" - } + "type": "http", + "url": "http://localhost:3000/mcp" }, "web-search-sse": { - "transport": { - "type": "sse", - "url": "http://localhost:3000/sse" - } + "type": "sse", + "url": "http://localhost:3000/sse" } } } ``` -**NPX Command Line Configuration:** +**NPX命令行配置示例:** ```json { "mcpServers": { @@ -179,13 +272,13 @@ npm run build } ``` -**Local STDIO Configuration for Cherry Studio (Windows):** +**Cherry Studio 本地 STDIO 配置 (Windows):** ```json { "mcpServers": { "open-websearch-local": { "command": "node", - "args": ["C:/path/to/your/project/build/index.js"], + "args": ["C:/你的项目路径/build/index.js"], "env": { "MODE": "stdio", "DEFAULT_SEARCH_ENGINE": "duckduckgo", @@ -196,31 +289,34 @@ npm run build } ``` -### Docker Deployment +### Docker部署 -Quick deployment using Docker Compose: +使用Docker Compose快速部署: ```bash docker-compose up -d ``` -Or use Docker directly: +或者直接使用Docker: ```bash docker run -d --name web-search -p 3000:3000 -e ENABLE_CORS=true -e CORS_ORIGIN=* ghcr.io/aas-ee/open-web-search:latest ``` -Environment variable configuration: - -| Variable | Default | Options | Description | -|----------|-------------------------|---------|-------------| -| `ENABLE_CORS` | `false` | `true`, `false` | Enable CORS | -| `CORS_ORIGIN` | `*` | Any valid origin | CORS origin configuration | -| `DEFAULT_SEARCH_ENGINE` | `bing` | `bing`, `duckduckgo`, `exa`, `brave` | Default search engine | -| `USE_PROXY` | `false` | `true`, `false` | Enable HTTP proxy | -| `PROXY_URL` | `http://127.0.0.1:7890` | Any valid URL | Proxy server URL | -| `PORT` | `3000` | 1-65535 | Server port | - -Then configure in your MCP client: +配置环境变量说明: + +| 变量名 | 默认值 | 可选值 | 说明 | +|--------|-------------------------|--------|------| +| `ENABLE_CORS` | `false` | `true`, `false` | 启用CORS | +| `CORS_ORIGIN` | `*` | 任何有效来源 | CORS来源配置 | +| `DEFAULT_SEARCH_ENGINE` | `bing` | `bing`, `duckduckgo`, `exa`, `brave`, `baidu`, `csdn`, `juejin`, `linuxdo` | 默认搜索引擎 | +| `USE_PROXY` | `false` | `true`, `false` | 启用HTTP代理 | +| `PROXY_URL` | `http://127.0.0.1:10809` | 任何有效URL | 代理服务器URL | +| `MODE` | `both` | `both`, `http`, `stdio` | 服务器模式 | +| `PORT` | `3000` | 1-65535 | 服务器端口 | +| `ALLOWED_SEARCH_ENGINES` | 空(全部可用) | 逗号分隔的引擎名称 | 限制可使用的搜索引擎 | +| `MAX_DESCRIPTION_LENGTH` | 无限制 | 正整数 | 搜索结果描述最大长度 | + +然后在MCP客户端中配置: ```json { "mcpServers": { @@ -244,57 +340,59 @@ Then configure in your MCP client: } ``` -## Usage Guide +## 使用说明 -The server provides four tools: `search`, `fetchLinuxDoArticle`, `fetchCsdnArticle`, and `fetchGithubReadme`. +服务器提供五个工具:`search`、`fetchCsdnArticle`、`fetchGithubReadme`、`fetchJuejinArticle` 和 `fetchLinuxDoArticle`。 -### search Tool Usage +### search工具使用说明 ```typescript { - "query": string, // Search query - "limit": number, // Optional: Number of results to return (default: 10) - "engines": string[] // Optional: Engines to use (bing,baidu,linuxdo,csdn,duckduckgo,exa,brave,juejin) default bing + "query": string, // 搜索查询词 + "limit": number, // 可选:返回结果数量(默认:10,范围:1-50) + "engines": string[], // 可选:使用的引擎 (bing,baidu,linuxdo,csdn,duckduckgo,exa,brave,juejin) 默认bing,大小写不敏感 + "maxDescriptionLength": number // 可选:单次调用的描述最大长度,优先级高于全局 MAX_DESCRIPTION_LENGTH } ``` -Usage example: +使用示例: ```typescript use_mcp_tool({ server_name: "web-search", tool_name: "search", arguments: { - query: "search content", - limit: 3, // Optional parameter - engines: ["bing", "csdn", "duckduckgo", "exa", "brave", "juejin"] // Optional parameter, supports multi-engine combined search + query: "搜索内容", + limit: 3, // 可选参数 + engines: ["bing", "csdn", "duckduckgo", "exa", "brave", "juejin"] // 可选参数,支持多引擎组合搜索 } }) ``` -Response example: +返回示例: ```json [ { - "title": "Example Search Result", + "title": "示例搜索结果", "url": "https://example.com", - "description": "Description text of the search result...", - "source": "Source", - "engine": "Engine used" + "description": "搜索结果的描述文本...", + "source": "来源", + "engine": "使用的引擎" } ] ``` -### fetchCsdnArticle Tool Usage -Used to fetch complete content of CSDN blog articles. +### fetchCsdnArticle工具使用说明 + +用于获取CSDN博客文章的完整内容。 ```typescript { - "url": string // URL from CSDN search results using the search tool + "url": string // search 工具使用csdn查询出的url } ``` -Usage example: +使用示例: ```typescript use_mcp_tool({ server_name: "web-search", @@ -305,26 +403,26 @@ use_mcp_tool({ }) ``` -Response example: +返回示例: ```json [ { - "content": "Example search result" + "content": "示例搜索结果" } ] ``` -### fetchLinuxDoArticle Tool Usage +### fetchLinuxDoArticle工具使用说明 -Used to fetch complete content of Linux.do forum articles. +用于获取Linux.do论坛文章的完整内容。 ```typescript { - "url": string // URL from linuxdo search results using the search tool + "url": string // search 工具使用linuxdo查询出的url } ``` -Usage example: +使用示例: ```typescript use_mcp_tool({ server_name: "web-search", @@ -335,26 +433,28 @@ use_mcp_tool({ }) ``` -Response example: +返回示例: ```json [ { - "content": "Example search result" + "content": "示例搜索结果" } ] + ``` -### fetchGithubReadme Tool Usage -Used to fetch README content from GitHub repositories. +### fetchGithubReadme工具使用说明 + +用于获取GitHub仓库的README文件内容。 ```typescript { - "url": string // GitHub repository URL (supports HTTPS, SSH formats) + "url": string // GitHub仓库URL(支持HTTPS、SSH格式) } ``` -Usage example: +使用示例: ```typescript use_mcp_tool({ server_name: "web-search", @@ -365,13 +465,13 @@ use_mcp_tool({ }) ``` -Supported URL formats: +支持的URL格式: - HTTPS: `https://github.com/owner/repo` - HTTPS with .git: `https://github.com/owner/repo.git` - SSH: `git@github.com:owner/repo.git` -- URLs with parameters: `https://github.com/owner/repo?tab=readme` +- 带参数的URL: `https://github.com/owner/repo?tab=readme` -Response example: +返回示例: ```json [ { @@ -380,17 +480,18 @@ Response example: ] ``` -### fetchJuejinArticle Tool Usage -Used to fetch complete content of Juejin articles. +### fetchJuejinArticle工具使用说明 + +用于获取掘金文章的完整内容。 ```typescript { - "url": string // Juejin article URL from search results + "url": string // 掘金文章URL } ``` -Usage example: +使用示例: ```typescript use_mcp_tool({ server_name: "web-search", @@ -401,10 +502,10 @@ use_mcp_tool({ }) ``` -Supported URL format: -- `https://juejin.cn/post/{article_id}` +支持的URL格式: +- `https://juejin.cn/post/{文章ID}` -Response example: +返回示例: ```json [ { @@ -413,97 +514,98 @@ Response example: ] ``` -## Usage Limitations -Since this tool works by scraping multi-engine search results, please note the following important limitations: +## 使用限制 + +由于本工具通过爬取多引擎搜索结果实现,请注意以下重要限制: -1. **Rate Limiting**: - - Too many searches in a short time may cause the used engines to temporarily block requests - - Recommendations: - - Maintain reasonable search frequency - - Use the limit parameter judiciously - - Add delays between searches when necessary +1. **频率限制**: + - 短时间内搜索次数过多可能导致使用的引擎暂时屏蔽请求 + - 建议: + - 保持合理的搜索频率 + - 审慎使用limit参数 + - 必要时可在搜索间设置延迟 -2. **Result Accuracy**: - - Depends on the HTML structure of corresponding engines, may fail when engines update - - Some results may lack metadata like descriptions - - Complex search operators may not work as expected +2. **结果准确性**: + - 依赖对应引擎的HTML结构,可能随引擎改版失效 + - 部分结果可能缺失描述等元数据 + - 复杂搜索运算符可能无法按预期工作 -3. **Legal Terms**: - - This tool is for personal use only - - Please comply with the terms of service of corresponding engines - - Implement appropriate rate limiting based on your actual use case +3. **法律条款**: + - 本工具仅限个人使用 + - 请遵守对应引擎的服务条款 + - 建议根据实际使用场景实施适当的频率限制 -4. **Search Engine Configuration**: - - Default search engine can be set via the `DEFAULT_SEARCH_ENGINE` environment variable - - Supported engines: bing, duckduckgo, exa, brave - - The default engine is used when searching specific websites +4. **搜索引擎配置**: + - 可通过环境变量`DEFAULT_SEARCH_ENGINE`设置默认搜索引擎 + - 支持的引擎有:bing, duckduckgo, exa, brave + - 当搜索特定网站内容时,会自动使用默认搜索引擎 -5. **Proxy Configuration**: - - HTTP proxy can be configured when certain search engines are unavailable in specific regions - - Enable proxy with environment variable `USE_PROXY=true` - - Configure proxy server address with `PROXY_URL` +5. **代理服务配置**: + - 当某些搜索引擎在特定地区不可用时,可配置HTTP代理 + - 通过环境变量`USE_PROXY=true`启用代理 + - 使用`PROXY_URL`配置代理服务器地址 -## Contributing +## 贡献指南 -Welcome to submit issue reports and feature improvement suggestions! +欢迎提交问题报告和功能改进建议! -### Contributor Guide +### 贡献者指南 -If you want to fork this repository and publish your own Docker image, you need to make the following configurations: +如果您想要fork本仓库并发布自己的Docker镜像,需要进行以下配置: -#### GitHub Secrets Configuration +#### GitHub Secrets配置 -To enable automatic Docker image building and publishing, please add the following secrets in your GitHub repository settings (Settings → Secrets and variables → Actions): +要启用自动Docker镜像构建和发布功能,请在您的GitHub仓库设置中添加以下secrets(Settings → Secrets and variables → Actions): -**Required Secrets:** -- `GITHUB_TOKEN`: Automatically provided by GitHub (no setup needed) +**必需的Secrets:** +- `GITHUB_TOKEN`: GitHub自动提供(无需设置) -**Optional Secrets (for Alibaba Cloud ACR):** -- `ACR_REGISTRY`: Your Alibaba Cloud Container Registry URL (e.g., `registry.cn-hangzhou.aliyuncs.com`) -- `ACR_USERNAME`: Your Alibaba Cloud ACR username -- `ACR_PASSWORD`: Your Alibaba Cloud ACR password -- `ACR_IMAGE_NAME`: Your image name in ACR (e.g., `your-namespace/open-web-search`) +**可选的Secrets(用于阿里云ACR):** +- `ACR_REGISTRY`: 您的阿里云容器镜像服务URL(例如:`registry.cn-hangzhou.aliyuncs.com`) +- `ACR_USERNAME`: 您的阿里云ACR用户名 +- `ACR_PASSWORD`: 您的阿里云ACR密码 +- `ACR_IMAGE_NAME`: 您在ACR中的镜像名称(例如:`your-namespace/open-web-search`) -#### CI/CD Workflow +#### CI/CD工作流程 -The repository includes a GitHub Actions workflow (`.github/workflows/docker.yml`) that automatically: +仓库包含一个GitHub Actions工作流程(`.github/workflows/docker.yml`),会自动: -1. **Trigger Conditions**: - - Push to `main` branch - - Push version tags (`v*`) - - Manual workflow trigger +1. **触发条件**: + - 推送到`main`分支 + - 推送版本标签(`v*`) + - 手动触发workflow -2. **Build and Push to**: - - GitHub Container Registry (ghcr.io) - always enabled - - Alibaba Cloud Container Registry - only enabled when ACR secrets are configured +2. **构建并推送到**: + - GitHub Container Registry (ghcr.io) - 始终启用 + - 阿里云容器镜像服务 - 仅在配置ACR secrets时启用 -3. **Image Tags**: - - `ghcr.io/your-username/open-web-search:latest` - - `your-acr-address/your-image-name:latest` (if ACR is configured) +3. **镜像标签**: + - `ghcr.io/您的用户名/open-web-search:latest` + - `您的ACR地址/您的镜像名:latest`(如果配置了ACR) -#### Fork and Publish Steps: +#### Fork和发布步骤: -1. **Fork the repository** to your GitHub account -2. **Configure secrets** (if you need ACR publishing): - - Go to Settings → Secrets and variables → Actions in your forked repository - - Add the ACR-related secrets listed above -3. **Push changes** to the `main` branch or create version tags -4. **GitHub Actions will automatically build and push** your Docker image -5. **Use your image**, update the Docker command: +1. **Fork仓库**到您的GitHub账户 +2. **配置secrets**(如果需要ACR发布): + - 进入您fork的仓库的Settings → Secrets and variables → Actions + - 添加上面列出的ACR相关secrets +3. **推送更改**到`main`分支或创建版本标签 +4. **GitHub Actions将自动构建并推送**您的Docker镜像 +5. **使用您的镜像**,更新Docker命令: ```bash - docker run -d --name web-search -p 3000:3000 -e ENABLE_CORS=true -e CORS_ORIGIN=* ghcr.io/your-username/open-web-search:latest + docker run -d --name web-search -p 3000:3000 -e ENABLE_CORS=true -e CORS_ORIGIN=* ghcr.io/您的用户名/open-web-search:latest ``` -#### Notes: -- If you don't configure ACR secrets, the workflow will only publish to GitHub Container Registry -- Make sure your GitHub repository has Actions enabled -- The workflow will use your GitHub username (converted to lowercase) as the GHCR image name +#### 注意事项: +- 如果您不配置ACR secrets,工作流程将只发布到GitHub Container Registry +- 确保您的GitHub仓库已启用Actions功能 +- 工作流程会使用您的GitHub用户名(转换为小写)作为GHCR镜像名称
## Star History -If you find this project helpful, please consider giving it a ⭐ Star! +如果项目对你有帮助,请考虑给个⭐ Star! [![Star History Chart](https://api.star-history.com/svg?repos=Aas-ee/open-webSearch&type=Date)](https://www.star-history.com/#Aas-ee/open-webSearch&Date) diff --git a/package-lock.json b/package-lock.json index edb057c..57d8a9d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,52 +1,93 @@ { - "name": "web-search", + "name": "open-websearch", "version": "1.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "web-search", + "name": "open-websearch", "version": "1.2.0", "dependencies": { - "@modelcontextprotocol/sdk": "^1.11.2", + "@modelcontextprotocol/sdk": "^1.27.1", "@types/axios": "^0.14.4", - "@types/cheerio": "^0.22.35", - "axios": "^1.7.9", - "cheerio": "^1.0.0", - "cors": "^2.8.5", - "express": "^4.18.2", + "@types/cheerio": "^1.0.0", + "axios": "^1.13.5", + "cheerio": "^1.2.0", + "cors": "^2.8.6", + "express": "^5.2.1", "https-proxy-agent": "^7.0.6", - "jsdom": "^26.1.0", - "npx": "^10.2.2" + "jsdom": "^28.1.0", + "puppeteer-core": "^24.37.5", + "zod": "^4.3.6" }, "bin": { - "web-search": "build/index.js" + "open-websearch": "build/index.js" }, "devDependencies": { "@types/cors": "^2.8.19", - "@types/express": "^4.17.21", - "@types/jsdom": "^21.1.7", - "@types/node": "^20.17.10", - "typescript": "^5.3.3" + "@types/express": "^5.0.6", + "@types/jsdom": "^28.0.0", + "@types/node": "^25.3.1", + "typescript": "^5.9.3" } }, + "node_modules/@acemir/cssom": { + "version": "0.9.31", + "resolved": "https://registry.npmjs.org/@acemir/cssom/-/cssom-0.9.31.tgz", + "integrity": "sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==", + "license": "MIT" + }, "node_modules/@asamuzakjp/css-color": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", - "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.0.1.tgz", + "integrity": "sha512-2SZFvqMyvboVV1d15lMf7XiI3m7SDqXUuKaTymJYLN6dSGadqp+fVojqJlVoMlbZnlTmu3S0TLwLTJpvBMO1Aw==", + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^3.1.1", + "@csstools/css-color-parser": "^4.0.2", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0", + "lru-cache": "^11.2.6" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.8.1.tgz", + "integrity": "sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==", + "license": "MIT", + "dependencies": { + "@asamuzakjp/nwsapi": "^2.3.9", + "bidi-js": "^1.0.3", + "css-tree": "^3.1.0", + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.2.6" + } + }, + "node_modules/@asamuzakjp/nwsapi": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", + "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", + "license": "MIT" + }, + "node_modules/@bramus/specificity": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.2.tgz", + "integrity": "sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==", "license": "MIT", "dependencies": { - "@csstools/css-calc": "^2.1.3", - "@csstools/css-color-parser": "^3.0.9", - "@csstools/css-parser-algorithms": "^3.0.4", - "@csstools/css-tokenizer": "^3.0.3", - "lru-cache": "^10.4.3" + "css-tree": "^3.0.0" + }, + "bin": { + "specificity": "bin/cli.js" } }, "node_modules/@csstools/color-helpers": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz", - "integrity": "sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.0.2.tgz", + "integrity": "sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==", "funding": [ { "type": "github", @@ -59,13 +100,13 @@ ], "license": "MIT-0", "engines": { - "node": ">=18" + "node": ">=20.19.0" } }, "node_modules/@csstools/css-calc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", - "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.1.1.tgz", + "integrity": "sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ==", "funding": [ { "type": "github", @@ -78,17 +119,17 @@ ], "license": "MIT", "engines": { - "node": ">=18" + "node": ">=20.19.0" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" } }, "node_modules/@csstools/css-color-parser": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.10.tgz", - "integrity": "sha512-TiJ5Ajr6WRd1r8HSiwJvZBiJOqtH86aHpUjq5aEKWHiII2Qfjqd/HCWKPOW8EP4vcspXbHnXrwIDlu5savQipg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.0.2.tgz", + "integrity": "sha512-0GEfbBLmTFf0dJlpsNU7zwxRIH0/BGEMuXLTCvFYxuL1tNhqzTbtnFICyJLTNK4a+RechKP75e7w42ClXSnJQw==", "funding": [ { "type": "github", @@ -101,21 +142,21 @@ ], "license": "MIT", "dependencies": { - "@csstools/color-helpers": "^5.0.2", - "@csstools/css-calc": "^2.1.4" + "@csstools/color-helpers": "^6.0.2", + "@csstools/css-calc": "^3.1.1" }, "engines": { - "node": ">=18" + "node": ">=20.19.0" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" } }, "node_modules/@csstools/css-parser-algorithms": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", - "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz", + "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==", "funding": [ { "type": "github", @@ -127,17 +168,18 @@ } ], "license": "MIT", + "peer": true, "engines": { - "node": ">=18" + "node": ">=20.19.0" }, "peerDependencies": { - "@csstools/css-tokenizer": "^3.0.4" + "@csstools/css-tokenizer": "^4.0.0" } }, - "node_modules/@csstools/css-tokenizer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", - "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.28.tgz", + "integrity": "sha512-1NRf1CUBjnr3K7hu8BLxjQrKCxEe8FP/xmPTenAxCRZWVLbmGotkFvG9mfNpjA6k7Bw1bw4BilZq9cu19RA5pg==", "funding": [ { "type": "github", @@ -148,271 +190,132 @@ "url": "https://opencollective.com/csstools" } ], - "license": "MIT", - "engines": { - "node": ">=18" - } + "license": "MIT-0" }, - "node_modules/@modelcontextprotocol/sdk": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.13.2.tgz", - "integrity": "sha512-Vx7qOcmoKkR3qhaQ9qf3GxiVKCEu+zfJddHv6x3dY/9P6+uIwJnmuAur5aB+4FDXf41rRrDnOEGkviX5oYZ67w==", + "node_modules/@csstools/css-tokenizer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz", + "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "license": "MIT", - "dependencies": { - "ajv": "^6.12.6", - "content-type": "^1.0.5", - "cors": "^2.8.5", - "cross-spawn": "^7.0.5", - "eventsource": "^3.0.2", - "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" - }, + "peer": true, "engines": { - "node": ">=18" + "node": ">=20.19.0" } }, - "node_modules/@modelcontextprotocol/sdk/node_modules/accepts": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", - "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "node_modules/@exodus/bytes": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.14.1.tgz", + "integrity": "sha512-OhkBFWI6GcRMUroChZiopRiSp2iAMvEBK47NhJooDqz1RERO4QuZIZnjP63TXX8GAiLABkYmX+fuQsdJ1dd2QQ==", "license": "MIT", - "dependencies": { - "mime-types": "^3.0.0", - "negotiator": "^1.0.0" - }, "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/body-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", - "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", - "license": "MIT", - "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" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/content-disposition": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", - "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" + "peerDependencies": { + "@noble/hashes": "^1.8.0 || ^2.0.0" }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/cookie-signature": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", - "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", - "license": "MIT", - "engines": { - "node": ">=6.6.0" + "peerDependenciesMeta": { + "@noble/hashes": { + "optional": true + } } }, - "node_modules/@modelcontextprotocol/sdk/node_modules/express": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", - "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", + "node_modules/@hono/node-server": { + "version": "1.19.9", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.9.tgz", + "integrity": "sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==", "license": "MIT", - "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" - }, "engines": { - "node": ">= 18" + "node": ">=18.14.1" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "peerDependencies": { + "hono": "^4" } }, - "node_modules/@modelcontextprotocol/sdk/node_modules/finalhandler": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", - "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.27.1", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.27.1.tgz", + "integrity": "sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA==", "license": "MIT", "dependencies": { - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "on-finished": "^2.4.1", - "parseurl": "^1.3.3", - "statuses": "^2.0.1" + "@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" }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", - "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/media-typer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/merge-descriptors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", - "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", - "license": "MIT", "engines": { "node": ">=18" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", - "license": "MIT", - "dependencies": { - "mime-db": "^1.54.0" + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" + "peerDependenciesMeta": { + "@cfworker/json-schema": { + "optional": true + }, + "zod": { + "optional": false + } } }, - "node_modules/@modelcontextprotocol/sdk/node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/@modelcontextprotocol/sdk/node_modules/zod-to-json-schema": { + "version": "3.25.1", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", + "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.25 || ^4" } }, - "node_modules/@modelcontextprotocol/sdk/node_modules/send": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", - "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", - "license": "MIT", + "node_modules/@puppeteer/browsers": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.13.0.tgz", + "integrity": "sha512-46BZJYJjc/WwmKjsvDFykHtXrtomsCIrwYQPOP7VfMJoZY2bsDF9oROBABR3paDjDcmkUye1Pb1BqdcdiipaWA==", + "license": "Apache-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" + "debug": "^4.4.3", + "extract-zip": "^2.0.1", + "progress": "^2.0.3", + "proxy-agent": "^6.5.0", + "semver": "^7.7.4", + "tar-fs": "^3.1.1", + "yargs": "^17.7.2" }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/@modelcontextprotocol/sdk/node_modules/serve-static": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", - "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", - "license": "MIT", - "dependencies": { - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "parseurl": "^1.3.3", - "send": "^1.2.0" + "bin": { + "browsers": "lib/cjs/main-cli.js" }, "engines": { - "node": ">= 18" + "node": ">=18" } }, - "node_modules/@modelcontextprotocol/sdk/node_modules/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", - "license": "MIT", - "dependencies": { - "content-type": "^1.0.5", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" - }, - "engines": { - "node": ">= 0.6" - } + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "license": "MIT" }, "node_modules/@types/axios": { "version": "0.14.4", @@ -435,11 +338,13 @@ } }, "node_modules/@types/cheerio": { - "version": "0.22.35", - "resolved": "https://registry.npmjs.org/@types/cheerio/-/cheerio-0.22.35.tgz", - "integrity": "sha512-yD57BchKRvTV+JD53UZ6PD8KWY5g5rvvMLRnZR3EQBCZXiDT/HR+pKpMzFGlWNhFrXlo7VPZXtKvIEwZkAWOIA==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/cheerio/-/cheerio-1.0.0.tgz", + "integrity": "sha512-zAaImHWoh5RY2CLgU2mvg3bl2k3F65B0N5yphuII3ythFLPmJhL7sj1RDu6gSxcgqHlETbr/lhA2OBY+WF1fXQ==", + "deprecated": "This is a stub types definition. cheerio provides its own type definitions, so you do not need this installed.", + "license": "MIT", "dependencies": { - "@types/node": "*" + "cheerio": "*" } }, "node_modules/@types/connect": { @@ -463,22 +368,21 @@ } }, "node_modules/@types/express": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz", - "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.6.tgz", + "integrity": "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==", "dev": true, "license": "MIT", "dependencies": { "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" + "@types/express-serve-static-core": "^5.0.0", + "@types/serve-static": "^2" } }, "node_modules/@types/express-serve-static-core": { - "version": "4.19.6", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", - "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.1.tgz", + "integrity": "sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A==", "dev": true, "license": "MIT", "dependencies": { @@ -496,32 +400,35 @@ "license": "MIT" }, "node_modules/@types/jsdom": { - "version": "21.1.7", - "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.7.tgz", - "integrity": "sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==", + "version": "28.0.0", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-28.0.0.tgz", + "integrity": "sha512-A8TBQQC/xAOojy9kM8E46cqT00sF0h7dWjV8t8BJhUi2rG6JRh7XXQo/oLoENuZIQEpXsxLccLCnknyQd7qssQ==", "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", "@types/tough-cookie": "*", - "parse5": "^7.0.0" + "parse5": "^7.0.0", + "undici-types": "^7.21.0" } }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/node": { - "version": "20.17.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.10.tgz", - "integrity": "sha512-/jrvh5h6NXhEauFFexRin69nA0uHJ5gwk4iDivp/DeoEua3uwCUto6PC86IpRITBOs4+6i2I56K5x5b6WYGXHA==", + "version": "25.3.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.1.tgz", + "integrity": "sha512-hj9YIJimBCipHVfHKRMnvmHg+wfhKc0o4mTtXh9pKBjC8TLJzz0nzGmLi5UJsYAUgSvXFHgb0V2oY10DUFtImw==", + "devOptional": true, + "license": "MIT", "dependencies": { - "undici-types": "~6.19.2" + "undici-types": "~7.18.0" } }, + "node_modules/@types/node/node_modules/undici-types": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "devOptional": true, + "license": "MIT" + }, "node_modules/@types/qs": { "version": "6.14.0", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", @@ -537,26 +444,24 @@ "license": "MIT" }, "node_modules/@types/send": { - "version": "0.17.5", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", - "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", + "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", "dev": true, "license": "MIT", "dependencies": { - "@types/mime": "^1", "@types/node": "*" } }, "node_modules/@types/serve-static": { - "version": "1.15.8", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", - "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-2.2.0.tgz", + "integrity": "sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==", "dev": true, "license": "MIT", "dependencies": { "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" + "@types/node": "*" } }, "node_modules/@types/tough-cookie": { @@ -566,19 +471,54 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", "license": "MIT", "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" }, "engines": { "node": ">= 0.6" } }, + "node_modules/accepts/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/agent-base": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", @@ -589,106 +529,253 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "license": "MIT" + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" }, "node_modules/axios": { - "version": "1.7.9", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", - "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", + "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", + "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } }, - "node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "license": "MIT", + "node_modules/b4a": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.0.tgz", + "integrity": "sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==", + "license": "Apache-2.0", + "peerDependencies": { + "react-native-b4a": "*" + }, + "peerDependenciesMeta": { + "react-native-b4a": { + "optional": true + } + } + }, + "node_modules/bare-events": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", + "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", + "license": "Apache-2.0", + "peerDependencies": { + "bare-abort-controller": "*" + }, + "peerDependenciesMeta": { + "bare-abort-controller": { + "optional": true + } + } + }, + "node_modules/bare-fs": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.5.4.tgz", + "integrity": "sha512-POK4oplfA7P7gqvetNmCs4CNtm9fNsx+IAh7jH7GgU0OJdge2rso0R20TNWVq6VoWcCvsTdlNDaleLHGaKx8CA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-events": "^2.5.4", + "bare-path": "^3.0.0", + "bare-stream": "^2.6.4", + "bare-url": "^2.2.2", + "fast-fifo": "^1.3.2" + }, + "engines": { + "bare": ">=1.16.0" + }, + "peerDependencies": { + "bare-buffer": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + } + } + }, + "node_modules/bare-os": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.2.tgz", + "integrity": "sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "bare": ">=1.14.0" + } + }, + "node_modules/bare-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", + "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-os": "^3.0.1" + } + }, + "node_modules/bare-stream": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.8.0.tgz", + "integrity": "sha512-reUN0M2sHRqCdG4lUK3Fw8w98eeUIZHL5c3H7Mbhk2yVBL+oofgaIp0ieLfD5QXwPCypBpmEEKU2WZKzbAk8GA==", + "license": "Apache-2.0", + "optional": true, "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" + "streamx": "^2.21.0", + "teex": "^1.0.1" + }, + "peerDependencies": { + "bare-buffer": "*", + "bare-events": "*" }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + }, + "bare-events": { + "optional": true + } + } + }, + "node_modules/bare-url": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.3.2.tgz", + "integrity": "sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-path": "^3.0.0" + } + }, + "node_modules/basic-ftp": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.2.0.tgz", + "integrity": "sha512-VoMINM2rqJwJgfdHq6RiUudKt2BV+FY5ZFezP/ypmwayk68+NzzAQy4XXLlqsGD4MCzq3DrmNFD/uUmBJuGoXw==", + "license": "MIT", "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": ">=10.0.0" } }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", "license": "MIT", "dependencies": { - "ms": "2.0.0" + "require-from-string": "^2.0.2" } }, - "node_modules/body-parser/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/body-parser": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "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" }, "engines": { - "node": ">=0.10.0" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/body-parser/node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", "license": "MIT", "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/boolbase": { @@ -696,6 +783,15 @@ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -734,24 +830,25 @@ } }, "node_modules/cheerio": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", - "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", + "integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==", + "license": "MIT", "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "encoding-sniffer": "^0.2.0", - "htmlparser2": "^9.1.0", - "parse5": "^7.1.2", - "parse5-htmlparser2-tree-adapter": "^7.0.0", + "domutils": "^3.2.2", + "encoding-sniffer": "^0.2.1", + "htmlparser2": "^10.1.0", + "parse5": "^7.3.0", + "parse5-htmlparser2-tree-adapter": "^7.1.0", "parse5-parser-stream": "^7.1.2", - "undici": "^6.19.5", + "undici": "^7.19.0", "whatwg-mimetype": "^4.0.0" }, "engines": { - "node": ">=18.17" + "node": ">=20.18.1" }, "funding": { "url": "https://github.com/cheeriojs/cheerio?sponsor=1" @@ -773,10 +870,89 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/cheerio/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/chromium-bidi": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-14.0.0.tgz", + "integrity": "sha512-9gYlLtS6tStdRWzrtXaTMnqcM4dudNegMXJxkR0I/CXObHalYeYcAMPrL19eroNZHtJ8DQmu1E+ZNOYu/IXMXw==", + "license": "Apache-2.0", + "dependencies": { + "mitt": "^3.0.1", + "zod": "^3.24.1" + }, + "peerDependencies": { + "devtools-protocol": "*" + } + }, + "node_modules/chromium-bidi/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -785,15 +961,16 @@ } }, "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", + "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/content-type": { @@ -814,15 +991,18 @@ } }, "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "license": "MIT" + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } }, "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", "license": "MIT", "dependencies": { "object-assign": "^4", @@ -830,6 +1010,10 @@ }, "engines": { "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/cross-spawn": { @@ -861,6 +1045,19 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/css-tree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.12.2", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, "node_modules/css-what": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", @@ -873,35 +1070,55 @@ } }, "node_modules/cssstyle": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.5.0.tgz", - "integrity": "sha512-/7gw8TGrvH/0g564EnhgFZogTMVe+lifpB7LWU+PEsiq5o83TUXR3fDbzTRXOJhoJwck5IS9ez3Em5LNMMO2aw==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-6.1.0.tgz", + "integrity": "sha512-Ml4fP2UT2K3CUBQnVlbdV/8aFDdlY69E+YnwJM+3VUWl08S3J8c8aRuJqCkD9Py8DHZ7zNNvsfKl8psocHZEFg==", "license": "MIT", "dependencies": { - "@asamuzakjp/css-color": "^3.2.0", - "rrweb-cssom": "^0.8.0" + "@asamuzakjp/css-color": "^5.0.0", + "@csstools/css-syntax-patches-for-csstree": "^1.0.28", + "css-tree": "^3.1.0", + "lru-cache": "^11.2.6" }, "engines": { - "node": ">=18" + "node": ">=20" } }, - "node_modules/data-urls": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", - "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", "license": "MIT", - "dependencies": { - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0" - }, "engines": { - "node": ">=18" + "node": ">= 14" + } + }, + "node_modules/data-urls": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-7.0.0.tgz", + "integrity": "sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==", + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/data-urls/node_modules/whatwg-mimetype": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", + "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", + "license": "MIT", + "engines": { + "node": ">=20" } }, "node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -916,15 +1133,30 @@ } }, "node_modules/decimal.js": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz", - "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==", + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", "license": "MIT" }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "license": "MIT", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -937,15 +1169,12 @@ "node": ">= 0.8" } }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "license": "MIT", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } + "node_modules/devtools-protocol": { + "version": "0.0.1566079", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1566079.tgz", + "integrity": "sha512-MJfAEA1UfVhSs7fbSQOG4czavUp1ajfg6prlAN0+cmfa2zNjaIbvq8VneP7do1WAQQIvgNJWSMeP6UyI90gIlQ==", + "license": "BSD-3-Clause", + "peer": true }, "node_modules/dom-serializer": { "version": "2.0.0", @@ -986,9 +1215,10 @@ } }, "node_modules/domutils": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.1.tgz", - "integrity": "sha512-xWXmuRnN9OMP6ptPd2+H0cCbcYBULa5YDTbMm/2lvkWvNA3O4wcW+GvzooqBuNM8yy6pl3VIAeJTUUWUbfI5Fw==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", @@ -1018,6 +1248,12 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "license": "MIT" }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, "node_modules/encodeurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", @@ -1028,9 +1264,10 @@ } }, "node_modules/encoding-sniffer": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz", - "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", + "license": "MIT", "dependencies": { "iconv-lite": "^0.6.3", "whatwg-encoding": "^3.1.1" @@ -1039,6 +1276,15 @@ "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" } }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -1080,12 +1326,88 @@ "node": ">= 0.4" } }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "license": "MIT" }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -1095,6 +1417,15 @@ "node": ">= 0.6" } }, + "node_modules/events-universal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", + "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", + "license": "Apache-2.0", + "dependencies": { + "bare-events": "^2.7.0" + } + }, "node_modules/eventsource": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", @@ -1117,45 +1448,43 @@ } }, "node_modules/express": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", - "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", - "license": "MIT", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.7.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.12", - "proxy-addr": "~2.0.7", - "qs": "6.13.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "license": "MIT", + "peer": true, + "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" + }, + "engines": { + "node": ">= 18" }, "funding": { "type": "opencollective", @@ -1163,10 +1492,13 @@ } }, "node_modules/express-rate-limit": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz", - "integrity": "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.2.1.tgz", + "integrity": "sha512-PCZEIEIxqwhzw4KF0n7QF4QqruVTcF73O5kFKUnGOyjbCCgizBBiFaYpd/fnBLUMPw/BWw9OsiN7GgrNYr7j6g==", "license": "MIT", + "dependencies": { + "ip-address": "10.0.1" + }, "engines": { "node": ">= 16" }, @@ -1177,20 +1509,59 @@ "express": ">= 4.11" } }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/express-rate-limit/node_modules/ip-address": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz", + "integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/express/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "license": "MIT", "dependencies": { - "ms": "2.0.0" + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "license": "BSD-2-Clause", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -1198,55 +1569,69 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "license": "MIT" }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", "license": "MIT" }, - "node_modules/finalhandler": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "license": "MIT", "dependencies": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" + "pend": "~1.2.0" } }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", "license": "MIT", "dependencies": { - "ms": "2.0.0" + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -1257,12 +1642,15 @@ } }, "node_modules/form-data": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", - "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "engines": { @@ -1279,12 +1667,12 @@ } }, "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, "node_modules/function-bind": { @@ -1296,6 +1684,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -1333,6 +1730,35 @@ "node": ">= 0.4" } }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-uri": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", + "license": "MIT", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -1357,6 +1783,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -1369,22 +1810,32 @@ "node": ">= 0.4" } }, + "node_modules/hono": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.2.tgz", + "integrity": "sha512-gJnaDHXKDayjt8ue0n8Gs0A007yKXj4Xzb8+cNjZeYsSzzwKc0Lr+OZgYwVfB0pHfUs17EPoLvrOsEaJ9mj+Tg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=16.9.0" + } + }, "node_modules/html-encoding-sniffer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", - "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz", + "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==", "license": "MIT", "dependencies": { - "whatwg-encoding": "^3.1.1" + "@exodus/bytes": "^1.6.0" }, "engines": { - "node": ">=18" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" } }, "node_modules/htmlparser2": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", - "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { @@ -1392,26 +1843,44 @@ "url": "https://github.com/sponsors/fb55" } ], + "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "entities": "^4.5.0" + "domutils": "^3.2.2", + "entities": "^7.0.1" } }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, "engines": { "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/http-proxy-agent": { @@ -1444,6 +1913,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -1456,4716 +1926,239 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "license": "MIT" - }, - "node_modules/is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, - "node_modules/jsdom": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz", - "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", - "license": "MIT", - "dependencies": { - "cssstyle": "^4.2.1", - "data-urls": "^5.0.0", - "decimal.js": "^10.5.0", - "html-encoding-sniffer": "^4.0.0", - "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.6", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.16", - "parse5": "^7.2.1", - "rrweb-cssom": "^0.8.0", - "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^5.1.1", - "w3c-xmlserializer": "^5.0.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^3.1.1", - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.1.1", - "ws": "^8.18.0", - "xml-name-validator": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "canvas": "^3.0.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" - }, - "node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "license": "ISC" - }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/npx": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/npx/-/npx-10.2.2.tgz", - "integrity": "sha512-eImmySusyeWphzs5iNh791XbZnZG0FSNvM4KSah34pdQQIDsdTDhIwg1sjN3AIVcjGLpbQ/YcfqHPshKZQK1fA==", - "bundleDependencies": [ - "npm", - "libnpx" - ], - "deprecated": "This package is now part of the npm CLI.", - "license": "ISC", - "dependencies": { - "libnpx": "10.2.2", - "npm": "5.1.0" - }, - "bin": { - "npx": "index.js" - } - }, - "node_modules/npx/node_modules/ansi-align": { - "version": "2.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "string-width": "^2.0.0" - } - }, - "node_modules/npx/node_modules/ansi-regex": { - "version": "3.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/ansi-styles": { - "version": "3.2.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/balanced-match": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/boxen": { - "version": "1.3.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-align": "^2.0.0", - "camelcase": "^4.0.0", - "chalk": "^2.0.1", - "cli-boxes": "^1.0.0", - "string-width": "^2.0.0", - "term-size": "^1.2.0", - "widest-line": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/brace-expansion": { - "version": "1.1.11", - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/npx/node_modules/builtins": { - "version": "1.0.3", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/camelcase": { - "version": "4.1.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/capture-stack-trace": { - "version": "1.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/chalk": { - "version": "2.4.2", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/ci-info": { - "version": "1.6.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/cli-boxes": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/cliui": { - "version": "4.1.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } - }, - "node_modules/npx/node_modules/code-point-at": { - "version": "1.1.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/color-convert": { - "version": "1.9.3", - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/npx/node_modules/color-name": { - "version": "1.1.3", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/concat-map": { - "version": "0.0.1", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/configstore": { - "version": "3.1.2", - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "dot-prop": "^4.1.0", - "graceful-fs": "^4.1.2", - "make-dir": "^1.0.0", - "unique-string": "^1.0.0", - "write-file-atomic": "^2.0.0", - "xdg-basedir": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/create-error-class": { - "version": "3.0.2", - "inBundle": true, - "license": "MIT", - "dependencies": { - "capture-stack-trace": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/cross-spawn": { - "version": "5.1.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "node_modules/npx/node_modules/crypto-random-string": { - "version": "1.0.0", - "inBundle": true, + "node_modules/ip-address": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", "license": "MIT", "engines": { - "node": ">=4" + "node": ">= 12" } }, - "node_modules/npx/node_modules/decamelize": { - "version": "1.2.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/deep-extend": { - "version": "0.6.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/npx/node_modules/dot-prop": { - "version": "4.2.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "is-obj": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/dotenv": { - "version": "5.0.1", - "inBundle": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.6.0" - } - }, - "node_modules/npx/node_modules/duplexer3": { - "version": "0.1.4", - "inBundle": true, - "license": "BSD-3-Clause" - }, - "node_modules/npx/node_modules/end-of-stream": { - "version": "1.4.4", - "inBundle": true, - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/npx/node_modules/escape-string-regexp": { - "version": "1.0.5", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/npx/node_modules/execa": { - "version": "0.7.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/find-up": { - "version": "2.1.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/fs.realpath": { - "version": "1.0.0", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/get-caller-file": { - "version": "1.0.3", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/get-stream": { - "version": "3.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/glob": { - "version": "7.1.6", - "inBundle": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npx/node_modules/global-dirs": { - "version": "0.1.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ini": "^1.3.4" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/got": { - "version": "6.7.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "create-error-class": "^3.0.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-redirect": "^1.0.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "lowercase-keys": "^1.0.0", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "unzip-response": "^2.0.1", - "url-parse-lax": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/graceful-fs": { - "version": "4.2.3", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/has-flag": { - "version": "3.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/hosted-git-info": { - "version": "2.8.5", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/import-lazy": { - "version": "2.1.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/imurmurhash": { - "version": "0.1.4", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/npx/node_modules/inflight": { - "version": "1.0.6", - "inBundle": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/npx/node_modules/inherits": { - "version": "2.0.4", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/ini": { - "version": "1.3.5", - "inBundle": true, - "license": "ISC", - "engines": { - "node": "*" - } - }, - "node_modules/npx/node_modules/invert-kv": { - "version": "2.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/is-ci": { - "version": "1.2.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ci-info": "^1.5.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/npx/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/is-installed-globally": { - "version": "0.1.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "global-dirs": "^0.1.0", - "is-path-inside": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/is-npm": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/is-obj": { - "version": "1.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/is-path-inside": { - "version": "1.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "path-is-inside": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/is-redirect": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/is-retry-allowed": { - "version": "1.2.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/is-stream": { - "version": "1.1.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/isexe": { - "version": "2.0.0", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/latest-version": { - "version": "3.1.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "package-json": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/lcid": { - "version": "2.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "invert-kv": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/npx/node_modules/libnpx": { - "version": "10.2.2", - "inBundle": true, - "license": "ISC", - "dependencies": { - "dotenv": "^5.0.1", - "npm-package-arg": "^6.0.0", - "rimraf": "^2.6.2", - "safe-buffer": "^5.1.0", - "update-notifier": "^2.3.0", - "which": "^1.3.0", - "y18n": "^4.0.0", - "yargs": "^11.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/locate-path": { - "version": "2.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/lowercase-keys": { - "version": "1.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/lru-cache": { - "version": "4.1.5", - "inBundle": true, - "license": "ISC", - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/npx/node_modules/make-dir": { - "version": "1.3.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/map-age-cleaner": { - "version": "0.1.3", - "inBundle": true, - "license": "MIT", - "dependencies": { - "p-defer": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/npx/node_modules/mem": { - "version": "4.3.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/npx/node_modules/mimic-fn": { - "version": "2.1.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/npx/node_modules/minimatch": { - "version": "3.0.4", - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/npx/node_modules/minimist": { - "version": "1.2.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/nice-try": { - "version": "1.0.5", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm": { - "version": "5.1.0", - "bundleDependencies": [ - "abbrev", - "ansi-regex", - "ansicolors", - "ansistyles", - "aproba", - "archy", - "cacache", - "call-limit", - "bluebird", - "chownr", - "cmd-shim", - "columnify", - "config-chain", - "debuglog", - "detect-indent", - "dezalgo", - "editor", - "fs-vacuum", - "fs-write-stream-atomic", - "fstream", - "fstream-npm", - "glob", - "graceful-fs", - "has-unicode", - "hosted-git-info", - "iferr", - "imurmurhash", - "inflight", - "inherits", - "ini", - "init-package-json", - "JSONStream", - "lazy-property", - "lockfile", - "lodash._baseindexof", - "lodash._baseuniq", - "lodash._bindcallback", - "lodash._cacheindexof", - "lodash._createcache", - "lodash._getnative", - "lodash.clonedeep", - "lodash.restparam", - "lodash.union", - "lodash.uniq", - "lodash.without", - "lru-cache", - "mkdirp", - "mississippi", - "move-concurrently", - "node-gyp", - "nopt", - "normalize-package-data", - "npm-cache-filename", - "npm-install-checks", - "npm-package-arg", - "npm-registry-client", - "npm-user-validate", - "npmlog", - "once", - "opener", - "osenv", - "pacote", - "path-is-inside", - "promise-inflight", - "read", - "read-cmd-shim", - "read-installed", - "read-package-json", - "read-package-tree", - "readable-stream", - "readdir-scoped-modules", - "request", - "retry", - "rimraf", - "semver", - "sha", - "slide", - "sorted-object", - "sorted-union-stream", - "ssri", - "strip-ansi", - "tar", - "text-table", - "uid-number", - "umask", - "unique-filename", - "unpipe", - "update-notifier", - "uuid", - "validate-npm-package-license", - "validate-npm-package-name", - "which", - "wrappy", - "write-file-atomic", - "safe-buffer", - "worker-farm" - ], - "inBundle": true, - "license": "Artistic-2.0", - "dependencies": { - "abbrev": "~1.1.0", - "ansi-regex": "~3.0.0", - "ansicolors": "~0.3.2", - "ansistyles": "~0.1.3", - "aproba": "~1.1.2", - "archy": "~1.0.0", - "bluebird": "~3.5.0", - "cacache": "~9.2.9", - "call-limit": "~1.1.0", - "chownr": "~1.0.1", - "cmd-shim": "~2.0.2", - "columnify": "~1.5.4", - "config-chain": "~1.1.11", - "debuglog": "*", - "detect-indent": "~5.0.0", - "dezalgo": "~1.0.3", - "editor": "~1.0.0", - "fs-vacuum": "~1.2.10", - "fs-write-stream-atomic": "~1.0.10", - "fstream": "~1.0.11", - "fstream-npm": "~1.2.1", - "glob": "~7.1.2", - "graceful-fs": "~4.1.11", - "has-unicode": "~2.0.1", - "hosted-git-info": "~2.5.0", - "iferr": "~0.1.5", - "imurmurhash": "*", - "inflight": "~1.0.6", - "inherits": "~2.0.3", - "ini": "~1.3.4", - "init-package-json": "~1.10.1", - "JSONStream": "~1.3.1", - "lazy-property": "~1.0.0", - "lockfile": "~1.0.3", - "lodash._baseindexof": "*", - "lodash._baseuniq": "~4.6.0", - "lodash._bindcallback": "*", - "lodash._cacheindexof": "*", - "lodash._createcache": "*", - "lodash._getnative": "*", - "lodash.clonedeep": "~4.5.0", - "lodash.restparam": "*", - "lodash.union": "~4.6.0", - "lodash.uniq": "~4.5.0", - "lodash.without": "~4.4.0", - "lru-cache": "~4.1.1", - "mississippi": "~1.3.0", - "mkdirp": "~0.5.1", - "move-concurrently": "~1.0.1", - "node-gyp": "~3.6.2", - "nopt": "~4.0.1", - "normalize-package-data": "~2.4.0", - "npm-cache-filename": "~1.0.2", - "npm-install-checks": "~3.0.0", - "npm-package-arg": "~5.1.2", - "npm-registry-client": "~8.4.0", - "npm-user-validate": "~1.0.0", - "npmlog": "~4.1.2", - "once": "~1.4.0", - "opener": "~1.4.3", - "osenv": "~0.1.4", - "pacote": "~2.7.38", - "path-is-inside": "~1.0.2", - "promise-inflight": "~1.0.1", - "read": "~1.0.7", - "read-cmd-shim": "~1.0.1", - "read-installed": "~4.0.3", - "read-package-json": "~2.0.9", - "read-package-tree": "~5.1.6", - "readable-stream": "~2.3.2", - "readdir-scoped-modules": "*", - "request": "~2.81.0", - "retry": "~0.10.1", - "rimraf": "~2.6.1", - "safe-buffer": "~5.1.1", - "semver": "~5.3.0", - "sha": "~2.0.1", - "slide": "~1.1.6", - "sorted-object": "~2.0.1", - "sorted-union-stream": "~2.1.3", - "ssri": "~4.1.6", - "strip-ansi": "~4.0.0", - "tar": "~2.2.1", - "text-table": "~0.2.0", - "uid-number": "0.0.6", - "umask": "~1.1.0", - "unique-filename": "~1.1.0", - "unpipe": "~1.0.0", - "update-notifier": "~2.2.0", - "uuid": "~3.1.0", - "validate-npm-package-license": "*", - "validate-npm-package-name": "~3.0.0", - "which": "~1.2.14", - "worker-farm": "~1.3.1", - "wrappy": "~1.0.2", - "write-file-atomic": "~2.1.0" - }, - "bin": { - "npm": "bin/npm-cli.js" - } - }, - "node_modules/npx/node_modules/npm-package-arg": { - "version": "6.1.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "hosted-git-info": "^2.7.1", - "osenv": "^0.1.5", - "semver": "^5.6.0", - "validate-npm-package-name": "^3.0.0" - } - }, - "node_modules/npx/node_modules/npm-run-path": { - "version": "2.0.2", - "inBundle": true, - "license": "MIT", - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/abbrev": { - "version": "1.1.0", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/ansi-regex": { - "version": "3.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/ansicolors": { - "version": "0.3.2", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/ansistyles": { - "version": "0.1.3", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/aproba": { - "version": "1.1.2", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/archy": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/bluebird": { - "version": "3.5.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/cacache": { - "version": "9.2.9", - "inBundle": true, - "license": "CC0-1.0", - "dependencies": { - "bluebird": "^3.5.0", - "chownr": "^1.0.1", - "glob": "^7.1.2", - "graceful-fs": "^4.1.11", - "lru-cache": "^4.1.1", - "mississippi": "^1.3.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.1", - "ssri": "^4.1.6", - "unique-filename": "^1.1.0", - "y18n": "^3.2.1" - } - }, - "node_modules/npx/node_modules/npm/node_modules/cacache/node_modules/lru-cache": { - "version": "4.1.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/npx/node_modules/npm/node_modules/cacache/node_modules/lru-cache/node_modules/pseudomap": { - "version": "1.0.2", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/cacache/node_modules/lru-cache/node_modules/yallist": { - "version": "2.1.2", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/cacache/node_modules/y18n": { - "version": "3.2.1", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/call-limit": { - "version": "1.1.0", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/chownr": { - "version": "1.0.1", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/cmd-shim": { - "version": "2.0.2", - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "graceful-fs": "^4.1.2", - "mkdirp": "~0.5.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/columnify": { - "version": "1.5.4", - "inBundle": true, - "license": "MIT", - "dependencies": { - "strip-ansi": "^3.0.0", - "wcwidth": "^1.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/columnify/node_modules/strip-ansi": { - "version": "3.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/columnify/node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/columnify/node_modules/wcwidth": { - "version": "1.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "defaults": "^1.0.3" - } - }, - "node_modules/npx/node_modules/npm/node_modules/columnify/node_modules/wcwidth/node_modules/defaults": { - "version": "1.0.3", - "inBundle": true, - "license": "MIT", - "dependencies": { - "clone": "^1.0.2" - } - }, - "node_modules/npx/node_modules/npm/node_modules/columnify/node_modules/wcwidth/node_modules/defaults/node_modules/clone": { - "version": "1.0.2", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/npx/node_modules/npm/node_modules/config-chain": { - "version": "1.1.11", - "inBundle": true, - "dependencies": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "node_modules/npx/node_modules/npm/node_modules/config-chain/node_modules/proto-list": { - "version": "1.2.4", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/debuglog": { - "version": "1.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/npx/node_modules/npm/node_modules/detect-indent": { - "version": "5.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/dezalgo": { - "version": "1.0.3", - "inBundle": true, - "license": "ISC", - "dependencies": { - "asap": "^2.0.0", - "wrappy": "1" - } - }, - "node_modules/npx/node_modules/npm/node_modules/dezalgo/node_modules/asap": { - "version": "2.0.5", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/editor": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/fs-vacuum": { - "version": "1.2.10", - "inBundle": true, - "license": "ISC", - "dependencies": { - "graceful-fs": "^4.1.2", - "path-is-inside": "^1.0.1", - "rimraf": "^2.5.2" - } - }, - "node_modules/npx/node_modules/npm/node_modules/fs-write-stream-atomic": { - "version": "1.0.10", - "inBundle": true, - "license": "ISC", - "dependencies": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - } - }, - "node_modules/npx/node_modules/npm/node_modules/fstream": { - "version": "1.0.11", - "inBundle": true, - "license": "ISC", - "dependencies": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - }, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/npx/node_modules/npm/node_modules/fstream-npm": { - "version": "1.2.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "fstream-ignore": "^1.0.0", - "inherits": "2" - } - }, - "node_modules/npx/node_modules/npm/node_modules/fstream-npm/node_modules/fstream-ignore": { - "version": "1.0.5", - "inBundle": true, - "license": "ISC", - "dependencies": { - "fstream": "^1.0.0", - "inherits": "2", - "minimatch": "^3.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/fstream-npm/node_modules/fstream-ignore/node_modules/minimatch": { - "version": "3.0.4", - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/npx/node_modules/npm/node_modules/fstream-npm/node_modules/fstream-ignore/node_modules/minimatch/node_modules/brace-expansion": { - "version": "1.1.8", - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/npx/node_modules/npm/node_modules/fstream-npm/node_modules/fstream-ignore/node_modules/minimatch/node_modules/brace-expansion/node_modules/balanced-match": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/fstream-npm/node_modules/fstream-ignore/node_modules/minimatch/node_modules/brace-expansion/node_modules/concat-map": { - "version": "0.0.1", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/glob": { - "version": "7.1.2", - "inBundle": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/npx/node_modules/npm/node_modules/glob/node_modules/fs.realpath": { - "version": "1.0.0", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/glob/node_modules/minimatch": { - "version": "3.0.4", - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/npx/node_modules/npm/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion": { - "version": "1.1.8", - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/npx/node_modules/npm/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion/node_modules/balanced-match": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion/node_modules/concat-map": { - "version": "0.0.1", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/glob/node_modules/path-is-absolute": { - "version": "1.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/graceful-fs": { - "version": "4.1.11", - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/has-unicode": { - "version": "2.0.1", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/hosted-git-info": { - "version": "2.5.0", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/iferr": { - "version": "0.1.5", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/imurmurhash": { - "version": "0.1.4", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/npx/node_modules/npm/node_modules/inflight": { - "version": "1.0.6", - "inBundle": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/npx/node_modules/npm/node_modules/inherits": { - "version": "2.0.3", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/ini": { - "version": "1.3.4", - "inBundle": true, - "license": "ISC", - "engines": { - "node": "*" - } - }, - "node_modules/npx/node_modules/npm/node_modules/init-package-json": { - "version": "1.10.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.1", - "npm-package-arg": "^4.0.0 || ^5.0.0", - "promzard": "^0.3.0", - "read": "~1.0.1", - "read-package-json": "1 || 2", - "semver": "2.x || 3.x || 4 || 5", - "validate-npm-package-license": "^3.0.1", - "validate-npm-package-name": "^3.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/init-package-json/node_modules/promzard": { - "version": "0.3.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "read": "1" - } - }, - "node_modules/npx/node_modules/npm/node_modules/JSONStream": { - "version": "1.3.1", - "inBundle": true, - "license": "(MIT OR Apache-2.0)", - "dependencies": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - }, - "bin": { - "JSONStream": "index.js" - }, - "engines": { - "node": "*" - } - }, - "node_modules/npx/node_modules/npm/node_modules/JSONStream/node_modules/jsonparse": { - "version": "1.3.1", - "engines": [ - "node >= 0.2.0" - ], - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/JSONStream/node_modules/through": { - "version": "2.3.8", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/lazy-property": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/lockfile": { - "version": "1.0.3", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/lodash._baseindexof": { - "version": "3.1.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/lodash._baseuniq": { - "version": "4.6.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "lodash._createset": "~4.0.0", - "lodash._root": "~3.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/lodash._baseuniq/node_modules/lodash._createset": { - "version": "4.0.3", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/lodash._baseuniq/node_modules/lodash._root": { - "version": "3.0.1", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/lodash._bindcallback": { - "version": "3.0.1", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/lodash._cacheindexof": { - "version": "3.0.2", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/lodash._createcache": { - "version": "3.1.2", - "inBundle": true, - "license": "MIT", - "dependencies": { - "lodash._getnative": "^3.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/lodash._getnative": { - "version": "3.9.1", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/lodash.clonedeep": { - "version": "4.5.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/lodash.restparam": { - "version": "3.6.1", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/lodash.union": { - "version": "4.6.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/lodash.uniq": { - "version": "4.5.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/lodash.without": { - "version": "4.4.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/lru-cache": { - "version": "4.1.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/npx/node_modules/npm/node_modules/lru-cache/node_modules/pseudomap": { - "version": "1.0.2", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/lru-cache/node_modules/yallist": { - "version": "2.1.2", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/mississippi": { - "version": "1.3.0", - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^1.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/mississippi/node_modules/concat-stream": { - "version": "1.6.0", - "engines": [ - "node >= 0.8" - ], - "inBundle": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/npx/node_modules/npm/node_modules/mississippi/node_modules/concat-stream/node_modules/typedarray": { - "version": "0.0.6", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/mississippi/node_modules/duplexify": { - "version": "3.5.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/mississippi/node_modules/duplexify/node_modules/end-of-stream": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "once": "~1.3.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/mississippi/node_modules/duplexify/node_modules/end-of-stream/node_modules/once": { - "version": "1.3.3", - "inBundle": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/npx/node_modules/npm/node_modules/mississippi/node_modules/duplexify/node_modules/stream-shift": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/mississippi/node_modules/end-of-stream": { - "version": "1.4.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/mississippi/node_modules/flush-write-stream": { - "version": "1.0.2", - "inBundle": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/mississippi/node_modules/from2": { - "version": "2.3.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/mississippi/node_modules/parallel-transform": { - "version": "1.1.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "cyclist": "~0.2.2", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - } - }, - "node_modules/npx/node_modules/npm/node_modules/mississippi/node_modules/parallel-transform/node_modules/cyclist": { - "version": "0.2.2", - "inBundle": true - }, - "node_modules/npx/node_modules/npm/node_modules/mississippi/node_modules/pump": { - "version": "1.0.2", - "inBundle": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/npx/node_modules/npm/node_modules/mississippi/node_modules/pumpify": { - "version": "1.3.5", - "inBundle": true, - "license": "MIT", - "dependencies": { - "duplexify": "^3.1.2", - "inherits": "^2.0.1", - "pump": "^1.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/mississippi/node_modules/stream-each": { - "version": "1.2.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/mississippi/node_modules/stream-each/node_modules/stream-shift": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/mississippi/node_modules/through2": { - "version": "2.0.3", - "inBundle": true, - "license": "MIT", - "dependencies": { - "readable-stream": "^2.1.5", - "xtend": "~4.0.1" - } - }, - "node_modules/npx/node_modules/npm/node_modules/mississippi/node_modules/through2/node_modules/xtend": { - "version": "4.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/mkdirp": { - "version": "0.5.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "minimist": "0.0.8" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/npx/node_modules/npm/node_modules/mkdirp/node_modules/minimist": { - "version": "0.0.8", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/move-concurrently": { - "version": "1.0.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "node_modules/npx/node_modules/npm/node_modules/move-concurrently/node_modules/copy-concurrently": { - "version": "1.0.3", - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/move-concurrently/node_modules/run-queue": { - "version": "1.0.3", - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^1.1.1" - } - }, - "node_modules/npx/node_modules/npm/node_modules/node-gyp": { - "version": "3.6.2", - "inBundle": true, - "license": "MIT", - "dependencies": { - "fstream": "^1.0.0", - "glob": "^7.0.3", - "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.0", - "nopt": "2 || 3", - "npmlog": "0 || 1 || 2 || 3 || 4", - "osenv": "0", - "request": "2", - "rimraf": "2", - "semver": "~5.3.0", - "tar": "^2.0.0", - "which": "1" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/node-gyp/node_modules/minimatch": { - "version": "3.0.4", - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/npx/node_modules/npm/node_modules/node-gyp/node_modules/minimatch/node_modules/brace-expansion": { - "version": "1.1.8", - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/npx/node_modules/npm/node_modules/node-gyp/node_modules/minimatch/node_modules/brace-expansion/node_modules/balanced-match": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/node-gyp/node_modules/minimatch/node_modules/brace-expansion/node_modules/concat-map": { - "version": "0.0.1", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/node-gyp/node_modules/nopt": { - "version": "3.0.6", - "inBundle": true, - "license": "ISC", - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - } - }, - "node_modules/npx/node_modules/npm/node_modules/nopt": { - "version": "4.0.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "abbrev": "1", - "osenv": "^0.1.4" - }, - "bin": { - "nopt": "bin/nopt.js" - } - }, - "node_modules/npx/node_modules/npm/node_modules/normalize-package-data": { - "version": "2.4.0", - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/npx/node_modules/npm/node_modules/normalize-package-data/node_modules/is-builtin-module": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "builtin-modules": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/normalize-package-data/node_modules/is-builtin-module/node_modules/builtin-modules": { - "version": "1.1.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/npm-cache-filename": { - "version": "1.0.2", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/npm-install-checks": { - "version": "3.0.0", - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "semver": "^2.3.0 || 3.x || 4 || 5" - } - }, - "node_modules/npx/node_modules/npm/node_modules/npm-package-arg": { - "version": "5.1.2", - "inBundle": true, - "license": "ISC", - "dependencies": { - "hosted-git-info": "^2.4.2", - "osenv": "^0.1.4", - "semver": "^5.1.0", - "validate-npm-package-name": "^3.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/npm-registry-client": { - "version": "8.4.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "concat-stream": "^1.5.2", - "graceful-fs": "^4.1.6", - "normalize-package-data": "~1.0.1 || ^2.0.0", - "npm-package-arg": "^3.0.0 || ^4.0.0 || ^5.0.0", - "once": "^1.3.3", - "request": "^2.74.0", - "retry": "^0.10.0", - "semver": "2 >=2.2.1 || 3.x || 4 || 5", - "slide": "^1.1.3", - "ssri": "^4.1.2" - }, - "optionalDependencies": { - "npmlog": "2 || ^3.1.0 || ^4.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/npm-registry-client/node_modules/concat-stream": { - "version": "1.6.0", - "engines": [ - "node >= 0.8" - ], - "inBundle": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/npx/node_modules/npm/node_modules/npm-registry-client/node_modules/concat-stream/node_modules/typedarray": { - "version": "0.0.6", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/npm-user-validate": { - "version": "1.0.0", - "inBundle": true, - "license": "BSD-2-Clause" - }, - "node_modules/npx/node_modules/npm/node_modules/npmlog": { - "version": "4.1.2", - "inBundle": true, - "license": "ISC", - "dependencies": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/npmlog/node_modules/are-we-there-yet": { - "version": "1.1.4", - "inBundle": true, - "license": "ISC", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "node_modules/npx/node_modules/npm/node_modules/npmlog/node_modules/are-we-there-yet/node_modules/delegates": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/npmlog/node_modules/console-control-strings": { - "version": "1.1.0", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/npmlog/node_modules/gauge": { - "version": "2.7.4", - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/npmlog/node_modules/gauge/node_modules/object-assign": { - "version": "4.1.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/npmlog/node_modules/gauge/node_modules/signal-exit": { - "version": "3.0.2", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/npmlog/node_modules/gauge/node_modules/string-width": { - "version": "1.0.2", - "inBundle": true, - "license": "MIT", - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/npmlog/node_modules/gauge/node_modules/string-width/node_modules/code-point-at": { - "version": "1.1.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/npmlog/node_modules/gauge/node_modules/string-width/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/npmlog/node_modules/gauge/node_modules/string-width/node_modules/is-fullwidth-code-point/node_modules/number-is-nan": { - "version": "1.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/npmlog/node_modules/gauge/node_modules/strip-ansi": { - "version": "3.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/npmlog/node_modules/gauge/node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/npmlog/node_modules/gauge/node_modules/wide-align": { - "version": "1.1.2", - "inBundle": true, - "license": "ISC", - "dependencies": { - "string-width": "^1.0.2" - } - }, - "node_modules/npx/node_modules/npm/node_modules/npmlog/node_modules/set-blocking": { - "version": "2.0.0", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/once": { - "version": "1.4.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/npx/node_modules/npm/node_modules/opener": { - "version": "1.4.3", - "inBundle": true, - "license": "(WTFPL OR MIT)", - "bin": { - "opener": "opener.js" - } - }, - "node_modules/npx/node_modules/npm/node_modules/osenv": { - "version": "0.1.4", - "inBundle": true, - "license": "ISC", - "dependencies": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/osenv/node_modules/os-homedir": { - "version": "1.0.2", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/osenv/node_modules/os-tmpdir": { - "version": "1.0.2", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote": { - "version": "2.7.38", - "inBundle": true, - "license": "CC0-1.0", - "dependencies": { - "bluebird": "^3.5.0", - "cacache": "^9.2.9", - "glob": "^7.1.2", - "lru-cache": "^4.1.1", - "make-fetch-happen": "^2.4.13", - "minimatch": "^3.0.4", - "mississippi": "^1.2.0", - "normalize-package-data": "^2.4.0", - "npm-package-arg": "^5.1.2", - "npm-pick-manifest": "^1.0.4", - "osenv": "^0.1.4", - "promise-inflight": "^1.0.1", - "promise-retry": "^1.1.1", - "protoduck": "^4.0.0", - "safe-buffer": "^5.1.1", - "semver": "^5.3.0", - "ssri": "^4.1.6", - "tar-fs": "^1.15.3", - "tar-stream": "^1.5.4", - "unique-filename": "^1.1.0", - "which": "^1.2.12" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen": { - "version": "2.4.13", - "inBundle": true, - "license": "CC0-1.0", - "dependencies": { - "agentkeepalive": "^3.3.0", - "cacache": "^9.2.9", - "http-cache-semantics": "^3.7.3", - "http-proxy-agent": "^2.0.0", - "https-proxy-agent": "^2.0.0", - "lru-cache": "^4.1.1", - "mississippi": "^1.2.0", - "node-fetch-npm": "^2.0.1", - "promise-retry": "^1.1.1", - "socks-proxy-agent": "^3.0.0", - "ssri": "^4.1.6" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/agentkeepalive": { - "version": "3.3.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "humanize-ms": "^1.2.1" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/agentkeepalive/node_modules/humanize-ms": { - "version": "1.2.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ms": "^2.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/agentkeepalive/node_modules/humanize-ms/node_modules/ms": { - "version": "2.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-cache-semantics": { - "version": "3.7.3", - "inBundle": true, - "license": "BSD-2-Clause" - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent": { - "version": "2.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "agent-base": "4", - "debug": "2" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/agent-base": { - "version": "4.1.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "es6-promisify": "^5.0.0" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/agent-base/node_modules/es6-promisify": { - "version": "5.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "es6-promise": "^4.0.3" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/agent-base/node_modules/es6-promisify/node_modules/es6-promise": { - "version": "4.1.1", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/debug": { - "version": "2.6.8", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent": { - "version": "2.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "agent-base": "^4.1.0", - "debug": "^2.4.1" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/agent-base": { - "version": "4.1.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "es6-promisify": "^5.0.0" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/agent-base/node_modules/es6-promisify": { - "version": "5.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "es6-promise": "^4.0.3" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/agent-base/node_modules/es6-promisify/node_modules/es6-promise": { - "version": "4.1.1", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/debug": { - "version": "2.6.8", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/node-fetch-npm": { - "version": "2.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "encoding": "^0.1.11", - "json-parse-helpfulerror": "^1.0.3", - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/node-fetch-npm/node_modules/encoding": { - "version": "0.1.12", - "inBundle": true, - "license": "MIT", - "dependencies": { - "iconv-lite": "~0.4.13" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/node-fetch-npm/node_modules/encoding/node_modules/iconv-lite": { - "version": "0.4.18", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/node-fetch-npm/node_modules/json-parse-helpfulerror": { - "version": "1.0.3", - "inBundle": true, - "license": "MIT", - "dependencies": { - "jju": "^1.1.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/node-fetch-npm/node_modules/json-parse-helpfulerror/node_modules/jju": { - "version": "1.3.0", - "inBundle": true, - "license": "WTFPL" - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent": { - "version": "3.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "agent-base": "^4.0.1", - "socks": "^1.1.10" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/agent-base": { - "version": "4.1.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "es6-promisify": "^5.0.0" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/agent-base/node_modules/es6-promisify": { - "version": "5.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "es6-promise": "^4.0.3" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/agent-base/node_modules/es6-promisify/node_modules/es6-promise": { - "version": "4.1.1", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/socks": { - "version": "1.1.10", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ip": "^1.1.4", - "smart-buffer": "^1.0.13" - }, - "engines": { - "node": ">= 0.10.0", - "npm": ">= 1.3.5" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/socks/node_modules/ip": { - "version": "1.1.5", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/socks/node_modules/smart-buffer": { - "version": "1.1.15", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.10.15", - "npm": ">= 1.3.5" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/minimatch": { - "version": "3.0.4", - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/minimatch/node_modules/brace-expansion": { - "version": "1.1.8", - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/minimatch/node_modules/brace-expansion/node_modules/balanced-match": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/minimatch/node_modules/brace-expansion/node_modules/concat-map": { - "version": "0.0.1", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/npm-pick-manifest": { - "version": "1.0.4", - "inBundle": true, - "license": "CC0-1.0", - "dependencies": { - "npm-package-arg": "^5.1.2", - "semver": "^5.3.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/promise-retry": { - "version": "1.1.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "err-code": "^1.0.0", - "retry": "^0.10.0" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/promise-retry/node_modules/err-code": { - "version": "1.1.2", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/protoduck": { - "version": "4.0.0", - "inBundle": true, - "license": "CC0-1.0", - "dependencies": { - "genfun": "^4.0.1" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/protoduck/node_modules/genfun": { - "version": "4.0.1", - "inBundle": true, - "license": "CC0-1.0" - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/tar-fs": { - "version": "1.15.3", - "inBundle": true, - "license": "MIT", - "dependencies": { - "chownr": "^1.0.1", - "mkdirp": "^0.5.1", - "pump": "^1.0.0", - "tar-stream": "^1.1.2" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/tar-fs/node_modules/pump": { - "version": "1.0.2", - "inBundle": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/tar-fs/node_modules/pump/node_modules/end-of-stream": { - "version": "1.4.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/tar-stream": { - "version": "1.5.4", - "inBundle": true, - "license": "MIT", - "dependencies": { - "bl": "^1.0.0", - "end-of-stream": "^1.0.0", - "readable-stream": "^2.0.0", - "xtend": "^4.0.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/tar-stream/node_modules/bl": { - "version": "1.2.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "readable-stream": "^2.0.5" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/tar-stream/node_modules/end-of-stream": { - "version": "1.4.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/pacote/node_modules/tar-stream/node_modules/xtend": { - "version": "4.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/path-is-inside": { - "version": "1.0.2", - "inBundle": true, - "license": "(WTFPL OR MIT)" - }, - "node_modules/npx/node_modules/npm/node_modules/promise-inflight": { - "version": "1.0.1", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/read": { - "version": "1.0.7", - "inBundle": true, - "license": "ISC", - "dependencies": { - "mute-stream": "~0.0.4" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/npx/node_modules/npm/node_modules/read-cmd-shim": { - "version": "1.0.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "graceful-fs": "^4.1.2" - } - }, - "node_modules/npx/node_modules/npm/node_modules/read-installed": { - "version": "4.0.3", - "inBundle": true, - "license": "ISC", - "dependencies": { - "debuglog": "^1.0.1", - "read-package-json": "^2.0.0", - "readdir-scoped-modules": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "slide": "~1.1.3", - "util-extend": "^1.0.1" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.2" - } - }, - "node_modules/npx/node_modules/npm/node_modules/read-installed/node_modules/util-extend": { - "version": "1.0.3", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/read-package-json": { - "version": "2.0.9", - "inBundle": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.1", - "json-parse-helpfulerror": "^1.0.2", - "normalize-package-data": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.2" - } - }, - "node_modules/npx/node_modules/npm/node_modules/read-package-json/node_modules/json-parse-helpfulerror": { - "version": "1.0.3", - "inBundle": true, - "license": "MIT", - "dependencies": { - "jju": "^1.1.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/read-package-json/node_modules/json-parse-helpfulerror/node_modules/jju": { - "version": "1.3.0", - "inBundle": true, - "license": "WTFPL" - }, - "node_modules/npx/node_modules/npm/node_modules/read-package-tree": { - "version": "5.1.6", - "inBundle": true, - "license": "ISC", - "dependencies": { - "debuglog": "^1.0.1", - "dezalgo": "^1.0.0", - "once": "^1.3.0", - "read-package-json": "^2.0.0", - "readdir-scoped-modules": "^1.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/read/node_modules/mute-stream": { - "version": "0.0.7", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/readable-stream": { - "version": "2.3.2", - "inBundle": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "safe-buffer": "~5.1.0", - "string_decoder": "~1.0.0", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/npx/node_modules/npm/node_modules/readable-stream/node_modules/core-util-is": { - "version": "1.0.2", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/readable-stream/node_modules/isarray": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/readable-stream/node_modules/process-nextick-args": { - "version": "1.0.7", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/readable-stream/node_modules/string_decoder": { - "version": "1.0.3", - "inBundle": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/readable-stream/node_modules/util-deprecate": { - "version": "1.0.2", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/readdir-scoped-modules": { - "version": "1.0.2", - "inBundle": true, - "license": "ISC", - "dependencies": { - "debuglog": "^1.0.1", - "dezalgo": "^1.0.0", - "graceful-fs": "^4.1.2", - "once": "^1.3.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request": { - "version": "2.81.0", - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "aws-sign2": "~0.6.0", - "aws4": "^1.2.1", - "caseless": "~0.12.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.0", - "forever-agent": "~0.6.1", - "form-data": "~2.1.1", - "har-validator": "~4.2.1", - "hawk": "~3.1.3", - "http-signature": "~1.1.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.7", - "oauth-sign": "~0.8.1", - "performance-now": "^0.2.0", - "qs": "~6.4.0", - "safe-buffer": "^5.0.1", - "stringstream": "~0.0.4", - "tough-cookie": "~2.3.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.0.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/aws-sign2": { - "version": "0.6.0", - "inBundle": true, - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/aws4": { - "version": "1.6.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/caseless": { - "version": "0.12.0", - "inBundle": true, - "license": "Apache-2.0" - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/combined-stream": { - "version": "1.0.5", - "inBundle": true, - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/combined-stream/node_modules/delayed-stream": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/extend": { - "version": "3.0.1", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/forever-agent": { - "version": "0.6.1", - "inBundle": true, - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/form-data": { - "version": "2.1.4", - "inBundle": true, - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.5", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/form-data/node_modules/asynckit": { - "version": "0.4.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/har-validator": { - "version": "4.2.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "ajv": "^4.9.1", - "har-schema": "^1.0.5" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/har-validator/node_modules/ajv": { - "version": "4.11.8", - "inBundle": true, - "license": "MIT", - "dependencies": { - "co": "^4.6.0", - "json-stable-stringify": "^1.0.1" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/har-validator/node_modules/ajv/node_modules/co": { - "version": "4.6.0", - "inBundle": true, - "license": "MIT", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/har-validator/node_modules/ajv/node_modules/json-stable-stringify": { - "version": "1.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "jsonify": "~0.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/har-validator/node_modules/ajv/node_modules/json-stable-stringify/node_modules/jsonify": { - "version": "0.0.0", - "inBundle": true, - "license": "Public Domain", - "engines": { - "node": "*" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/har-validator/node_modules/har-schema": { - "version": "1.0.5", - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/hawk": { - "version": "3.1.3", - "inBundle": true, - "license": "BSD-3-Clause", - "dependencies": { - "boom": "2.x.x", - "cryptiles": "2.x.x", - "hoek": "2.x.x", - "sntp": "1.x.x" - }, - "engines": { - "node": ">=0.10.32" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/hawk/node_modules/boom": { - "version": "2.10.1", - "inBundle": true, - "license": "BSD-3-Clause", - "dependencies": { - "hoek": "2.x.x" - }, - "engines": { - "node": ">=0.10.40" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/hawk/node_modules/cryptiles": { - "version": "2.0.5", - "inBundle": true, - "license": "BSD-3-Clause", - "dependencies": { - "boom": "2.x.x" - }, - "engines": { - "node": ">=0.10.40" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/hawk/node_modules/hoek": { - "version": "2.16.3", - "inBundle": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.40" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/hawk/node_modules/sntp": { - "version": "1.0.9", - "inBundle": true, - "dependencies": { - "hoek": "2.x.x" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/http-signature": { - "version": "1.1.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "assert-plus": "^0.2.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/http-signature/node_modules/assert-plus": { - "version": "0.2.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/http-signature/node_modules/jsprim": { - "version": "1.4.0", - "engines": [ - "node >=0.6.0" - ], - "inBundle": true, - "license": "MIT", - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.0.2", - "json-schema": "0.2.3", - "verror": "1.3.6" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/http-signature/node_modules/jsprim/node_modules/assert-plus": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/http-signature/node_modules/jsprim/node_modules/extsprintf": { - "version": "1.0.2", - "engines": [ - "node >=0.6.0" - ], - "inBundle": true - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/http-signature/node_modules/jsprim/node_modules/json-schema": { - "version": "0.2.3", - "inBundle": true - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/http-signature/node_modules/jsprim/node_modules/verror": { - "version": "1.3.6", - "engines": [ - "node >=0.6.0" - ], - "inBundle": true, - "dependencies": { - "extsprintf": "1.0.2" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk": { - "version": "1.13.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "dashdash": "^1.12.0", - "getpass": "^0.1.1" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - }, - "optionalDependencies": { - "bcrypt-pbkdf": "^1.0.0", - "ecc-jsbn": "~0.1.1", - "jsbn": "~0.1.0", - "tweetnacl": "~0.14.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/node_modules/asn1": { - "version": "0.2.3", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/node_modules/assert-plus": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/node_modules/bcrypt-pbkdf": { - "version": "1.0.1", - "inBundle": true, - "license": "BSD-3-Clause", - "optional": true, - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/node_modules/dashdash": { - "version": "1.14.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/node_modules/ecc-jsbn": { - "version": "0.1.1", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "jsbn": "~0.1.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/node_modules/getpass": { - "version": "0.1.7", - "inBundle": true, - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/node_modules/jsbn": { - "version": "0.1.1", - "inBundle": true, - "license": "MIT", - "optional": true - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/node_modules/tweetnacl": { - "version": "0.14.5", - "inBundle": true, - "license": "Unlicense", - "optional": true - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/is-typedarray": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/isstream": { - "version": "0.1.2", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/json-stringify-safe": { - "version": "5.0.1", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/mime-types": { - "version": "2.1.15", - "inBundle": true, - "license": "MIT", - "dependencies": { - "mime-db": "~1.27.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/mime-types/node_modules/mime-db": { - "version": "1.27.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/oauth-sign": { - "version": "0.8.2", - "inBundle": true, - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/performance-now": { - "version": "0.2.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/qs": { - "version": "6.4.0", - "inBundle": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/stringstream": { - "version": "0.0.5", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/tough-cookie": { - "version": "2.3.2", - "inBundle": true, - "license": "BSD-3-Clause", - "dependencies": { - "punycode": "^1.4.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/tough-cookie/node_modules/punycode": { - "version": "1.4.1", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/request/node_modules/tunnel-agent": { - "version": "0.6.0", - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/npx/node_modules/npm/node_modules/retry": { - "version": "0.10.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/npx/node_modules/npm/node_modules/rimraf": { - "version": "2.6.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "glob": "^7.0.5" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/npx/node_modules/npm/node_modules/safe-buffer": { - "version": "5.1.1", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/semver": { - "version": "5.3.0", - "inBundle": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/npx/node_modules/npm/node_modules/sha": { - "version": "2.0.1", - "inBundle": true, - "license": "(BSD-2-Clause OR MIT)", - "dependencies": { - "graceful-fs": "^4.1.2", - "readable-stream": "^2.0.2" - } - }, - "node_modules/npx/node_modules/npm/node_modules/slide": { - "version": "1.1.6", - "inBundle": true, - "license": "ISC", - "engines": { - "node": "*" - } - }, - "node_modules/npx/node_modules/npm/node_modules/sorted-object": { - "version": "2.0.1", - "inBundle": true, - "license": "(WTFPL OR MIT)" - }, - "node_modules/npx/node_modules/npm/node_modules/sorted-union-stream": { - "version": "2.1.3", - "inBundle": true, - "license": "MIT", - "dependencies": { - "from2": "^1.3.0", - "stream-iterate": "^1.1.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/sorted-union-stream/node_modules/from2": { - "version": "1.3.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "inherits": "~2.0.1", - "readable-stream": "~1.1.10" - } - }, - "node_modules/npx/node_modules/npm/node_modules/sorted-union-stream/node_modules/from2/node_modules/readable-stream": { - "version": "1.1.14", - "inBundle": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/npx/node_modules/npm/node_modules/sorted-union-stream/node_modules/from2/node_modules/readable-stream/node_modules/core-util-is": { - "version": "1.0.2", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/sorted-union-stream/node_modules/from2/node_modules/readable-stream/node_modules/isarray": { - "version": "0.0.1", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/sorted-union-stream/node_modules/from2/node_modules/readable-stream/node_modules/string_decoder": { - "version": "0.10.31", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/sorted-union-stream/node_modules/stream-iterate": { - "version": "1.2.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "readable-stream": "^2.1.5", - "stream-shift": "^1.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/sorted-union-stream/node_modules/stream-iterate/node_modules/stream-shift": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/ssri": { - "version": "4.1.6", - "inBundle": true, - "license": "CC0-1.0", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/strip-ansi": { - "version": "4.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "3.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/tar": { - "version": "2.2.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "block-stream": "*", - "fstream": "^1.0.2", - "inherits": "2" - } - }, - "node_modules/npx/node_modules/npm/node_modules/tar/node_modules/block-stream": { - "version": "0.0.9", - "inBundle": true, - "license": "ISC", - "dependencies": { - "inherits": "~2.0.0" - }, - "engines": { - "node": "0.4 || >=0.5.8" - } - }, - "node_modules/npx/node_modules/npm/node_modules/text-table": { - "version": "0.2.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/uid-number": { - "version": "0.0.6", - "inBundle": true, - "license": "ISC", - "engines": { - "node": "*" - } - }, - "node_modules/npx/node_modules/npm/node_modules/umask": { - "version": "1.1.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/unique-filename": { - "version": "1.1.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "unique-slug": "^2.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/unique-filename/node_modules/unique-slug": { - "version": "2.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/unpipe": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier": { - "version": "2.2.0", - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "boxen": "^1.0.0", - "chalk": "^1.0.0", - "configstore": "^3.0.0", - "import-lazy": "^2.1.0", - "is-npm": "^1.0.0", - "latest-version": "^3.0.0", - "semver-diff": "^2.0.0", - "xdg-basedir": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/boxen": { - "version": "1.1.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-align": "^2.0.0", - "camelcase": "^4.0.0", - "chalk": "^1.1.1", - "cli-boxes": "^1.0.0", - "string-width": "^2.0.0", - "term-size": "^0.1.0", - "widest-line": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/boxen/node_modules/ansi-align": { - "version": "2.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "string-width": "^2.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/boxen/node_modules/camelcase": { - "version": "4.1.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/boxen/node_modules/cli-boxes": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/boxen/node_modules/string-width": { - "version": "2.1.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/boxen/node_modules/string-width/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/boxen/node_modules/string-width/node_modules/strip-ansi": { - "version": "4.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/boxen/node_modules/term-size": { - "version": "0.1.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "execa": "^0.4.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/boxen/node_modules/term-size/node_modules/execa": { - "version": "0.4.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "cross-spawn-async": "^2.1.1", - "is-stream": "^1.1.0", - "npm-run-path": "^1.0.0", - "object-assign": "^4.0.1", - "path-key": "^1.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/boxen/node_modules/term-size/node_modules/execa/node_modules/cross-spawn-async": { - "version": "2.2.5", - "inBundle": true, - "license": "MIT", - "dependencies": { - "lru-cache": "^4.0.0", - "which": "^1.2.8" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/boxen/node_modules/term-size/node_modules/execa/node_modules/is-stream": { - "version": "1.1.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/boxen/node_modules/term-size/node_modules/execa/node_modules/npm-run-path": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "path-key": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/boxen/node_modules/term-size/node_modules/execa/node_modules/object-assign": { - "version": "4.1.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/boxen/node_modules/term-size/node_modules/execa/node_modules/path-key": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/boxen/node_modules/term-size/node_modules/execa/node_modules/strip-eof": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/boxen/node_modules/widest-line": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "string-width": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/boxen/node_modules/widest-line/node_modules/string-width": { - "version": "1.0.2", - "inBundle": true, - "license": "MIT", - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/boxen/node_modules/widest-line/node_modules/string-width/node_modules/code-point-at": { - "version": "1.1.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/boxen/node_modules/widest-line/node_modules/string-width/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/boxen/node_modules/widest-line/node_modules/string-width/node_modules/is-fullwidth-code-point/node_modules/number-is-nan": { - "version": "1.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/boxen/node_modules/widest-line/node_modules/string-width/node_modules/strip-ansi": { - "version": "3.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/boxen/node_modules/widest-line/node_modules/string-width/node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/chalk": { - "version": "1.1.3", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/chalk/node_modules/ansi-styles": { - "version": "2.2.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/chalk/node_modules/escape-string-regexp": { - "version": "1.0.5", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/chalk/node_modules/has-ansi": { - "version": "2.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/chalk/node_modules/has-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/chalk/node_modules/strip-ansi": { - "version": "3.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/chalk/node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/chalk/node_modules/supports-color": { - "version": "2.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/configstore": { - "version": "3.1.0", - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "dot-prop": "^4.1.0", - "graceful-fs": "^4.1.2", - "make-dir": "^1.0.0", - "unique-string": "^1.0.0", - "write-file-atomic": "^2.0.0", - "xdg-basedir": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/configstore/node_modules/dot-prop": { - "version": "4.1.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "is-obj": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/configstore/node_modules/dot-prop/node_modules/is-obj": { - "version": "1.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/configstore/node_modules/make-dir": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "pify": "^2.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/configstore/node_modules/make-dir/node_modules/pify": { - "version": "2.3.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/configstore/node_modules/unique-string": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "crypto-random-string": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/configstore/node_modules/unique-string/node_modules/crypto-random-string": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/import-lazy": { - "version": "2.1.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/is-npm": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version": { - "version": "3.1.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "package-json": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json": { - "version": "4.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "got": "^6.7.1", - "registry-auth-token": "^3.0.1", - "registry-url": "^3.0.3", - "semver": "^5.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json/node_modules/got": { - "version": "6.7.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "create-error-class": "^3.0.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-redirect": "^1.0.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "lowercase-keys": "^1.0.0", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "unzip-response": "^2.0.1", - "url-parse-lax": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json/node_modules/got/node_modules/create-error-class": { - "version": "3.0.2", - "inBundle": true, - "license": "MIT", - "dependencies": { - "capture-stack-trace": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json/node_modules/got/node_modules/create-error-class/node_modules/capture-stack-trace": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json/node_modules/got/node_modules/duplexer3": { - "version": "0.1.4", - "inBundle": true, - "license": "BSD-3-Clause" - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json/node_modules/got/node_modules/get-stream": { - "version": "3.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json/node_modules/got/node_modules/is-redirect": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json/node_modules/got/node_modules/is-retry-allowed": { - "version": "1.1.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json/node_modules/got/node_modules/is-stream": { - "version": "1.1.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json/node_modules/got/node_modules/lowercase-keys": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json/node_modules/got/node_modules/timed-out": { - "version": "4.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json/node_modules/got/node_modules/unzip-response": { - "version": "2.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json/node_modules/got/node_modules/url-parse-lax": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "prepend-http": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json/node_modules/got/node_modules/url-parse-lax/node_modules/prepend-http": { - "version": "1.0.4", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json/node_modules/registry-auth-token": { - "version": "3.3.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "rc": "^1.1.6", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json/node_modules/registry-auth-token/node_modules/rc": { - "version": "1.2.1", - "inBundle": true, - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "dependencies": { - "deep-extend": "~0.4.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "index.js" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json/node_modules/registry-auth-token/node_modules/rc/node_modules/deep-extend": { - "version": "0.4.2", - "inBundle": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.12.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json/node_modules/registry-auth-token/node_modules/rc/node_modules/minimist": { - "version": "1.2.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json/node_modules/registry-auth-token/node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json/node_modules/registry-url": { - "version": "3.1.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "rc": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json/node_modules/registry-url/node_modules/rc": { - "version": "1.2.1", - "inBundle": true, - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "dependencies": { - "deep-extend": "~0.4.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "index.js" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json/node_modules/registry-url/node_modules/rc/node_modules/deep-extend": { - "version": "0.4.2", - "inBundle": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.12.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json/node_modules/registry-url/node_modules/rc/node_modules/minimist": { - "version": "1.2.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/latest-version/node_modules/package-json/node_modules/registry-url/node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/semver-diff": { - "version": "2.1.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "semver": "^5.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/update-notifier/node_modules/xdg-basedir": { - "version": "3.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/uuid": { - "version": "3.1.0", - "inBundle": true, - "license": "MIT", - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/npx/node_modules/npm/node_modules/validate-npm-package-license": { - "version": "3.0.1", - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "~1.0.0", - "spdx-expression-parse": "~1.0.0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-correct": { - "version": "1.0.2", - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-license-ids": "^1.0.2" - } - }, - "node_modules/npx/node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-correct/node_modules/spdx-license-ids": { - "version": "1.2.2", - "inBundle": true, - "license": "Unlicense" - }, - "node_modules/npx/node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": { - "version": "1.0.4", - "inBundle": true, - "license": "(MIT AND CC-BY-3.0)" - }, - "node_modules/npx/node_modules/npm/node_modules/validate-npm-package-name": { - "version": "3.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "builtins": "^1.0.3" - } - }, - "node_modules/npx/node_modules/npm/node_modules/validate-npm-package-name/node_modules/builtins": { - "version": "1.0.3", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/which": { - "version": "1.2.14", - "inBundle": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/npx/node_modules/npm/node_modules/which/node_modules/isexe": { - "version": "2.0.0", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/worker-farm": { - "version": "1.3.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "errno": ">=0.1.1 <0.2.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - } - }, - "node_modules/npx/node_modules/npm/node_modules/worker-farm/node_modules/errno": { - "version": "0.1.4", - "inBundle": true, - "license": "MIT", - "dependencies": { - "prr": "~0.0.0" - }, - "bin": { - "errno": "cli.js" - } - }, - "node_modules/npx/node_modules/npm/node_modules/worker-farm/node_modules/errno/node_modules/prr": { - "version": "0.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/npm/node_modules/worker-farm/node_modules/xtend": { - "version": "4.0.1", - "inBundle": true, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/npx/node_modules/npm/node_modules/wrappy": { - "version": "1.0.2", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/npm/node_modules/write-file-atomic": { - "version": "2.1.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "slide": "^1.1.5" - } - }, - "node_modules/npx/node_modules/number-is-nan": { - "version": "1.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/once": { - "version": "1.4.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/npx/node_modules/os-homedir": { - "version": "1.0.2", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/os-locale": { - "version": "3.1.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/npx/node_modules/os-locale/node_modules/cross-spawn": { - "version": "6.0.5", - "inBundle": true, - "license": "MIT", - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/npx/node_modules/os-locale/node_modules/execa": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/npx/node_modules/os-locale/node_modules/get-stream": { - "version": "4.1.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/npx/node_modules/os-tmpdir": { - "version": "1.0.2", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/osenv": { - "version": "0.1.5", - "inBundle": true, - "license": "ISC", - "dependencies": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "node_modules/npx/node_modules/p-defer": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/p-finally": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/p-is-promise": { - "version": "2.1.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/npx/node_modules/p-limit": { - "version": "1.3.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/p-locate": { - "version": "2.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/p-try": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/package-json": { - "version": "4.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "got": "^6.7.1", - "registry-auth-token": "^3.0.1", - "registry-url": "^3.0.3", - "semver": "^5.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/path-exists": { - "version": "3.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/path-is-absolute": { - "version": "1.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/path-is-inside": { - "version": "1.0.2", - "inBundle": true, - "license": "(WTFPL OR MIT)" - }, - "node_modules/npx/node_modules/path-key": { - "version": "2.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/pify": { - "version": "3.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/prepend-http": { - "version": "1.0.4", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/pseudomap": { - "version": "1.0.2", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/pump": { - "version": "3.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/npx/node_modules/rc": { - "version": "1.2.8", - "inBundle": true, - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/npx/node_modules/registry-auth-token": { - "version": "3.4.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "rc": "^1.1.6", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/npx/node_modules/registry-url": { - "version": "3.1.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "rc": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/require-directory": { - "version": "2.1.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/require-main-filename": { - "version": "1.0.1", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/rimraf": { - "version": "2.7.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/npx/node_modules/safe-buffer": { - "version": "5.2.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npx/node_modules/semver": { - "version": "5.7.1", - "inBundle": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/npx/node_modules/semver-diff": { - "version": "2.1.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "semver": "^5.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/set-blocking": { - "version": "2.0.0", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/shebang-command": { - "version": "1.2.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/shebang-regex": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/signal-exit": { - "version": "3.0.2", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/string-width": { - "version": "2.1.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/strip-ansi": { - "version": "4.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/strip-eof": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/strip-json-comments": { - "version": "2.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npx/node_modules/supports-color": { - "version": "5.5.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npx/node_modules/term-size": { - "version": "1.2.0", - "inBundle": true, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "license": "MIT", - "dependencies": { - "execa": "^0.7.0" - }, "engines": { - "node": ">=4" + "node": ">= 0.10" } }, - "node_modules/npx/node_modules/timed-out": { - "version": "4.0.1", - "inBundle": true, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/npx/node_modules/unique-string": { - "version": "1.0.0", - "inBundle": true, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "license": "MIT" + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/jose": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz", + "integrity": "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==", "license": "MIT", - "dependencies": { - "crypto-random-string": "^1.0.0" - }, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/sponsors/panva" } }, - "node_modules/npx/node_modules/unzip-response": { - "version": "2.0.1", - "inBundle": true, - "license": "MIT", + "node_modules/jsdom": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-28.1.0.tgz", + "integrity": "sha512-0+MoQNYyr2rBHqO1xilltfDjV9G7ymYGlAUazgcDLQaUf8JDHbuGwsxN6U9qWaElZ4w1B2r7yEGIL3GdeW3Rug==", + "license": "MIT", + "dependencies": { + "@acemir/cssom": "^0.9.31", + "@asamuzakjp/dom-selector": "^6.8.1", + "@bramus/specificity": "^2.4.2", + "@exodus/bytes": "^1.11.0", + "cssstyle": "^6.0.1", + "data-urls": "^7.0.0", + "decimal.js": "^10.6.0", + "html-encoding-sniffer": "^6.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "parse5": "^8.0.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^6.0.0", + "undici": "^7.21.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^8.0.1", + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.0", + "xml-name-validator": "^5.0.0" + }, "engines": { - "node": ">=4" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } } }, - "node_modules/npx/node_modules/update-notifier": { - "version": "2.5.0", - "inBundle": true, + "node_modules/jsdom/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", "license": "BSD-2-Clause", - "dependencies": { - "boxen": "^1.2.1", - "chalk": "^2.0.1", - "configstore": "^3.0.0", - "import-lazy": "^2.1.0", - "is-ci": "^1.0.10", - "is-installed-globally": "^0.1.0", - "is-npm": "^1.0.0", - "latest-version": "^3.0.0", - "semver-diff": "^2.0.0", - "xdg-basedir": "^3.0.0" - }, "engines": { - "node": ">=4" + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/npx/node_modules/url-parse-lax": { - "version": "1.0.0", - "inBundle": true, + "node_modules/jsdom/node_modules/parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.0.tgz", + "integrity": "sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==", "license": "MIT", "dependencies": { - "prepend-http": "^1.0.1" + "entities": "^6.0.0" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/npx/node_modules/validate-npm-package-name": { - "version": "3.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "builtins": "^1.0.3" + "node_modules/jsdom/node_modules/whatwg-mimetype": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", + "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", + "license": "MIT", + "engines": { + "node": ">=20" } }, - "node_modules/npx/node_modules/which": { - "version": "1.3.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" }, - "node_modules/npx/node_modules/which-module": { - "version": "2.0.0", - "inBundle": true, - "license": "ISC" + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "license": "BSD-2-Clause" }, - "node_modules/npx/node_modules/widest-line": { - "version": "2.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "string-width": "^2.1.1" - }, + "node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=4" + "node": "20 || >=22" } }, - "node_modules/npx/node_modules/wrap-ansi": { - "version": "2.1.0", - "inBundle": true, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "license": "MIT", - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, - "node_modules/npx/node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "inBundle": true, + "node_modules/mdn-data": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", + "license": "CC0-1.0" + }, + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 0.8" } }, - "node_modules/npx/node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "inBundle": true, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", "license": "MIT", - "dependencies": { - "number-is-nan": "^1.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/npx/node_modules/wrap-ansi/node_modules/string-width": { - "version": "1.0.2", - "inBundle": true, - "license": "MIT", - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "engines": { - "node": ">=0.10.0" + "node": ">= 0.6" } }, - "node_modules/npx/node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "3.0.1", - "inBundle": true, - "license": "MIT", + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dependencies": { - "ansi-regex": "^2.0.0" + "mime-db": "1.52.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.6" } }, - "node_modules/npx/node_modules/wrappy": { - "version": "1.0.2", - "inBundle": true, - "license": "ISC" + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "license": "MIT" }, - "node_modules/npx/node_modules/write-file-atomic": { - "version": "2.4.3", - "inBundle": true, - "license": "ISC", - "dependencies": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, - "node_modules/npx/node_modules/xdg-basedir": { - "version": "3.0.0", - "inBundle": true, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", "license": "MIT", "engines": { - "node": ">=4" + "node": ">= 0.6" } }, - "node_modules/npx/node_modules/y18n": { - "version": "4.0.0", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/yallist": { - "version": "2.1.2", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npx/node_modules/yargs": { - "version": "11.1.1", - "inBundle": true, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", "license": "MIT", - "dependencies": { - "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.1.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^9.0.2" - } - }, - "node_modules/npx/node_modules/yargs-parser": { - "version": "9.0.2", - "inBundle": true, - "license": "ISC", - "dependencies": { - "camelcase": "^4.1.0" + "engines": { + "node": ">= 0.4.0" } }, - "node_modules/npx/node_modules/yargs/node_modules/y18n": { - "version": "3.2.1", - "inBundle": true, - "license": "ISC" - }, "node_modules/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -6177,12 +2170,6 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "node_modules/nwsapi": { - "version": "2.2.20", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.20.tgz", - "integrity": "sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==", - "license": "MIT" - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -6225,6 +2212,38 @@ "wrappy": "1" } }, + "node_modules/pac-proxy-agent": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", + "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", + "license": "MIT", + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.6", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "license": "MIT", + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/parse5": { "version": "7.2.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", @@ -6277,10 +2296,10 @@ "node": ">=8" } }, - "node_modules/path-to-regexp": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "license": "MIT" }, "node_modules/pkce-challenge": { @@ -6292,6 +2311,15 @@ "node": ">=16.20.0" } }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -6305,11 +2333,49 @@ "node": ">= 0.10" } }, + "node_modules/proxy-agent": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.6", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.1.0", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -6319,42 +2385,95 @@ "node": ">=6" } }, + "node_modules/puppeteer-core": { + "version": "24.37.5", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.37.5.tgz", + "integrity": "sha512-ybL7iE78YPN4T6J+sPLO7r0lSByp/0NN6PvfBEql219cOnttoTFzCWKiBOjstXSqi/OKpwae623DWAsL7cn2MQ==", + "license": "Apache-2.0", + "dependencies": { + "@puppeteer/browsers": "2.13.0", + "chromium-bidi": "14.0.0", + "debug": "^4.4.3", + "devtools-protocol": "0.0.1566079", + "typed-query-selector": "^2.12.0", + "webdriver-bidi-protocol": "0.4.1", + "ws": "^8.19.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.0.6" + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { - "node": ">=0.6" + "node": ">=0.10.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">=0.10.0" } }, - "node_modules/raw-body": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", - "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.6.3", - "unpipe": "1.0.0" - }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", "engines": { - "node": ">= 0.8" + "node": ">=0.10.0" } }, "node_modules/router": { @@ -6374,40 +2493,15 @@ } }, "node_modules/router/node_modules/path-to-regexp": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", - "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", "license": "MIT", - "engines": { - "node": ">=16" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/rrweb-cssom": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", - "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", - "license": "MIT" - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -6425,67 +2519,86 @@ "node": ">=v12.22.7" } }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", "license": "MIT", "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" + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/send/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", "license": "MIT", - "dependencies": { - "ms": "2.0.0" + "engines": { + "node": ">= 0.6" } }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/send/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "node_modules/send/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, "engines": { - "node": ">= 0.8" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", "license": "MIT", "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.19.0" + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/setprototypeof": { @@ -6586,36 +2699,175 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", + "license": "MIT", + "dependencies": { + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, + "node_modules/streamx": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", + "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", + "license": "MIT", + "dependencies": { + "events-universal": "^1.0.0", + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "license": "MIT" }, + "node_modules/tar-fs": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", + "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", + "license": "MIT", + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^4.0.1", + "bare-path": "^3.0.0" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/teex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", + "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", + "license": "MIT", + "optional": true, + "dependencies": { + "streamx": "^2.12.5" + } + }, + "node_modules/text-decoder": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz", + "integrity": "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==", + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, "node_modules/tldts": { - "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", - "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", + "version": "7.0.23", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.23.tgz", + "integrity": "sha512-ASdhgQIBSay0R/eXggAkQ53G4nTJqTXqC2kbaBbdDwM7SkjyZyO0OaaN1/FH7U/yCeqOHDwFO5j8+Os/IS1dXw==", "license": "MIT", "dependencies": { - "tldts-core": "^6.1.86" + "tldts-core": "^7.0.23" }, "bin": { "tldts": "bin/cli.js" } }, "node_modules/tldts-core": { - "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", - "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==", + "version": "7.0.23", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.23.tgz", + "integrity": "sha512-0g9vrtDQLrNIiCj22HSe9d4mLVG3g5ph5DZ8zCKBr4OtrspmNB6ss7hVyzArAeE88ceZocIEGkyW1Ime7fxPtQ==", "license": "MIT" }, "node_modules/toidentifier": { @@ -6627,47 +2879,86 @@ } }, "node_modules/tough-cookie": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", - "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz", + "integrity": "sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==", "license": "BSD-3-Clause", "dependencies": { - "tldts": "^6.1.32" + "tldts": "^7.0.5" }, "engines": { "node": ">=16" } }, "node_modules/tr46": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", - "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", + "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", "license": "MIT", "dependencies": { "punycode": "^2.3.1" }, "engines": { - "node": ">=18" + "node": ">=20" } }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", "license": "MIT", "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" }, "engines": { "node": ">= 0.6" } }, + "node_modules/type-is/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/typed-query-selector": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz", + "integrity": "sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==", + "license": "MIT" + }, "node_modules/typescript": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", - "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -6677,17 +2968,20 @@ } }, "node_modules/undici": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.0.tgz", - "integrity": "sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw==", + "version": "7.22.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.22.0.tgz", + "integrity": "sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==", + "license": "MIT", "engines": { - "node": ">=18.17" + "node": ">=20.18.1" } }, "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" + "version": "7.22.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.22.0.tgz", + "integrity": "sha512-RKZvifiL60xdsIuC80UY0dq8Z7DbJUV8/l2hOVbyZAxBzEeQU4Z58+4ZzJ6WN2Lidi9KzT5EbiGX+PI/UGYuRw==", + "dev": true, + "license": "MIT" }, "node_modules/unpipe": { "version": "1.0.0", @@ -6697,24 +2991,6 @@ "node": ">= 0.8" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -6736,19 +3012,27 @@ "node": ">=18" } }, + "node_modules/webdriver-bidi-protocol": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.4.1.tgz", + "integrity": "sha512-ARrjNjtWRRs2w4Tk7nqrf2gBI0QXWuOmMCx2hU+1jUt6d00MjMxURrhxhGbrsoiZKJrhTSTzbIrc554iKI10qw==", + "license": "Apache-2.0" + }, "node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", + "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==", "license": "BSD-2-Clause", "engines": { - "node": ">=12" + "node": ">=20" } }, "node_modules/whatwg-encoding": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", + "license": "MIT", "dependencies": { "iconv-lite": "0.6.3" }, @@ -6765,16 +3049,17 @@ } }, "node_modules/whatwg-url": { - "version": "14.2.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", - "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-16.0.1.tgz", + "integrity": "sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==", "license": "MIT", "dependencies": { - "tr46": "^5.1.0", - "webidl-conversions": "^7.0.0" + "@exodus/bytes": "^1.11.0", + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.1" }, "engines": { - "node": ">=18" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" } }, "node_modules/which": { @@ -6792,6 +3077,23 @@ "node": ">= 8" } }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -6799,9 +3101,9 @@ "license": "ISC" }, "node_modules/ws": { - "version": "8.18.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", - "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -6834,21 +3136,60 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "license": "MIT" }, - "node_modules/zod": { - "version": "3.24.1", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz", - "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==", - "funding": { - "url": "https://github.com/sponsors/colinhacks" + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" } }, - "node_modules/zod-to-json-schema": { - "version": "3.24.6", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz", - "integrity": "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==", + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "license": "ISC", - "peerDependencies": { - "zod": "^3.24.1" + "engines": { + "node": ">=12" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/zod": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", + "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/colinhacks" } } } diff --git a/package.json b/package.json index 920716e..066cf08 100644 --- a/package.json +++ b/package.json @@ -20,22 +20,23 @@ "test:both": "set MODE=both && node build/index.js" }, "dependencies": { - "@modelcontextprotocol/sdk": "^1.11.2", + "@modelcontextprotocol/sdk": "^1.27.1", "@types/axios": "^0.14.4", - "@types/cheerio": "^0.22.35", - "axios": "^1.7.9", - "cheerio": "^1.0.0", - "cors": "^2.8.5", - "express": "^4.18.2", + "@types/cheerio": "^1.0.0", + "axios": "^1.13.5", + "cheerio": "^1.2.0", + "cors": "^2.8.6", + "express": "^5.2.1", "https-proxy-agent": "^7.0.6", - "jsdom": "^26.1.0", - "npx": "^10.2.2" + "jsdom": "^28.1.0", + "puppeteer-core": "^24.37.5", + "zod": "^4.3.6" }, "devDependencies": { "@types/cors": "^2.8.19", - "@types/express": "^4.17.21", - "@types/jsdom": "^21.1.7", - "@types/node": "^20.17.10", - "typescript": "^5.3.3" + "@types/express": "^5.0.6", + "@types/jsdom": "^28.0.0", + "@types/node": "^25.3.1", + "typescript": "^5.9.3" } } diff --git a/src/config.ts b/src/config.ts index d8fae2c..9ab95dc 100644 --- a/src/config.ts +++ b/src/config.ts @@ -12,6 +12,10 @@ export interface AppConfig { corsOrigin: string; // Server configuration (determined by MODE env var: 'both', 'http', or 'stdio') enableHttpServer: boolean; + // 搜索结果描述最大长度(undefined = 不限制) + maxDescriptionLength?: number; + // 网络请求超时时间(毫秒) + requestTimeout: number; } // Read from environment variables or use defaults @@ -30,7 +34,11 @@ export const config: AppConfig = { corsOrigin: process.env.CORS_ORIGIN || '*', // Server configuration - determined by MODE environment variable // Modes: 'both' (default), 'http', 'stdio' - enableHttpServer: process.env.MODE ? ['both', 'http'].includes(process.env.MODE) : true + enableHttpServer: process.env.MODE ? ['both', 'http'].includes(process.env.MODE) : true, + // 搜索结果描述最大长度 + maxDescriptionLength: process.env.MAX_DESCRIPTION_LENGTH ? parseInt(process.env.MAX_DESCRIPTION_LENGTH, 10) : undefined, + // 网络请求超时时间(毫秒),默认 30 秒 + requestTimeout: process.env.REQUEST_TIMEOUT ? parseInt(process.env.REQUEST_TIMEOUT, 10) : 30000 }; // Valid search engines list diff --git a/src/engines/baidu/baidu.ts b/src/engines/baidu/baidu.ts index 13ce471..ea1c938 100644 --- a/src/engines/baidu/baidu.ts +++ b/src/engines/baidu/baidu.ts @@ -1,72 +1,80 @@ -import axios from 'axios'; import * as cheerio from 'cheerio'; import { SearchResult } from '../../types.js'; +import { getSharedBrowser, destroySharedBrowser } from '../shared/browser.js'; +import { config } from '../../config.js'; export async function searchBaidu(query: string, limit: number): Promise { - let allResults: SearchResult[] = []; - let pn = 0; + try { + const browser = await getSharedBrowser(); + let allResults: SearchResult[] = []; + let pn = 0; - while (allResults.length < limit) { - const response = await axios.get('https://www.baidu.com/s', { - params: { - wd: query, - pn: pn.toString(), - ie: "utf-8", - mod: "1", - isbd: "1", - isid: "f7ba1776007bcf9e", - oq: query, - tn: "88093251_62_hao_pg", - usm: "1", - fenlei: "256", - rsv_idx: "1", - rsv_pq: "f7ba1776007bcf9e", - rsv_t: "8179fxGiNMUh/0dXHrLsJXPlKYbkj9S5QH6rOLHY6pG6OGQ81YqzRTIGjjeMwEfiYQTSiTQIhCJj", - bs: query, - rsv_sid: undefined, - _ss: "1", - f4s: "1", - csor: "5", - _cr1: "30385", - }, - headers: { - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' + while (allResults.length < limit) { + const page = await browser.newPage(); + + const searchUrl = `https://www.baidu.com/s?wd=${encodeURIComponent(query)}&pn=${pn}&ie=utf-8`; + + try { + await page.goto(searchUrl, { waitUntil: 'networkidle2', timeout: config.requestTimeout }); + } catch (navErr: any) { + // 百度可能在导航时销毁 iframe(如天气小组件),回退到 domcontentloaded + if (navErr.message?.includes('frame was detached') || navErr.message?.includes('Navigating frame')) { + console.error('⚠️ Baidu frame detached during navigation, retrying with domcontentloaded...'); + await page.goto(searchUrl, { waitUntil: 'domcontentloaded', timeout: config.requestTimeout }); + } else { + throw navErr; + } } - }); + await new Promise(r => setTimeout(r, 1000)); - const $ = cheerio.load(response.data); - const results: SearchResult[] = []; + const html = await page.content(); + await page.close(); - $('#content_left').children().each((i, element) => { - const titleElement = $(element).find('h3'); - const linkElement = $(element).find('a'); - const snippetElement = $(element).find('.cos-row').first(); + const $ = cheerio.load(html); - if (titleElement.length && linkElement.length) { - const url = linkElement.attr('href'); - if (url && url.startsWith('http')) { - const snippetElementBaidu = $(element).find('.c-font-normal.c-color-text').first(); - const sourceElement = $(element).find('.cosc-source'); - results.push({ - title: titleElement.text(), - url: url, - description: snippetElementBaidu.attr('aria-label') || snippetElement.text().trim() || '', - source: sourceElement.text().trim() || '', - engine: 'baidu' - }); - } + // 检测百度安全验证页面 + const title = $('title').text(); + if (title.includes('安全验证')) { + console.error('⚠️ Baidu security verification detected, no results for this page.'); + break; } - }); - allResults = allResults.concat(results); + const results: SearchResult[] = []; + + $('#content_left').children().each((i, element) => { + const titleElement = $(element).find('h3'); + const linkElement = $(element).find('a'); + const snippetElement = $(element).find('.cos-row').first(); - if (results.length === 0) { - console.error('⚠️ No more results, ending early....'); - break; + if (titleElement.length && linkElement.length) { + const url = linkElement.attr('href'); + if (url && url.startsWith('http')) { + const snippetElementBaidu = $(element).find('.c-font-normal.c-color-text').first(); + const sourceElement = $(element).find('.cosc-source'); + results.push({ + title: titleElement.text(), + url: url, + description: snippetElementBaidu.attr('aria-label') || snippetElement.text().trim() || '', + source: sourceElement.text().trim() || '', + engine: 'baidu' + }); + } + } + }); + + allResults = allResults.concat(results); + + if (results.length === 0) { + console.error('⚠️ No more results, ending early....'); + break; + } + + pn += 10; } - pn += 10; + return allResults.slice(0, limit); + } catch (err) { + await destroySharedBrowser(); + throw err; } - - return allResults.slice(0, limit); // 截取最多 limit 个 } diff --git a/src/engines/bing/bing.ts b/src/engines/bing/bing.ts index bd16e5c..d0b1983 100644 --- a/src/engines/bing/bing.ts +++ b/src/engines/bing/bing.ts @@ -1,72 +1,112 @@ -import axios from 'axios'; import * as cheerio from 'cheerio'; import { SearchResult } from '../../types.js'; +import { getSharedBrowser, destroySharedBrowser } from '../shared/browser.js'; +import { config } from '../../config.js'; -export async function searchBing(query: string, limit: number): Promise { - let allResults: SearchResult[] = []; - let pn = 0; +/** + * 解码 Bing 重定向 URL,提取实际目标地址。 + * Bing URL 格式: https://www.bing.com/ck/a?...&u=a1 + * 参数 'u' 的值以 'a1' 开头,后接 Base64 编码的原始 URL。 + */ +function decodeBingUrl(bingUrl: string): string { + try { + const url = new URL(bingUrl); + const encodedUrl = url.searchParams.get('u'); + if (!encodedUrl) { + return bingUrl; + } + const base64Part = encodedUrl.substring(2); + const decodedUrl = Buffer.from(base64Part, 'base64').toString('utf-8'); + if (decodedUrl.startsWith('http')) { + return decodedUrl; + } + return bingUrl; + } catch { + return bingUrl; + } +} - while (allResults.length < limit) { - const response = await axios.get('https://www.bing.com/search', { - params: { - q: query, - first: 1 + pn * 10 - }, - headers: { - "authority": "www.bing.com", - "ect": "3g", - "pragma": "no-cache", - "sec-ch-ua-arch": "\"x86\"", - "sec-ch-ua-bitness": "\"64\"", - "sec-ch-ua-full-version": "\"112.0.5615.50\"", - "sec-ch-ua-full-version-list": "\"Chromium\";v=\"112.0.5615.50\", \"Google Chrome\";v=\"112.0.5615.50\", \"Not:A-Brand\";v=\"99.0.0.0\"", - "sec-ch-ua-model": "\"\"", - "sec-ch-ua-platform-version": "\"15.0.0\"", - "sec-fetch-user": "?1", - "upgrade-insecure-requests": "1", - "Cookie": "MUID=3727DBB14FD763511D80CDBD4ED262EF; MSPTC=5UlNf4UsLqV53oFqqdHiR26FwDDL8zSW3kC74kIJQfM; _EDGE_S=SID=132F08F578E06F832D931EE779E16E2D; MUIDB=3727DBB14FD763511D80CDBD4ED262EF; SRCHD=AF=NOFORM; SRCHUID=V=2&GUID=B3AFD0E41DB649E39803C690946C3B65&dmnchg=1; ak_bmsc=578AE2B7DA55FA9F332ADCDFBA0B9B64~000000000000000000000000000000~YAAQZCg0F9XLkYGXAQAAjywwkhxcD6Pm2nguBmpB14hnmCR3kz9Mfau5cZ7pwHxdU2Uog9+6hOkBmzpOV3UoTOhi52nB725xM7zN90mRDv0zQtJdO/llaKlt2zqTmB4F5kd+GzPjXLAN4Zmj4KwpAjLK1T4TexH/9WlQTkRamdJTKuR47IZWHHebqsbNqHoYncHhxICO9Rnu51vhlps/rrhPBtgPgbrQnDfr6YzAQWmSqc5g9hk03sM9nnWUyVbRV0ZVsgke7BCYX5V1JD5L0Zf8/FWdntBpjpd2IcmehBz38ChGThPrBEWNCZQbCS6lE4OaQanrrdmBHf/r5YEf2LeIqZy0bJGIiSQaSh6d7KFO2haTQk/JscZAs+V5kNsAOxIGreRve+E=; _UR=QS=0&TQS=0&Pn=0; BFBUSR=BFBHP=0; SRCHUSR=DOB=20250621&DS=1; _Rwho=u=d&ts=2025-06-21; ipv6=hit=1750507922628&t=4; BFPRResults=FirstPageUrls=C5E678E900F98310F0D3DB1F3EB96D99%2CB5A20FAE72B0C3019A56409EAC7AF3FB%2C7A44A77FF42EDF11CC9BF5CFE08B179A%2C6ED615E5E634BD5AFC7BB2A0A77F8FF8%2CA993E7AAF4890BEC06882621CA376D00%2C49CF0FC3C203D5E918A76258506B0CF4%2C7F03D5026C1D046F66B11D525095BF8B%2C058BB67A6B7F15E58D3A19B897BC57F8%2C1B886024FDE703428D24A41AFA1E62AF%2C5A8B56DC0AE03A8B94643DEA2A22DBAC&FPIG=05F126AA95514CF5AD5E33E4AEBA474D; _HPVN=CS=eyJQbiI6eyJDbiI6MSwiU3QiOjAsIlFzIjowLCJQcm9kIjoiUCJ9LCJTYyI6eyJDbiI6MSwiU3QiOjAsIlFzIjowLCJQcm9kIjoiSCJ9LCJReiI6eyJDbiI6MSwiU3QiOjAsIlFzIjowLCJQcm9kIjoiVCJ9LCJBcCI6dHJ1ZSwiTXV0ZSI6dHJ1ZSwiTGFkIjoiMjAyNS0wNi0yMVQwMDowMDowMFoiLCJJb3RkIjowLCJHd2IiOjAsIlRucyI6MCwiRGZ0IjpudWxsLCJNdnMiOjAsIkZsdCI6MCwiSW1wIjoxNSwiVG9ibiI6MH0=; _C_ETH=1; _RwBf=r=0&ilt=15&ihpd=1&ispd=14&rc=36&rb=0&rg=200&pc=36&mtu=0&rbb=0&clo=0&v=15&l=2025-06-21T07:00:00.0000000Z&lft=0001-01-01T00:00:00.0000000&aof=0&ard=0001-01-01T00:00:00.0000000&rwdbt=0&rwflt=0&rwaul2=0&g=&o=2&p=&c=&t=0&s=0001-01-01T00:00:00.0000000+00:00&ts=2025-06-21T11:36:08.7064260+00:00&rwred=0&wls=&wlb=&wle=&ccp=&cpt=&lka=0&lkt=0&aad=0&TH=&cid=0&gb=; _SS=SID=132F08F578E06F832D931EE779E16E2D&R=36&RB=0&GB=0&RG=200&RP=36; SRCHHPGUSR=SRCHLANG=zh-Hans&IG=63A0A44F5D2F4499AD165A366D073C03&DM=0&BRW=N&BRH=T&CW=1202&CH=1289&SCW=1185&SCH=2279&DPR=1.0&UTC=480&HV=1750505768&HVE=notFound&WTS=63886101120&PV=15.0.0&PRVCW=1202&PRVCH=1289&EXLTT=13; SRCHHPGUSR=SRCHLANG=en&IG=9A53F826E9C9432497327CA995144E14&DM=0&BRW=N&BRH=T&CW=1202&CH=1289&SCW=1185&SCH=2279&DPR=1.0&UTC=480&HV=1750505768&HVE=notFound&WTS=63886101120&PV=15.0.0&PRVCW=1202&PRVCH=1289&EXLTT=13", - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", - "Accept": "*/*", - "Host": "cn.bing.com", - "Connection": "keep-alive" +function parsePageResults(html: string): SearchResult[] { + const $ = cheerio.load(html); + const results: SearchResult[] = []; + $('#b_results h2').each((i, element) => { + const linkElement = $(element).find('a').first(); + if (linkElement.length) { + const rawUrl = linkElement.attr('href'); + if (rawUrl && rawUrl.startsWith('http')) { + const url = decodeBingUrl(rawUrl); + const parentLi = $(element).closest('li'); + const snippetElement = parentLi.find('p').first(); + const sourceElement = parentLi.find('.b_tpcn'); + results.push({ + title: linkElement.text().trim(), + url: url, + description: snippetElement.text().trim() || '', + source: sourceElement.text().trim() || '', + engine: 'bing' + }); } - }); + } + }); + return results; +} - const $ = cheerio.load(response.data); - const results: SearchResult[] = []; +export async function searchBing(query: string, limit: number): Promise { + try { + const browser = await getSharedBrowser(); + const page = await browser.newPage(); - $('#b_content').children() - .find('#b_results').children() - .each((i, element) => { - const titleElement = $(element).find('h2'); - const linkElement = $(element).find('a'); - const snippetElement = $(element).find('p').first(); + try { + const searchUrl = `https://www.bing.com/search?q=${encodeURIComponent(query)}`; + await page.goto(searchUrl, { waitUntil: 'networkidle2', timeout: config.requestTimeout }); - if (titleElement.length && linkElement.length) { - const url = linkElement.attr('href'); - if (url && url.startsWith('http')) { + // cn.bing.com 等本地化版本可能异步渲染搜索结果, + // networkidle2 无法保证 DOM 已就绪,需要显式等待结果选择器。 + try { + await page.waitForSelector('#b_results .b_algo', { timeout: 10000 }); + } catch { + // 可能确实没有结果,或者 Bing 使用了不同的页面结构,继续尝试解析 + console.warn('[bing] 等待搜索结果选择器 #b_results .b_algo 超时,页面 URL:', page.url()); + } - const sourceElement = $(element).find('.b_tpcn'); - results.push({ - title: titleElement.text(), - url: url, - description: snippetElement.text().trim() || '', - source: sourceElement.text().trim() || '', - engine: 'bing' - }); - } - } - }); + let allResults = parsePageResults(await page.content()); - allResults = allResults.concat(results); + // 如果首次解析为空,可能是异步渲染还没完成(cn.bing.com 特有的延迟), + // 或者出现了 cookie 同意弹窗等遮挡,尝试再等待一次。 + if (allResults.length === 0) { + console.warn('[bing] 首次解析返回 0 条结果,等待 3 秒后重试...'); + await new Promise(r => setTimeout(r, 3000)); + allResults = parsePageResults(await page.content()); + } - if (results.length === 0) { - console.error('⚠️ No more results, ending early....'); - break; - } + while (allResults.length < limit) { + const nextLink = await page.$('.sb_pagN'); + if (!nextLink) break; + // Bing 翻页可能用完整导航或 AJAX,两种方式都要兼容 + const navPromise = page.waitForNavigation({ waitUntil: 'networkidle2', timeout: config.requestTimeout }).catch(() => {}); + await nextLink.click(); + await navPromise; + try { + await page.waitForSelector('#b_results .b_algo', { timeout: 10000 }); + } catch { + // 翻页后如果超时,继续尝试解析 + } + const pageResults = parsePageResults(await page.content()); + if (pageResults.length === 0) break; + allResults = allResults.concat(pageResults); + } - pn += 1; + const finalResults = allResults.slice(0, limit); + if (finalResults.length === 0) { + const finalUrl = page.url(); + console.warn(`[bing] 搜索返回 0 条结果。最终 URL: ${finalUrl}。页面可能出现了验证码、Cookie 同意弹窗,或 HTML 结构已变更。`); + } + return finalResults; + } finally { + await page.close(); + } + } catch (err) { + await destroySharedBrowser(); + throw err; } - - return allResults.slice(0, limit); // 截取最多 limit 个 } diff --git a/src/engines/brave/brave.ts b/src/engines/brave/brave.ts index bd06643..64cdccc 100644 --- a/src/engines/brave/brave.ts +++ b/src/engines/brave/brave.ts @@ -1,7 +1,7 @@ import axios from 'axios'; import * as cheerio from 'cheerio'; import { SearchResult } from '../../types.js'; -import {getProxyUrl} from "../../config.js"; +import {getProxyUrl, config} from "../../config.js"; import {HttpsProxyAgent} from "https-proxy-agent"; export async function searchBrave(query: string, limit: number): Promise { @@ -39,7 +39,7 @@ export async function searchBrave(query: string, limit: number): Promise { let allResults: SearchResult[] = []; @@ -8,6 +9,7 @@ export async function searchCsdn(query: string, limit: number): Promise { @@ -10,7 +11,8 @@ export async function fetchCsdnArticle(url: string): Promise<{ content: string } 'Connection': 'keep-alive', 'Cookie': 'https_waf_cookie=771a8075-77ae-4b2cdf3bda08cd28ad372861867be773d8c1; uuid_tt_dd=10_20283045860-1751096847125-425142; dc_session_id=10_1751096847125.891975; waf_captcha_marker=318c5c7f316f665febdb746a58e039a681a94708df7a26376ed47720663cd99d', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36', - } + }, + timeout: config.requestTimeout }); const $ = cheerio.load(response.data); diff --git a/src/engines/duckduckgo/searchDuckDuckGo.ts b/src/engines/duckduckgo/searchDuckDuckGo.ts index 46780a2..d6c0ac3 100644 --- a/src/engines/duckduckgo/searchDuckDuckGo.ts +++ b/src/engines/duckduckgo/searchDuckDuckGo.ts @@ -2,7 +2,17 @@ import axios from 'axios'; import * as cheerio from 'cheerio'; import {HttpsProxyAgent} from 'https-proxy-agent'; import {SearchResult} from "../../types.js"; -import {getProxyUrl} from "../../config.js"; +import {getProxyUrl, config} from "../../config.js"; + + +/** 从错误对象提取简短消息(处理 AxiosError/AggregateError message 为空的情况) */ +function errMsg(error: unknown): string { + if (axios.isAxiosError(error)) { + return [error.code, error.message, error.response?.status && `HTTP ${error.response.status}`].filter(Boolean).join(' - ') || 'Unknown AxiosError'; + } + if (error instanceof Error && error.message) return error.message; + return String(error) || 'Unknown error'; +} /** @@ -23,11 +33,16 @@ export async function searchDuckDuckGo(query: string, limit: number): Promise 0) { return results; } + console.warn('[duckduckgo] 预加载 URL 方法返回 0 条结果,尝试 HTML 方法...'); } catch (error) { - console.warn('预加载URL方法失败,尝试HTML方法:', error); + console.warn('预加载URL方法失败,尝试HTML方法:', errMsg(error)); } - return await searchDuckDuckGoHtml(query, limit, effectiveProxyUrl); + const htmlResults = await searchDuckDuckGoHtml(query, limit, effectiveProxyUrl); + if (htmlResults.length === 0) { + console.warn('[duckduckgo] 预加载和 HTML 两种方法均返回 0 条结果。查询可能过于具体,或 DuckDuckGo 阻止了请求。'); + } + return htmlResults; } /** @@ -66,7 +81,7 @@ export async function searchDuckDuckGo(query: string, limit: number): Promise( `https://exa.ai/search/api/search-fast`, data, - requestOptions + { ...requestOptions, timeout: config.requestTimeout } ); const apiResults = response.data.results; @@ -82,11 +82,10 @@ export async function searchExa(query: string, limit: number): Promise 'Accept': 'application/vnd.github.v3.raw', 'User-Agent': 'GitHub-README-Fetcher/1.0' }, - timeout: 10000, + timeout: config.requestTimeout, validateStatus: (status) => status === 200 }); diff --git a/src/engines/juejin/fetchJuejinArticle.ts b/src/engines/juejin/fetchJuejinArticle.ts index 082a26e..bdeae32 100644 --- a/src/engines/juejin/fetchJuejinArticle.ts +++ b/src/engines/juejin/fetchJuejinArticle.ts @@ -1,5 +1,6 @@ import axios from 'axios'; import * as cheerio from 'cheerio'; +import { config } from '../../config.js'; export async function fetchJuejinArticle(url: string): Promise<{ content: string }> { try { @@ -21,7 +22,7 @@ export async function fetchJuejinArticle(url: string): Promise<{ content: string 'accept-language': 'zh-CN,zh;q=0.9', 'priority': 'u=0, i' }, - timeout: 30000, + timeout: config.requestTimeout, decompress: true }); @@ -68,7 +69,8 @@ export async function fetchJuejinArticle(url: string): Promise<{ content: string return { content }; } catch (error) { - console.error('❌ 获取掘金文章失败:', error); - throw new Error(`获取掘金文章失败: ${error instanceof Error ? error.message : '未知错误'}`); + const msg = error instanceof Error ? error.message : String(error); + console.error(`❌ 获取掘金文章失败: ${msg}`); + throw new Error(`获取掘金文章失败: ${msg}`); } } diff --git a/src/engines/juejin/juejin.ts b/src/engines/juejin/juejin.ts index e29edf7..761c320 100644 --- a/src/engines/juejin/juejin.ts +++ b/src/engines/juejin/juejin.ts @@ -1,5 +1,6 @@ import axios from 'axios'; import { SearchResult } from '../../types.js'; +import { config } from '../../config.js'; interface JuejinSearchResponse { err_no: number; @@ -44,6 +45,7 @@ export async function searchJuejin(query: string, limit: number): Promise('https://api.juejin.cn/search_api/v1/search', { + timeout: config.requestTimeout, params: { aid: '2608', uuid: '7259393293459605051', @@ -79,17 +81,18 @@ export async function searchJuejin(query: string, limit: number): Promise { + const results: SearchResult[] = responseData.data + .filter((item) => item.result_model?.article_info && item.result_model?.author_user_info) + .map((item) => { const { result_model, title_highlight, content_highlight } = item; const { article_info, author_user_info, category, tags } = result_model; // 移除HTML标签的高亮标记 - const cleanTitle = title_highlight.replace(/<\/?em>/g, ''); - const cleanContent = content_highlight.replace(/<\/?em>/g, ''); + const cleanTitle = (title_highlight || article_info.title || '').replace(/<\/?em>/g, ''); + const cleanContent = (content_highlight || article_info.brief_content || '').replace(/<\/?em>/g, ''); - // 构建描述信息 - const tagNames = tags.map(tag => tag.tag_name).join(', '); - const description = `${cleanContent} | 分类: ${category.category_name} | 标签: ${tagNames} | 👍 ${article_info.digg_count} | 👀 ${article_info.view_count}`; + const tagNames = (tags || []).map(tag => tag.tag_name).join(', '); + const description = `${cleanContent} | 分类: ${category?.category_name ?? ''} | 标签: ${tagNames} | 👍 ${article_info.digg_count} | 👀 ${article_info.view_count}`; return { title: cleanTitle, @@ -104,22 +107,21 @@ export async function searchJuejin(query: string, limit: number): Promise { - const match = url.match(/\/topic\/(\d+)/); + // 同时支持 /topic/123 和 /t/slug/123 两种 URL 格式 + const match = url.match(/(?:\/topic\/|\/)t\/(?:[^\/]+\/)?(\d+)/) || url.match(/\/topic\/(\d+)/); const topicId = match ? match[1] : null; if (!topicId) { @@ -12,26 +14,10 @@ export async function fetchLinuxDoArticle(url: string): Promise<{ content: strin const response = await axios.get(apiUrl, { headers: { - 'accept': 'application/json, text/javascript, */*; q=0.01', - 'accept-language': 'zh-CN,zh;q=0.9', - 'cache-control': 'no-cache', - 'discourse-track-view': 'true', - 'discourse-track-view-topic-id': `${topicId}`, - 'pragma': 'no-cache', - 'referer': 'https://linux.do/search', - 'sec-ch-ua': '"Chromium";v="112", "Google Chrome";v="112", "Not:A-Brand";v="99"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', - 'sec-fetch-dest': 'empty', - 'sec-fetch-mode': 'cors', - 'sec-fetch-site': 'same-origin', - 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36', - 'x-csrf-token': 'K7YORqytPH8vZTM48iHLitfzv4NfU9GuiL1992MKuIBoviOCHyJk_w0LvTkfsX2bjn8ueXKzIGU8Uf8tzoxldg', - 'x-requested-with': 'XMLHttpRequest', - 'Cookie': '_ga=GA1.1.1014556084.1750571986; cf_clearance=OHwsuY8kOismHG8rBN1tCKczIEyTdoJrMPH65aPVUSI-1750571989-1.2.1.1-uJ4vrRUBXQtFG8Ws7JrPw0VNT8_YWVWOz1GSvHyAWTCUPPC8PNqnKApl9hVhLHHs4kB.sQ4B0V54VEwG.RT23ewifTx0rifGNIVItA1Tt5Sq1M78h7sqlwaW7p0vWYuAasaSwcZLKElbcwIxDGd4_EU44Lss.jIl0p9PYPa9QWlUCtbwHISkR8lt8zHtX_YIFrU25pjsHLkLqzYgk7mpmEwAaryi4wgxoc7R0u_FqP5kD1Fq4t559mXPdvj3H23004H12XYT95hHNudrfmHUbO6yLzrspsmV0rdUxJHLwCtI_0aK6JvrQNGJpU13_XS0Q8R_WKOLYrVgHLC_wmg_YOJJ2tMRkJFt_yV2pHV0JPLCvN5I986ooXiLXkVAWvNQ; __stripe_mid=45e0bc73-88a1-4392-9a8e-56b3ad60d5017557f5; __stripe_sid=23ed10a8-f6f4-4cd8-948b-386cb239067ad435dc; _ga_1X49KS6K0M=GS2.1.s1750571986$o1$g1$t1750571999$j47$l0$h1911122445', - 'Host': 'linux.do', - 'Connection': 'keep-alive' - } + 'accept': 'application/json', + 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + }, + timeout: config.requestTimeout }); const cookedHtml = response.data?.post_stream?.posts?.[0]?.cooked || ''; diff --git a/src/engines/linuxdo/linuxdo.ts b/src/engines/linuxdo/linuxdo.ts index e5115ff..be52e9c 100644 --- a/src/engines/linuxdo/linuxdo.ts +++ b/src/engines/linuxdo/linuxdo.ts @@ -1,99 +1,7 @@ -import axios from 'axios'; import {SearchResult} from '../../types.js'; import { config } from '../../config.js'; import {searchDuckDuckGo} from "../duckduckgo/index.js"; -import * as cheerio from 'cheerio'; - -async function searchBingForLinuxDo(query: string, limit: number): Promise { - let allResults: SearchResult[] = []; - let pn = 0; - // Format query for URL - const encodedQuery = encodeURIComponent(query); - - try { - while (allResults.length < limit) { - const response = await axios.get('https://cn.bing.com/search', { - params: { - "q": query, - "qs": "n", - "sp": "-1", - "lq": "0", - "pq": query, - "sc": "1-26", - "sk": "", - "cvid": "83A1CA7981304D6D9DC6924C92C248C9", - "FPIG": "5A297328992C4FB8BEED24CB159DD092", - "first": 1 + pn * 10, - "FORM": "PERE", - "rdr": "1", - "rdrig": "5BE6670756A24EA5A4274EB2A47D978D" - }, - headers: { - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", - "Connection": "keep-alive", - "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", - "Accept-Encoding": "gzip, deflate, br", - "ect": "4g", - "sec-ch-ua": "\"Chromium\";v=\"112\", \"Google Chrome\";v=\"112\", \"Not:A-Brand\";v=\"99\"", - "sec-ch-ua-mobile": "?0", - "sec-ch-ua-full-version": "\"112.0.5615.50\"", - "sec-ch-ua-arch": "\"x86\"", - "sec-ch-ua-platform": "\"Windows\"", - "sec-ch-ua-platform-version": "\"15.0.0\"", - "sec-ch-ua-model": "\"\"", - "sec-ch-ua-bitness": "\"64\"", - "sec-ch-ua-full-version-list": "\"Chromium\";v=\"112.0.5615.50\", \"Google Chrome\";v=\"112.0.5615.50\", \"Not:A-Brand\";v=\"99.0.0.0\"", - "upgrade-insecure-requests": "1", - "sec-fetch-site": "same-origin", - "sec-fetch-mode": "navigate", - "sec-fetch-dest": "document", - "referer": `https://cn.bing.com/search?q=${encodedQuery}&qs=n&sp=-1&lq=0&pq=${encodedQuery}&sc=1-26&sk=&cvid=83A1CA7981304D6D9DC6924C92C248C9&FPIG=5A297328992C4FB8BEED24CB159DD092&first=11&FORM=PERE`, - "accept-language": "zh-CN,zh;q=0.9", - "Cookie": "MUID=296FAEFA1CB065372DBFB8DB1D6264B0; MUIDB=296FAEFA1CB065372DBFB8DB1D6264B0; _EDGE_S=F=1&SID=063A15C99EE5624608BF03E89F3763A1; _EDGE_V=1; SRCHD=AF=NOFORM; SRCHUID=V=2&GUID=5C95B3592BB9427D94A15ACCB93B2998&dmnchg=1; _Rwho=u=d&ts=2025-07-06; ipv6=hit=1751775967739&t=4; USRLOC=HS=1&ELOC=LAT=23.0211181640625|LON=113.73304748535156|N=%E4%B8%9C%E8%8E%9E%E5%B8%82%EF%BC%8C%E5%B9%BF%E4%B8%9C%E7%9C%81|ELT=4|; BFPRResults=FirstPageUrls=B0D24EBFA8A0B66D6B071D854B69DC44%2C20426A336B6E4CF57DE0D0DD3484549D%2C9BF59C5A66BB498707BDEE26787183B3%2C4BD56F463CDE1E98954C975164097F6F%2C0F9C9A380F681662D573A082BEE6F471%2C8ED94F5FBF7A57786DE0FECB10C3D613%2C23FB8C1D9A41145741724F52CB242134%2CBD2D8F53469372B7D64F7AEF3D7F642D%2C6D9A9E581F375A9E57BF5A9599101CD5%2C8FC7081B6D04C85C644E9E41D523F4A0&FPIG=5A297328992C4FB8BEED24CB159DD092; SRCHUSR=DOB=20250706&DS=1; _RwBf=r=0&ilt=10&ihpd=0&ispd=10&rc=30&rb=0&rg=200&pc=27&mtu=0&rbb=0&clo=0&v=10&l=2025-07-05T07:00:00.0000000Z&lft=0001-01-01T00:00:00.0000000&aof=0&ard=0001-01-01T00:00:00.0000000&rwdbt=0&rwflt=0&rwaul2=0&g=&o=2&p=&c=&t=0&s=0001-01-01T00:00:00.0000000+00:00&ts=2025-07-06T04:16:43.3231859+00:00&rwred=0&wls=&wlb=&wle=&ccp=&cpt=&lka=0&lkt=0&aad=0&TH=&cid=0&gb=; _SS=SID=063A15C99EE5624608BF03E89F3763A1&R=30&RB=0&GB=0&RG=200&RP=27; SRCHHPGUSR=SRCHLANG=zh-Hans&PV=15.0.0&BZA=0&BRW=XW&BRH=M&CW=1707&CH=809&SCW=1691&SCH=1685&DPR=1.5&UTC=480&PRVCW=1707&PRVCH=809&HV=1751775699&HVE=CfDJ8Inh5QCoSQBNls38F2rbEpRMaCs0odiEKdnprhQV_w0a8_NuQurksG4JGF0rBdUFR2yGWPBo6wf3uOSO2p1l-Y8XcVCroAmqnrOsA1QCo3OSPJl7M38jS2gXSuJk8XX-qNBkwJmrKmfmGnVmG3kTuHL1a5gIpkLuYYB9-DlPnVHAE8tfBgro5p7vESusk8fsWA&EXLTT=11&DM=0" - } - }); - - const $ = cheerio.load(response.data); - const results: SearchResult[] = []; - - $('#b_content').children() - .find('#b_results').children() - .each((i, element) => { - const titleElement = $(element).find('h2'); - const linkElement = $(element).find('a'); - const snippetElement = $(element).find('p').first(); - - if (titleElement.length && linkElement.length) { - const url = linkElement.attr('href'); - if (url && url.startsWith('http') && url.includes('linux.do')) { - const sourceElement = $(element).find('.b_tpcn'); - results.push({ - title: titleElement.text(), - url: url, - description: snippetElement.text().trim() || '', - source: 'linux.do', - engine: 'bing' - }); - } - } - }); - - allResults = allResults.concat(results); - - if (results.length === 0) { - console.error('⚠️ No more results from Bing, ending early....'); - break; - } - - pn += 1; - } - - return allResults.slice(0, limit); - } catch (error: any) { - console.error('❌ Bing search failed:', error.message || error); - return []; - } -} +import {searchBing} from "../bing/index.js"; export async function searchLinuxDo(query: string, limit: number): Promise { @@ -108,10 +16,10 @@ export async function searchLinuxDo(query: string, limit: number): Promise { result.source = 'linux.do'; - // Keep the original engine info }); return filteredResults.slice(0, limit); diff --git a/src/engines/shared/browser.ts b/src/engines/shared/browser.ts new file mode 100644 index 0000000..abadae2 --- /dev/null +++ b/src/engines/shared/browser.ts @@ -0,0 +1,346 @@ +/** + * 全局共享的 Puppeteer 浏览器管理模块。 + * 所有需要真实浏览器环境的搜索引擎(Bing、Baidu 等)共用同一个浏览器实例。 + */ +import puppeteer, { type Browser } from 'puppeteer-core'; +import { existsSync, mkdtempSync, rmSync } from 'fs'; +import { tmpdir } from 'os'; +import { join } from 'path'; +import { spawn, execFileSync } from 'child_process'; +import { createServer } from 'net'; + +let cachedBrowserPath: string | null = null; + +function getBrowserPath(): string { + if (cachedBrowserPath) return cachedBrowserPath; + + const candidates: string[] = []; + + // Windows 硬编码常见路径(MCP 环境下环境变量可能缺失时的后备方案) + candidates.push('C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe'); + candidates.push('C:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe'); + candidates.push('C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe'); + candidates.push('C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'); + + // 基于环境变量的路径 + const pf86 = process.env['PROGRAMFILES(X86)']; + const pf = process.env['PROGRAMFILES']; + const localAppData = process.env['LOCALAPPDATA']; + if (pf86) { + candidates.push(pf86 + '\\Microsoft\\Edge\\Application\\msedge.exe'); + candidates.push(pf86 + '\\Google\\Chrome\\Application\\chrome.exe'); + } + if (pf) { + candidates.push(pf + '\\Microsoft\\Edge\\Application\\msedge.exe'); + candidates.push(pf + '\\Google\\Chrome\\Application\\chrome.exe'); + } + if (localAppData) { + candidates.push(localAppData + '\\Google\\Chrome\\Application\\chrome.exe'); + } + + // Linux/macOS 路径 + candidates.push('/usr/bin/google-chrome', '/usr/bin/chromium-browser', '/usr/bin/chromium', '/usr/bin/microsoft-edge'); + candidates.push('/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'); + candidates.push('/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge'); + + const unique = [...new Set(candidates)]; + for (const p of unique) { + if (existsSync(p)) { + console.error(`[browser] Found browser: ${p}`); + cachedBrowserPath = p; + return p; + } + } + throw new Error('未找到 Chromium 内核浏览器,请安装 Chrome 或 Edge。'); +} + +/** 查找可用的 TCP 端口 */ +function findFreePort(): Promise { + return new Promise((resolve, reject) => { + const srv = createServer(); + srv.listen(0, '127.0.0.1', () => { + const addr = srv.address(); + if (addr && typeof addr === 'object') { + const port = addr.port; + srv.close(() => resolve(port)); + } else { + srv.close(() => reject(new Error('Could not determine port'))); + } + }); + srv.on('error', reject); + }); +} + +interface BrowserSession { + browser: Browser; + tempDir: string; + browserPid?: number; +} + +let cachedSession: BrowserSession | null = null; +let cleanupRegistered = false; + +async function launchBrowser(): Promise { + const browserPath = getBrowserPath(); + const tempDir = mkdtempSync(join(tmpdir(), 'mcp-search-')); + const port = await findFreePort(); + + const args = [ + `--remote-debugging-port=${port}`, + `--user-data-dir=${tempDir}`, + '--no-sandbox', + '--disable-setuid-sandbox', + '--disable-gpu', + '--disable-dev-shm-usage', + '--disable-extensions', + '--no-first-run', + '--no-default-browser-check', + '--disable-blink-features=AutomationControlled', + // 使用 GUI 模式(非 headless)以避免 Bing 等搜索引擎的反自动化检测, + // 通过将窗口移到屏幕外来隐藏 + '--window-position=-32000,-32000', + '--window-size=1,1', + ]; + + console.error(`[browser] Spawning browser on port ${port}, profile: ${tempDir}`); + + let browserPid: number | undefined; + + if (process.platform === 'win32') { + // 在一个独立的不可见 Win32 Desktop 上启动浏览器。 + // 通过 CreateProcessW + STARTUPINFO.lpDesktop 直接指定桌面, + // 子进程自动继承父进程的桌面,因此 Edge 的所有子进程(GPU、渲染器等) + // 都在隐藏桌面上运行,用户桌面上不会出现任何窗口。 + const desktopName = `mcp-search-${Date.now()}`; + // 安全说明:cmdLine 中的 browserPath 来自 getBrowserPath() 的硬编码路径列表, + // args 全部是内部生成的常量,desktopName 是时间戳——均无外部输入,不存在注入风险。 + // 下方 replace(/'/g, "''") 是 PowerShell 单引号字符串的标准转义,作为防御性编码。 + const cmdLine = `"${browserPath}" ${args.join(' ')}`; + const psScript = ` +Add-Type @" +using System; +using System.Runtime.InteropServices; + +public class HiddenLauncher { + [DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Unicode)] + static extern IntPtr CreateDesktopW(string lpszDesktop, IntPtr lpszDevice, + IntPtr pDevmode, int dwFlags, uint dwDesiredAccess, IntPtr lpsa); + + [DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode)] + static extern bool CreateProcessW(string lpApp, string lpCmd, + IntPtr lpProcAttr, IntPtr lpThreadAttr, bool bInherit, uint dwFlags, + IntPtr lpEnv, string lpDir, ref STARTUPINFOW si, out PROCESS_INFORMATION pi); + + [DllImport("kernel32.dll", SetLastError=true)] + static extern bool DuplicateHandle(IntPtr hSourceProcess, IntPtr hSourceHandle, + IntPtr hTargetProcess, out IntPtr lpTargetHandle, + uint dwDesiredAccess, bool bInheritHandle, uint dwOptions); + + [DllImport("kernel32.dll")] + static extern IntPtr GetCurrentProcess(); + + [DllImport("kernel32.dll", SetLastError=true)] + static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInherit, int dwProcId); + + [DllImport("kernel32.dll")] + static extern bool CloseHandle(IntPtr hObject); + + [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] + struct STARTUPINFOW { + public int cb; public string lpReserved; public string lpDesktop; + public string lpTitle; public int dwX; public int dwY; + public int dwXSize; public int dwYSize; public int dwXCountChars; + public int dwYCountChars; public int dwFillAttribute; public int dwFlags; + public short wShowWindow; public short cbReserved2; + public IntPtr lpReserved2; public IntPtr hStdInput; + public IntPtr hStdOutput; public IntPtr hStdError; + } + + [StructLayout(LayoutKind.Sequential)] + struct PROCESS_INFORMATION { + public IntPtr hProcess; public IntPtr hThread; + public int dwProcessId; public int dwThreadId; + } + + const uint GENERIC_ALL = 0x10000000; + const uint PROCESS_DUP_HANDLE = 0x0040; + const uint DUPLICATE_SAME_ACCESS = 0x0002; + + public static int Launch(string cmdLine, string desktopName) { + IntPtr hDesk = CreateDesktopW(desktopName, IntPtr.Zero, IntPtr.Zero, + 0, GENERIC_ALL, IntPtr.Zero); + if (hDesk == IntPtr.Zero) + throw new Exception("CreateDesktop failed: " + + Marshal.GetLastWin32Error()); + + var si = new STARTUPINFOW(); + si.cb = Marshal.SizeOf(si); + si.lpDesktop = desktopName; + + PROCESS_INFORMATION pi; + if (!CreateProcessW(null, cmdLine, IntPtr.Zero, IntPtr.Zero, + false, 0, IntPtr.Zero, null, ref si, out pi)) + throw new Exception("CreateProcess failed: " + + Marshal.GetLastWin32Error()); + + // 将桌面句柄复制到浏览器进程中,使其持有对桌面的引用。 + // 这样即使当前进程(PowerShell)退出,桌面也不会被销毁。 + IntPtr hBrowserProc = OpenProcess(PROCESS_DUP_HANDLE, false, pi.dwProcessId); + if (hBrowserProc != IntPtr.Zero) { + IntPtr dupHandle; + DuplicateHandle(GetCurrentProcess(), hDesk, + hBrowserProc, out dupHandle, + 0, false, DUPLICATE_SAME_ACCESS); + CloseHandle(hBrowserProc); + } + + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + + return pi.dwProcessId; + } +} +"@ +[HiddenLauncher]::Launch('${cmdLine.replace(/'/g, "''")}', '${desktopName}')`; + try { + const output = execFileSync('powershell.exe', [ + '-NoProfile', '-NonInteractive', '-Command', psScript, + ], { encoding: 'utf8', windowsHide: true, timeout: 15000 }); + browserPid = parseInt(output.trim()); + console.error(`[browser] Browser started on hidden desktop "${desktopName}", PID: ${browserPid}`); + } catch (err: any) { + try { rmSync(tempDir, { recursive: true, force: true }); } catch {} + throw new Error(`启动浏览器失败: ${err.message}`); + } + } else { + const child = spawn(browserPath, args, { + stdio: 'ignore', + detached: true, + }); + child.on('error', () => {}); + child.unref(); + browserPid = child.pid; + } + + const debugUrl = `http://127.0.0.1:${port}/json/version`; + let wsUrl: string | null = null; + for (let i = 0; i < 30; i++) { + await new Promise(r => setTimeout(r, 200)); + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), 2000); + try { + const resp = await fetch(debugUrl, { signal: controller.signal }); + const data = await resp.json() as { webSocketDebuggerUrl?: string }; + if (data.webSocketDebuggerUrl) { + wsUrl = data.webSocketDebuggerUrl; + break; + } + } catch { + // 浏览器尚未就绪或请求超时 + } finally { + clearTimeout(timeoutId); + } + } + + if (!wsUrl) { + if (browserPid) try { process.kill(browserPid); } catch {} + try { rmSync(tempDir, { recursive: true, force: true }); } catch {} + throw new Error('浏览器启动失败:无法获取 WebSocket URL'); + } + + console.error(`[browser] Browser ready, connecting via ${wsUrl}`); + try { + const browser = await puppeteer.connect({ browserWSEndpoint: wsUrl }); + return { browser, tempDir, browserPid }; + } catch (err) { + if (browserPid) try { process.kill(browserPid); } catch {} + try { rmSync(tempDir, { recursive: true, force: true }); } catch {} + throw err; + } +} + +/** + * 优雅关闭浏览器:通过 CDP 命令让浏览器自行退出,所有子进程自动清理。 + * 如果 close() 超时,则回退到强杀进程树。 + */ +async function closeSession(session: BrowserSession) { + try { + // browser.close() 发送 CDP Browser.close 命令,浏览器会优雅退出并清理所有子进程 + await Promise.race([ + session.browser.close(), + new Promise(r => { const t = setTimeout(r, 5000); if (typeof t === 'object') t.unref(); }), // 5 秒超时,不阻塞事件循环 + ]); + } catch (err) { + // close 失败(例如浏览器已崩溃),回退到强杀 + console.error('[browser] browser.close() failed, falling back to force kill:', (err as Error).message ?? err); + killBrowserProcess(session); + } + try { rmSync(session.tempDir, { recursive: true, force: true }); } catch {} +} + +/** + * 同步强杀浏览器进程树(仅在 process.on('exit') 等无法使用 async 的场景中使用)。 + */ +function killBrowserProcess(session: BrowserSession) { + console.error(`[browser] Force killing browser process tree (PID: ${session.browserPid ?? 'unknown'})`); + try { session.browser.disconnect(); } catch {} + if (session.browserPid) { + if (process.platform === 'win32') { + // Windows 上 process.kill 只杀主进程,Edge 的子进程(GPU、渲染器等)会变成孤儿。 + // 使用 taskkill /T 级联终止整个进程树。 + try { execFileSync('taskkill', ['/F', '/T', '/PID', String(session.browserPid)], { windowsHide: true, timeout: 5000 }); } catch {} + } else { + try { process.kill(-session.browserPid); } catch {} // Unix: 杀进程组 + try { process.kill(session.browserPid); } catch {} + } + } + try { rmSync(session.tempDir, { recursive: true, force: true }); } catch {} +} + +/** 获取或复用全局共享的浏览器实例 */ +export async function getSharedBrowser(): Promise { + if (cachedSession) { + try { + await cachedSession.browser.version(); + return cachedSession.browser; + } catch { + console.error('[browser] Cached browser session is dead, relaunching...'); + killBrowserProcess(cachedSession); + cachedSession = null; + } + } + + const session = await launchBrowser(); + cachedSession = session; + + if (!cleanupRegistered) { + cleanupRegistered = true; + // exit 事件只能执行同步代码,使用强杀作为最后防线 + process.once('exit', () => { + if (cachedSession) { + killBrowserProcess(cachedSession); + cachedSession = null; + } + }); + // SIGINT/SIGTERM 可以执行异步代码,优先使用优雅关闭 + const signalCleanup = async () => { + if (cachedSession) { + await closeSession(cachedSession); + cachedSession = null; + } + process.exit(); + }; + process.once('SIGINT', signalCleanup); + process.once('SIGTERM', signalCleanup); + } + + return cachedSession.browser; +} + +/** 销毁全局浏览器会话(搜索出错时调用,下次会重新启动) */ +export async function destroySharedBrowser(): Promise { + if (cachedSession) { + await closeSession(cachedSession); + cachedSession = null; + } +} diff --git a/src/engines/zhihu/zhihu.ts b/src/engines/zhihu/zhihu.ts index d971f41..16f6ad1 100644 --- a/src/engines/zhihu/zhihu.ts +++ b/src/engines/zhihu/zhihu.ts @@ -1,98 +1,7 @@ -import axios from 'axios'; import {SearchResult} from '../../types.js'; import { config } from '../../config.js'; import {searchDuckDuckGo} from "../duckduckgo/index.js"; -import * as cheerio from 'cheerio'; - -async function searchBingForZhiHu(query: string, limit: number): Promise { - let allResults: SearchResult[] = []; - let pn = 0; - // Format query for URL - const encodedQuery = encodeURIComponent(query); - - try { - while (allResults.length < limit) { - const response = await axios.get('https://cn.bing.com/search', { - params: { - "q": query, - "qs": "n", - "form": "QBRE", - "sp": "-1", - "lq": "0", - "pq": query, - "sc": "5-36", - "sk": "", - "cvid": "EC2944BAA67C4476B26D801B068E79FD", - "rdr": "1", - "rdrig": "03977EC990574FBF94EC11E34B85CD62", - "first": 2 + pn * 10, - }, - headers: { - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", - "Connection": "keep-alive", - "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", - "Accept-Encoding": "gzip, deflate, br", - "cache-control": "max-age=0", - "ect": "4g", - "sec-ch-ua": "\"Chromium\";v=\"112\", \"Google Chrome\";v=\"112\", \"Not:A-Brand\";v=\"99\"", - "sec-ch-ua-mobile": "?0", - "sec-ch-ua-full-version": "\"112.0.5615.50\"", - "sec-ch-ua-arch": "\"x86\"", - "sec-ch-ua-platform": "\"Windows\"", - "sec-ch-ua-platform-version": "\"15.0.0\"", - "sec-ch-ua-model": "\"\"", - "sec-ch-ua-bitness": "\"64\"", - "sec-ch-ua-full-version-list": "\"Chromium\";v=\"112.0.5615.50\", \"Google Chrome\";v=\"112.0.5615.50\", \"Not:A-Brand\";v=\"99.0.0.0\"", - "upgrade-insecure-requests": "1", - "sec-fetch-site": "none", - "sec-fetch-mode": "navigate", - "sec-fetch-user": "?1", - "sec-fetch-dest": "document", - "accept-language": "zh-CN,zh;q=0.9" - } - }); - - const $ = cheerio.load(response.data); - const results: SearchResult[] = []; - - $('#b_content').children() - .find('#b_results').children() - .each((i, element) => { - const titleElement = $(element).find('h2'); - const linkElement = $(element).find('a'); - const snippetElement = $(element).find('p').first(); - - if (titleElement.length && linkElement.length) { - const url = linkElement.attr('href'); - if (url && url.startsWith('http') && url.includes('zhuanlan.zhihu.com')) { - const sourceElement = $(element).find('.b_tpcn'); - results.push({ - title: titleElement.text(), - url: url, - description: snippetElement.text().trim() || '', - source: 'zhuanlan.zhihu.com', - engine: 'bing' - }); - } - } - }); - - allResults = allResults.concat(results); - - if (results.length === 0) { - console.error('⚠️ No more results from Bing, ending early....'); - break; - } - - pn += 1; - } - - return allResults.slice(0, limit); - } catch (error: any) { - console.error('❌ Bing search failed:', error.message || error); - return []; - } -} +import {searchBing} from "../bing/index.js"; export async function searchZhiHu(query: string, limit: number): Promise { @@ -107,10 +16,10 @@ export async function searchZhiHu(query: string, limit: number): Promise { result.source = 'zhuanlan.zhihu.com'; - // Keep the original engine info }); return filteredResults.slice(0, limit); diff --git a/src/index.ts b/src/index.ts index c07b0e1..89f5332 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,6 +9,7 @@ import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js" import { randomUUID } from "node:crypto"; import cors from 'cors'; import {config} from "./config.js"; +import { destroySharedBrowser } from "./engines/shared/browser.js"; async function main() { // Create MCP server @@ -29,6 +30,13 @@ async function main() { }).catch(error => { console.error('❌ Failed to initialize STDIO transport:', error); }); + + // stdin 关闭时(MCP 宿主停止服务器),主动清理浏览器并退出 + server.server.onclose = async () => { + console.error('[server] MCP connection closed, cleaning up...'); + await destroySharedBrowser(); + process.exit(0); + }; } // Only set up HTTP server if enabled diff --git a/src/test/diag-bing.ts b/src/test/diag-bing.ts new file mode 100644 index 0000000..a06bf98 --- /dev/null +++ b/src/test/diag-bing.ts @@ -0,0 +1,164 @@ +/** + * 诊断脚本:分析 Bing 搜索为何对指定查询返回 0 结果。 + * 运行: npx tsx src/test/diag-bing.ts + */ +import { getSharedBrowser, destroySharedBrowser } from '../engines/shared/browser.js'; +import * as cheerio from 'cheerio'; +import { writeFileSync } from 'fs'; +import { join } from 'path'; + +const QUERY = 'proot-xed signal 11 SIGSEGV bus error Android apk add bash post-install crash workaround'; + +async function diagnose() { + console.log('=== Bing 搜索诊断 ==='); + console.log(`查询: "${QUERY}"`); + console.log(`编码后: ${encodeURIComponent(QUERY)}`); + console.log(`URL 长度: ${'https://www.bing.com/search?q='.length + encodeURIComponent(QUERY).length}`); + console.log(); + + const browser = await getSharedBrowser(); + const page = await browser.newPage(); + + try { + const searchUrl = `https://www.bing.com/search?q=${encodeURIComponent(QUERY)}`; + console.log(`导航到: ${searchUrl}`); + + const response = await page.goto(searchUrl, { waitUntil: 'networkidle2', timeout: 30000 }); + console.log(`HTTP 状态码: ${response?.status()}`); + console.log(`最终 URL: ${page.url()}`); + + await new Promise(r => setTimeout(r, 2000)); // 多等一会 + + const html = await page.content(); + const outPath = join(process.cwd(), 'diag-bing-output.html'); + writeFileSync(outPath, html, 'utf8'); + console.log(`\n页面 HTML 已保存到: ${outPath} (${html.length} 字符)`); + + // 截图 + const screenshotPath = join(process.cwd(), 'diag-bing-screenshot.png'); + await page.screenshot({ path: screenshotPath, fullPage: true }); + console.log(`截图已保存到: ${screenshotPath}`); + + const $ = cheerio.load(html); + + console.log('\n=== 选择器分析 ==='); + console.log(`#b_results 是否存在: ${$('#b_results').length > 0}`); + console.log(`#b_results 子元素数: ${$('#b_results').children().length}`); + console.log(`#b_results h2 数量: ${$('#b_results h2').length}`); + console.log(`#b_results li 数量: ${$('#b_results li').length}`); + console.log(`#b_results .b_algo 数量: ${$('#b_results .b_algo').length}`); + console.log(`所有 h2 数量: ${$('h2').length}`); + console.log(`所有 h2 文本:`); + $('h2').each((i, el) => { + console.log(` [${i}] ${$(el).text().trim().substring(0, 100)}`); + }); + + // 检查 Cookie 同意弹窗 + console.log('\n=== Cookie/弹窗检测 ==='); + const cookieSelectors = [ + '#bnp_container', // Bing cookie banner + '#bnp_btn_accept', // Bing accept button + '.bnp_btn_accept', + '#consent-banner', + '.consent-banner', + '#onetrust-banner', + '.cc-banner', + '#cookie-banner', + '#b_notificationContainer', + 'div[data-bm="1"]', // Bing modal overlay + ]; + for (const sel of cookieSelectors) { + const count = $(sel).length; + if (count > 0) { + console.log(` ✓ 发现弹窗元素: ${sel} (${count} 个)`); + console.log(` 内容: ${$(sel).text().trim().substring(0, 200)}`); + } + } + + // 检查验证码 + console.log('\n=== 验证码/反爬检测 ==='); + const captchaSelectors = [ + '#captcha', + '.captcha', + '#cf-wrapper', // Cloudflare challenge + '#challenge-running', + 'form[action*="captcha"]', + '#bnp_captcha', + ]; + for (const sel of captchaSelectors) { + const count = $(sel).length; + if (count > 0) { + console.log(` ✓ 发现验证码元素: ${sel} (${count} 个)`); + } + } + + // 检查 "没有结果" 提示 + console.log('\n=== 无结果/错误提示检测 ==='); + const noResultSelectors = [ + '.b_no', // Bing no results + '.b_msg', + '#b_results .b_ans', + ]; + for (const sel of noResultSelectors) { + const count = $(sel).length; + if (count > 0) { + console.log(` ✓ 发现提示: ${sel}: "${$(sel).text().trim().substring(0, 200)}"`); + } + } + + // 检查是否被重定向到 cn.bing.com 或其他本地化版本 + console.log('\n=== URL/重定向分析 ==='); + const finalUrl = page.url(); + console.log(`最终 URL: ${finalUrl}`); + if (!finalUrl.includes('www.bing.com')) { + console.log('⚠️ 被重定向到了非 www.bing.com 的域名!'); + } + + // 输出页面 title + console.log(`\n页面标题: ${$('title').text()}`); + + // 显示 body 的前 1000 个文本字符 + console.log('\n=== 页面正文前 500 字符 ==='); + const bodyText = $('body').text().replace(/\s+/g, ' ').trim(); + console.log(bodyText.substring(0, 500)); + + // 检查 #b_results 内部结构 + console.log('\n=== #b_results 内部结构 ==='); + $('#b_results').children().each((i, el) => { + const tag = (el as any).tagName; + const cls = $(el).attr('class') || ''; + const id = $(el).attr('id') || ''; + const h2Text = $(el).find('h2').first().text().trim().substring(0, 80); + console.log(` [${i}] <${tag}> class="${cls}" id="${id}" h2="${h2Text}"`); + if (i > 15) { + console.log(' ... (截断)'); + return false; + } + }); + + // 看链接 + console.log('\n=== #b_results 中的 a[href^=http] ==='); + let linkCount = 0; + $('#b_results a[href^="http"]').each((i, el) => { + if (linkCount >= 10) return false; + const href = $(el).attr('href'); + const text = $(el).text().trim().substring(0, 80); + if (text) { + console.log(` [${linkCount}] "${text}" -> ${href?.substring(0, 120)}`); + linkCount++; + } + }); + if (linkCount === 0) { + console.log(' (无 http 链接)'); + } + + } finally { + await page.close(); + await destroySharedBrowser(); + } +} + +diagnose().catch(err => { + console.error('诊断失败:', err); + process.exit(1); +}); diff --git a/src/test/fetchLinuxDoArticleTests.ts b/src/test/fetchLinuxDoArticleTests.ts new file mode 100644 index 0000000..8043c43 --- /dev/null +++ b/src/test/fetchLinuxDoArticleTests.ts @@ -0,0 +1,58 @@ +import { fetchLinuxDoArticle } from "../engines/linuxdo/fetchLinuxDoArticle.js"; + +async function testFetchLinuxDoArticle() { + console.log('🔍 Starting Linux.do article fetch test...'); + + try { + // A real linux.do topic URL (standard Discourse format: /t/slug/id) + const url = 'https://linux.do/t/welcome-to-linux-do/1'; + + console.log(`📝 Fetching article from URL: ${url}`); + + const result = await fetchLinuxDoArticle(url); + + console.log(`🎉 Article fetched successfully!`); + console.log(`\n📄 Content preview (first 200 chars):`); + console.log(` ${result.content.substring(0, 200)}`); + console.log(`\n📊 Total content length: ${result.content.length} characters`); + + return result; + } catch (error) { + console.error('❌ Test failed:', error instanceof Error ? error.message : error); + if (error && typeof error === 'object' && 'response' in error) { + const resp = (error as any).response; + console.error(` HTTP Status: ${resp?.status}`); + console.error(` Status Text: ${resp?.statusText}`); + } + return { content: '' }; + } +} + +async function testInvalidUrl() { + console.log('\n🔍 Testing with invalid URL...'); + + try { + const invalidUrl = 'https://linux.do/invalid_path'; + + console.log(`📝 Attempting to fetch from invalid URL: ${invalidUrl}`); + + const result = await fetchLinuxDoArticle(invalidUrl); + console.log(`🎉 Result: ${result.content.substring(0, 100)}`); + + return result; + } catch (error) { + console.log('✅ Expected error for invalid URL:', error instanceof Error ? error.message : error); + return { content: '' }; + } +} + +async function runTests() { + console.log('🧪 Running tests for fetchLinuxDoArticle function\n'); + + await testFetchLinuxDoArticle(); + await testInvalidUrl(); + + console.log('\n✅ All tests completed'); +} + +runTests().catch(console.error); diff --git a/src/test/test-baidu-availability.ts b/src/test/test-baidu-availability.ts new file mode 100644 index 0000000..4772ae5 --- /dev/null +++ b/src/test/test-baidu-availability.ts @@ -0,0 +1,90 @@ +import { searchBaidu } from '../engines/baidu/index.js'; +import { destroySharedBrowser } from '../engines/shared/browser.js'; + +/** + * 测试百度搜索引擎是否正常工作 (Issue #29: baidu被ban了) + * 验证百度搜索能返回结果,且结果结构正确 + */ + +async function testBaiduAvailability() { + console.log('=== Baidu availability test (Issue #29) ===\n'); + + const tests: { name: string; pass: boolean }[] = []; + + // Test 1: 英文查询能否返回结果 + { + const name = 'English query returns results'; + try { + const results = await searchBaidu('websearch mcp', 5); + const pass = results.length > 0; + console.log(`${pass ? '✅ PASS' : '❌ FAIL'}: ${name} — got ${results.length} results`); + tests.push({ name, pass }); + } catch (e) { + console.log(`❌ FAIL: ${name} — error: ${e instanceof Error ? e.message : e}`); + tests.push({ name, pass: false }); + } + } + + // Test 2: 中文热门查询 (Issue #29 的核心场景) + { + const name = 'Chinese hot query returns results (Issue #29)'; + try { + const results = await searchBaidu('天气预报', 5); + const pass = results.length > 0; + console.log(`${pass ? '✅ PASS' : '❌ FAIL'}: ${name} — got ${results.length} results`); + tests.push({ name, pass }); + } catch (e) { + console.log(`❌ FAIL: ${name} — error: ${e instanceof Error ? e.message : e}`); + tests.push({ name, pass: false }); + } + } + + // Test 3: 结果结构验证 + { + const name = 'Results have correct structure'; + try { + const results = await searchBaidu('nodejs', 3); + const pass = results.length > 0 && results.every(r => + typeof r.title === 'string' && r.title.length > 0 && + typeof r.url === 'string' && r.url.startsWith('http') && + typeof r.description === 'string' && + r.engine === 'baidu' + ); + console.log(`${pass ? '✅ PASS' : '❌ FAIL'}: ${name}`); + if (!pass && results.length > 0) { + console.log(' Sample result:', JSON.stringify(results[0], null, 2)); + } + tests.push({ name, pass }); + } catch (e) { + console.log(`❌ FAIL: ${name} — error: ${e instanceof Error ? e.message : e}`); + tests.push({ name, pass: false }); + } + } + + // Test 4: limit 参数生效 + { + const name = 'Limit parameter is respected'; + try { + const results = await searchBaidu('open source', 3); + const pass = results.length > 0 && results.length <= 3; + console.log(`${pass ? '✅ PASS' : '❌ FAIL'}: ${name} — requested 3, got ${results.length}`); + tests.push({ name, pass }); + } catch (e) { + console.log(`❌ FAIL: ${name} — error: ${e instanceof Error ? e.message : e}`); + tests.push({ name, pass: false }); + } + } + + const passed = tests.filter(t => t.pass).length; + const total = tests.length; + + console.log(`\n=== Results: ${passed}/${total} passed ===`); + + if (passed === total) { + console.log('\n✅ 百度搜索运行正常。'); + } + + process.exit(passed === total ? 0 : 1); +} + +testBaiduAvailability().catch(console.error).finally(async () => { await destroySharedBrowser(); process.exit(0); }); diff --git a/src/test/test-baidu.ts b/src/test/test-baidu.ts index 65987a8..130a8d2 100644 --- a/src/test/test-baidu.ts +++ b/src/test/test-baidu.ts @@ -1,4 +1,5 @@ import { searchBaidu } from '../engines/baidu/index.js'; +import { destroySharedBrowser } from '../engines/shared/browser.js'; async function testBaiduSearch() { console.log('🔍 Starting Baidu search test...'); @@ -28,4 +29,4 @@ async function testBaiduSearch() { } // Run the test -testBaiduSearch().catch(console.error); +testBaiduSearch().catch(console.error).finally(async () => { await destroySharedBrowser(); process.exit(0); }); diff --git a/src/test/test-bing-quality.ts b/src/test/test-bing-quality.ts new file mode 100644 index 0000000..b7d6570 --- /dev/null +++ b/src/test/test-bing-quality.ts @@ -0,0 +1,67 @@ +/** + * Bing 搜索结果质量测试。 + * + * 验证 Bing 搜索能正确理解查询语义,而不是将 "MCP" 等缩写 + * 错误地解读为 "Microsoft Certified Professional" 等无关含义。 + * + * 背景:cn.bing.com 对直接 URL 导航返回降级的搜索结果, + * 必须通过搜索框表单提交(带 form=QBLH 参数)才能获得正确结果。 + * 此外,headless 模式下 Bing 搜索框提交返回 0 结果, + * 必须使用 GUI 模式(窗口隐藏)的浏览器。 + */ +import { searchBing } from '../engines/bing/index.js'; +import { destroySharedBrowser } from '../engines/shared/browser.js'; + +const rand = () => Math.random().toString(36).slice(2, 6); + +async function testBingSearchQuality() { + let passed = 0; + let failed = 0; + + async function assertRelevant(query: string, relevancePattern: RegExp, minRelevant: number) { + // 追加随机后缀确保每次搜索都是全新查询,避免缓存 + const suffix = rand(); + const fullQuery = `${query} ${suffix}`; + console.log(`\n🔍 Query: "${fullQuery}"`); + + const results = await searchBing(fullQuery, 10); + const relevant = results.filter(r => relevancePattern.test(r.title)); + + console.log(` Results: ${results.length}, Relevant: ${relevant.length}/${results.length}`); + results.slice(0, 5).forEach((r, i) => { + const mark = relevancePattern.test(r.title) ? '✓' : '✗'; + console.log(` ${mark} ${i + 1}. ${r.title}`); + }); + + if (relevant.length >= minRelevant) { + console.log(` ✅ PASS (>= ${minRelevant} relevant)`); + passed++; + } else { + console.log(` ❌ FAIL (expected >= ${minRelevant} relevant, got ${relevant.length})`); + failed++; + } + } + + console.log('=== Bing 搜索结果质量测试 ===\n'); + + // 测试1: "MCP" 应被理解为 Model Context Protocol,而非 Microsoft Certified Professional + await assertRelevant( + 'MCP tool rename duplicate tool names proxy wrapper', + /tool|FastMCP|collision|wrapper|proxy|duplicate|mcp.*server|rename|spring.*ai/i, + 3 + ); + + // 测试2: 常规英文技术搜索 + await assertRelevant( + 'TypeScript generic type inference guide', + /typescript|generic|type|inference|guide/i, + 3 + ); + + console.log(`\n=== 结果: ${passed} passed, ${failed} failed ===`); + if (failed > 0) process.exitCode = 1; +} + +testBingSearchQuality() + .catch(err => { console.error('❌ Test error:', err); process.exitCode = 1; }) + .finally(async () => { await destroySharedBrowser(); process.exit(); }); diff --git a/src/test/test-bing.ts b/src/test/test-bing.ts index 346b457..ca25dd0 100644 --- a/src/test/test-bing.ts +++ b/src/test/test-bing.ts @@ -1,4 +1,5 @@ import { searchBing } from '../engines/bing/index.js'; +import { destroySharedBrowser } from '../engines/shared/browser.js'; async function testBingSearch() { console.log('🔍 Starting Bing search test...'); @@ -28,4 +29,4 @@ async function testBingSearch() { } // Run the test -testBingSearch().catch(console.error); +testBingSearch().catch(console.error).finally(async () => { await destroySharedBrowser(); process.exit(0); }); diff --git a/src/test/test-description-length.ts b/src/test/test-description-length.ts new file mode 100644 index 0000000..77ac109 --- /dev/null +++ b/src/test/test-description-length.ts @@ -0,0 +1,89 @@ +import { searchBing } from '../engines/bing/index.js'; +import { SearchResult } from '../types.js'; +import { config } from '../config.js'; +import { destroySharedBrowser } from '../engines/shared/browser.js'; + +// 与 setupTools.ts 中相同的截断逻辑 +function truncateDescriptions(results: SearchResult[], descLimit?: number): SearchResult[] { + if (!descLimit) return results; + return results.map(r => ({ + ...r, + description: r.description.length > descLimit + ? r.description.slice(0, descLimit) + '...' + : r.description + })); +} + +async function testDescriptionLength() { + console.log('🔍 Starting description length truncation test...\n'); + + let passed = 0; + let failed = 0; + + function assert(condition: boolean, message: string) { + if (condition) { + console.log(` ✅ ${message}`); + passed++; + } else { + console.error(` ❌ ${message}`); + failed++; + } + } + + // ===== 单元测试:截断逻辑 ===== + console.log('--- 单元测试:截断逻辑 ---'); + + const mockResults: SearchResult[] = [ + { title: 'A', url: 'http://a.com', description: 'Short', source: 'bing', engine: 'bing' }, + { title: 'B', url: 'http://b.com', description: 'This is a much longer description that exceeds the limit', source: 'bing', engine: 'bing' }, + { title: 'C', url: 'http://c.com', description: '', source: 'bing', engine: 'bing' }, + ]; + + // 测试1:无限制时不截断 + const noLimit = truncateDescriptions(mockResults, undefined); + assert(noLimit[0].description === 'Short', '无限制时短描述不变'); + assert(noLimit[1].description === 'This is a much longer description that exceeds the limit', '无限制时长描述不变'); + assert(noLimit[2].description === '', '无限制时空描述不变'); + + // 测试2:设置限制后截断 + const limited = truncateDescriptions(mockResults, 10); + assert(limited[0].description === 'Short', '短于限制的描述不变'); + assert(limited[1].description === 'This is a ...', '超过限制的描述被截断并加省略号'); + assert(limited[1].description.length === 13, `截断后长度为 10+3=13 (实际: ${limited[1].description.length})`); + assert(limited[2].description === '', '空描述保持为空'); + + // 测试3:限制恰好等于描述长度时不截断 + const exact = truncateDescriptions(mockResults, 5); + assert(exact[0].description === 'Short', '长度恰好等于限制时不截断'); + + // 测试4:限制为1 + const one = truncateDescriptions(mockResults, 1); + assert(one[1].description === 'T...', '限制为1时只保留1个字符加省略号'); + + // 测试5:全局配置默认值 + console.log('\n--- 全局配置检查 ---'); + assert(config.maxDescriptionLength === undefined, `默认全局配置为 undefined (实际: ${config.maxDescriptionLength})`); + + // ===== 集成测试:实际搜索 + 截断 ===== + console.log('\n--- 集成测试:实际搜索 + 截断 ---'); + try { + const results = await searchBing('typescript', 3); + assert(results.length > 0, `Bing 搜索返回了 ${results.length} 条结果`); + + const truncated = truncateDescriptions(results, 20); + for (const r of truncated) { + const ok = r.description.length <= 23; // 20 + '...' + assert(ok, `"${r.title}" 描述长度 ${r.description.length} <= 23`); + } + } catch (error) { + console.error(` ⚠️ 集成测试跳过 (搜索失败): ${error instanceof Error ? error.message : error}`); + } + + // ===== 结果汇总 ===== + console.log(`\n📊 结果: ${passed} 通过, ${failed} 失败`); + if (failed > 0) process.exit(1); +} + +testDescriptionLength().catch(e => { + console.error('❌ 测试异常:', e); +}).finally(async () => { await destroySharedBrowser(); process.exit(0); }); diff --git a/src/test/test-engine-case.ts b/src/test/test-engine-case.ts new file mode 100644 index 0000000..31c434a --- /dev/null +++ b/src/test/test-engine-case.ts @@ -0,0 +1,55 @@ +import { z } from 'zod'; + +// 复现 setupTools.ts 中的引擎 schema 逻辑(与实际代码一致) +const SUPPORTED_ENGINES = ['baidu', 'bing', 'linuxdo', 'csdn', 'duckduckgo', 'exa', 'brave', 'juejin'] as const; + +const getAllowedEngines = () => [...SUPPORTED_ENGINES] as string[]; + +const enginesSchema = z.array(z.string()) + .min(1).default(['bing']) + .transform(requestedEngines => { + const allowed = getAllowedEngines(); + const normalized = requestedEngines.map(e => e.toLowerCase()); + const valid = normalized.filter(e => allowed.includes(e)); + if (valid.length === 0) { + throw new Error(`No valid engine found. Allowed engines: ${allowed.join(', ')}`); + } + return valid; + }); + +function test(name: string, input: unknown, expected: string[] | 'error') { + try { + const result = enginesSchema.parse(input); + if (expected === 'error') { + console.log(`❌ FAIL: ${name} — expected error but got ${JSON.stringify(result)}`); + return false; + } + const pass = JSON.stringify(result) === JSON.stringify(expected); + console.log(`${pass ? '✅ PASS' : '❌ FAIL'}: ${name} — got ${JSON.stringify(result)}`); + return pass; + } catch (e) { + if (expected === 'error') { + console.log(`✅ PASS: ${name} — correctly rejected`); + return true; + } + console.log(`❌ FAIL: ${name} — unexpected error: ${e instanceof Error ? e.message : e}`); + return false; + } +} + +console.log('=== Engine name case-insensitivity tests ===\n'); + +const results = [ + test('lowercase "bing"', ['bing'], ['bing']), + test('uppercase first letter "Bing"', ['Bing'], ['bing']), + test('all caps "DUCKDUCKGO"', ['DUCKDUCKGO'], ['duckduckgo']), + test('mixed case "BaiDu"', ['BaiDu'], ['baidu']), + test('multiple mixed case engines', ['Bing', 'BRAVE', 'exa'], ['bing', 'brave', 'exa']), + test('invalid engine name', ['invalid'], 'error'), + test('empty array', [], 'error'), +]; + +const passed = results.filter(Boolean).length; +const total = results.length; +console.log(`\n=== Results: ${passed}/${total} passed ===`); +process.exit(passed === total ? 0 : 1); diff --git a/src/test/test-linuxdo.ts b/src/test/test-linuxdo.ts index ab86f67..315c4df 100644 --- a/src/test/test-linuxdo.ts +++ b/src/test/test-linuxdo.ts @@ -1,4 +1,5 @@ import { searchLinuxDo } from '../engines/linuxdo/index.js'; +import { destroySharedBrowser } from '../engines/shared/browser.js'; async function testLinuxDoSearch() { console.log('🔍 Starting LinuxDo search test...'); @@ -28,4 +29,4 @@ async function testLinuxDoSearch() { } // Run the test -testLinuxDoSearch().catch(console.error); +testLinuxDoSearch().catch(console.error).finally(async () => { await destroySharedBrowser(); process.exit(0); }); diff --git a/src/test/test-search-relevance.ts b/src/test/test-search-relevance.ts new file mode 100644 index 0000000..bec9170 --- /dev/null +++ b/src/test/test-search-relevance.ts @@ -0,0 +1,95 @@ +import { searchBaidu } from '../engines/baidu/index.js'; +import { searchBing } from '../engines/bing/index.js'; +import { destroySharedBrowser } from '../engines/shared/browser.js'; + +interface TestCase { + engine: 'baidu' | 'bing'; + query: string; + mustContainAny: string[]; + description: string; +} + +const tests: TestCase[] = [ + { + engine: 'baidu', + query: '天气预报', + mustContainAny: ['天气', '预报', 'weather'], + description: 'Baidu "天气预报" (Issue #29 核心问题词)', + }, + { + engine: 'baidu', + query: 'Python教程', + mustContainAny: ['python', 'Python', '教程', '编程'], + description: 'Baidu "Python教程" (Issue #29 问题词)', + }, + { + engine: 'bing', + query: 'websearch mcp server', + mustContainAny: ['websearch', 'mcp', 'search', 'MCP'], + description: 'Bing "websearch mcp server" 结果相关性', + }, + { + engine: 'bing', + query: 'TypeScript tutorial', + mustContainAny: ['typescript', 'TypeScript', 'tutorial', '教程'], + description: 'Bing "TypeScript tutorial" 结果相关性', + }, +]; + +async function testSearchRelevance() { + console.log('=== 搜索结果相关性测试 ===\n'); + + let passed = 0; + let failed = 0; + + for (const tc of tests) { + console.log(`--- ${tc.description} ---`); + console.log(`查询: "${tc.query}" (${tc.engine})`); + + try { + const results = tc.engine === 'baidu' + ? await searchBaidu(tc.query, 5) + : await searchBing(tc.query, 5); + + if (results.length === 0) { + console.log(`❌ FAIL: 返回 0 条结果`); + failed++; + continue; + } + + results.forEach((r, i) => { + console.log(` ${i + 1}. ${r.title}`); + }); + + const keywords = tc.mustContainAny.map(k => k.toLowerCase()); + let relevantCount = 0; + for (const r of results) { + const text = `${r.title} ${r.url} ${r.description}`.toLowerCase(); + if (keywords.some(k => text.includes(k))) { + relevantCount++; + } + } + + const ratio = relevantCount / results.length; + if (ratio >= 0.5) { + console.log(`✅ PASS: ${relevantCount}/${results.length} 条结果相关 (${(ratio * 100).toFixed(0)}%)`); + passed++; + } else { + console.log(`❌ FAIL: ${relevantCount}/${results.length} 条结果相关 (${(ratio * 100).toFixed(0)}%) — 相关性不足`); + failed++; + } + } catch (err: any) { + console.log(`❌ FAIL: ${err.message}`); + failed++; + } + console.log(); + } + + console.log(`=== 结果: ${passed}/${passed + failed} 通过 ===`); + if (failed > 0) { + console.log(`⚠️ ${failed} 项未通过`); + process.exitCode = 1; + } +} + +testSearchRelevance().catch(console.error).finally(async () => { await destroySharedBrowser(); process.exit(0); }); diff --git a/src/test/test-zhihu.ts b/src/test/test-zhihu.ts index d1194cf..aac0383 100644 --- a/src/test/test-zhihu.ts +++ b/src/test/test-zhihu.ts @@ -1,4 +1,5 @@ import {searchZhiHu} from "../engines/zhihu/zhihu.js"; +import { destroySharedBrowser } from '../engines/shared/browser.js'; async function testZhiHuSearch() { console.log('🔍 Starting Zhihu search test...'); @@ -28,4 +29,4 @@ async function testZhiHuSearch() { } // Run the test -testZhiHuSearch().catch(console.error); +testZhiHuSearch().catch(console.error).finally(async () => { await destroySharedBrowser(); process.exit(0); }); diff --git a/src/tools/setupTools.ts b/src/tools/setupTools.ts index d5cac1f..90ecdfc 100644 --- a/src/tools/setupTools.ts +++ b/src/tools/setupTools.ts @@ -15,6 +15,20 @@ import {searchBrave} from "../engines/brave/index.js"; import {fetchGithubReadme} from "../engines/github/index.js"; import { fetchJuejinArticle } from "../engines/juejin/fetchJuejinArticle.js"; import { searchJuejin } from "../engines/juejin/index.js"; +import axios from 'axios'; + +/** 从错误对象中提取可读的错误消息(处理 AxiosError/AggregateError 等 message 为空的情况) */ +function getErrorMessage(error: unknown): string { + if (axios.isAxiosError(error)) { + const parts: string[] = []; + if (error.code) parts.push(error.code); + if (error.message) parts.push(error.message); + if (error.response) parts.push(`HTTP ${error.response.status}`); + if (parts.length > 0) return parts.join(' - '); + } + if (error instanceof Error && error.message) return error.message; + return String(error) || 'Unknown error'; +} // 支持的搜索引擎 const SUPPORTED_ENGINES = ['baidu', 'bing', 'linuxdo', 'csdn', 'duckduckgo','exa','brave','juejin'] as const; @@ -42,8 +56,13 @@ const distributeLimit = (totalLimit: number, engineCount: number): number[] => { ); }; +interface SearchExecutionResult { + results: SearchResult[]; + errors: { engine: string; message: string }[]; +} + // 执行搜索 -const executeSearch = async (query: string, engines: string[], limit: number): Promise => { +const executeSearch = async (query: string, engines: string[], limit: number): Promise => { // Clean up the query string to ensure it won't cause issues due to spaces or special characters const cleanQuery = query.trim(); console.error(`[DEBUG] Executing search, query: "${cleanQuery}", engines: ${engines.join(', ')}, limit: ${limit}`); @@ -51,33 +70,32 @@ const executeSearch = async (query: string, engines: string[], limit: number): P if (!cleanQuery) { console.error('Query string is empty'); throw new Error('Query string cannot be empty'); - } const limits = distributeLimit(limit, engines.length); + const errors: { engine: string; message: string }[] = []; const searchTasks = engines.map((engine, index) => { const engineLimit = limits[index]; const searchFn = engineMap[engine as SupportedEngine]; if (!searchFn) { - console.warn(`Unsupported search engine: ${engine}`); + const msg = `Unsupported search engine: ${engine}`; + console.warn(msg); + errors.push({ engine, message: msg }); return Promise.resolve([]); } return searchFn(query, engineLimit).catch(error => { - console.error(`Search failed for engine ${engine}:`, error); + const msg = getErrorMessage(error); + console.error(`Search failed for engine ${engine}: ${msg}`); + errors.push({ engine, message: msg }); return []; }); }); - try { - const results = await Promise.all(searchTasks); - return results.flat().slice(0, limit); - } catch (error) { - console.error('Search execution failed:', error); - throw error; - } + const results = await Promise.all(searchTasks); + return { results: results.flat().slice(0, limit), errors }; }; // 验证文章 URL @@ -87,7 +105,7 @@ const validateArticleUrl = (url: string, type: 'linuxdo' | 'csdn' | 'juejin'): b switch (type) { case 'linuxdo': - return urlObj.hostname === 'linux.do' && url.includes('.json'); + return urlObj.hostname === 'linux.do' && /\/t(opic)?\//.test(url); case 'csdn': return urlObj.hostname === 'blog.csdn.net' && url.includes('/article/details/'); case 'juejin': @@ -154,8 +172,9 @@ export const setupTools = (server: McpServer): void => { // 搜索工具 // 生成搜索工具的动态描述 const getSearchDescription = () => { + const scenarioHint = '。当你需要查找最新信息、验证事实、研究主题或查阅超出你训练数据的文档/教程时,请使用此工具。中文查询优先选择 Baidu 或 Bing;英文查询优先选择 Bing 或 DuckDuckGo;开发/编程主题可考虑 CSDN、Juejin(掘金) 或 Exa。'; if (config.allowedSearchEngines.length === 0) { - return "Search the web using multiple engines (e.g., Baidu, Bing, DuckDuckGo, CSDN, Exa, Brave, Juejin(掘金)) with no API key required"; + return "Search the web using multiple engines (e.g., Baidu, Bing, DuckDuckGo, CSDN, Exa, Brave, Juejin(掘金)) with no API key required" + scenarioHint; } else { const enginesText = config.allowedSearchEngines.map(e => { switch (e) { @@ -165,7 +184,7 @@ export const setupTools = (server: McpServer): void => { return e.charAt(0).toUpperCase() + e.slice(1); } }).join(', '); - return `Search the web using these engines: ${enginesText} (no API key required)`; + return `Search the web using these engines: ${enginesText} (no API key required)` + scenarioHint; } }; @@ -185,7 +204,9 @@ export const setupTools = (server: McpServer): void => { { query: z.string().min(1, "Search query must not be empty"), limit: z.number().min(1).max(50).default(10), - engines: z.array(getEnginesEnum()).min(1).default([config.defaultSearchEngine]) + maxDescriptionLength: z.number().min(1).optional() + .describe("Maximum length of each result's description. Defaults to the global MAX_DESCRIPTION_LENGTH setting. Omit for no limit."), + engines: z.array(z.string().transform(s => s.toLowerCase()).pipe(getEnginesEnum())).min(1).default([config.defaultSearchEngine]) .transform(requestedEngines => { // 如果有配置允许的搜索引擎,过滤请求的引擎 if (config.allowedSearchEngines.length > 0) { @@ -200,29 +221,92 @@ export const setupTools = (server: McpServer): void => { return requestedEngines; }) }, - async ({query, limit = 10, engines = ['bing']}) => { + async ({query, limit = 10, maxDescriptionLength, engines = ['bing']}) => { try { console.error(`Searching for "${query}" using engines: ${engines.join(', ')}`); - const results = await executeSearch(query.trim(), engines, limit); + const { results, errors } = await executeSearch(query.trim(), engines, limit); + + // 所有引擎全部失败(错误数 == 引擎数)→ 返回 isError + if (errors.length === engines.length) { + const errorDetail = errors.map(e => `${e.engine}: ${e.message}`).join('\n'); + return { + content: [{ + type: 'text', + text: `All search engines failed:\n${errorDetail}` + }], + isError: true + }; + } + + // 0 结果但只有部分引擎失败 → 也标记为错误,列出各引擎状态 + if (results.length === 0 && errors.length > 0) { + const failedSet = new Set(errors.map(e => e.engine)); + const succeededEngines = engines.filter(e => !failedSet.has(e)); + const lines = errors.map(e => `${e.engine}: ${e.message}`); + if (succeededEngines.length > 0) { + lines.push(`${succeededEngines.join(', ')}: returned 0 results`); + } + return { + content: [{ + type: 'text', + text: `No results found:\n${lines.join('\n')}` + }], + isError: true + }; + } + + // 所有引擎均成功执行但返回 0 条结果 → 不是错误,给出信息性提示 + if (results.length === 0 && errors.length === 0) { + return { + content: [{ + type: 'text', + text: JSON.stringify({ + query: query.trim(), + engines: engines, + totalResults: 0, + results: [], + message: `所有搜索引擎(${engines.join('、')})均未找到与此查询匹配的结果。可能是查询过于具体、过长,或搜索引擎未能找到匹配的页面。建议简化查询或使用不同的关键词。` + }, null, 2) + }] + }; + } + + // 应用描述长度限制:调用参数 > 全局配置 > 不限制 + const descLimit = maxDescriptionLength ?? config.maxDescriptionLength; + const truncatedResults = descLimit + ? results.map(r => ({ + ...r, + description: r.description.length > descLimit + ? r.description.slice(0, descLimit) + '...' + : r.description + })) + : results; + + const response: Record = { + query: query.trim(), + engines: engines, + totalResults: truncatedResults.length, + results: truncatedResults + }; + + // 部分引擎失败 → 在结果中附带警告 + if (errors.length > 0) { + response.warnings = errors.map(e => `${e.engine}: ${e.message}`); + } return { content: [{ type: 'text', - text: JSON.stringify({ - query: query.trim(), - engines: engines, - totalResults: results.length, - results: results - }, null, 2) + text: JSON.stringify(response, null, 2) }] }; } catch (error) { - console.error('Search tool execution failed:', error); + console.error(`Search tool execution failed: ${getErrorMessage(error)}`); return { content: [{ type: 'text', - text: `Search failed: ${error instanceof Error ? error.message : 'Unknown error'}` + text: `Search failed: ${getErrorMessage(error)}` }], isError: true }; @@ -233,7 +317,7 @@ export const setupTools = (server: McpServer): void => { // 获取 Linux.do 文章工具 server.tool( fetchLinuxDoToolName, - "Fetch full article content from a linux.do post URL", + "获取 linux.do 帖子的完整内容。当搜索结果中包含 linux.do 链接,且你需要阅读完整讨论或帖子内容以回答用户问题时,请使用此工具。", { url: z.string().url().refine( (url) => validateArticleUrl(url, 'linuxdo'), @@ -252,11 +336,11 @@ export const setupTools = (server: McpServer): void => { }] }; } catch (error) { - console.error('Failed to fetch Linux.do article:', error); + console.error(`Failed to fetch Linux.do article: ${getErrorMessage(error)}`); return { content: [{ type: 'text', - text: `Failed to fetch article: ${error instanceof Error ? error.message : 'Unknown error'}` + text: `Failed to fetch article: ${getErrorMessage(error)}` }], isError: true }; @@ -267,7 +351,7 @@ export const setupTools = (server: McpServer): void => { // 获取 CSDN 文章工具 server.tool( fetchCsdnToolName, - "Fetch full article content from a csdn post URL", + "获取 CSDN 博客文章的完整内容。当搜索结果中包含 blog.csdn.net 链接,且你需要全文来回答用户问题时,请使用此工具。", { url: z.string().url().refine( (url) => validateArticleUrl(url, 'csdn'), @@ -286,11 +370,11 @@ export const setupTools = (server: McpServer): void => { }] }; } catch (error) { - console.error('Failed to fetch CSDN article:', error); + console.error(`Failed to fetch CSDN article: ${getErrorMessage(error)}`); return { content: [{ type: 'text', - text: `Failed to fetch article: ${error instanceof Error ? error.message : 'Unknown error'}` + text: `Failed to fetch article: ${getErrorMessage(error)}` }], isError: true }; @@ -301,7 +385,7 @@ export const setupTools = (server: McpServer): void => { // 获取 GitHub README 工具 server.tool( fetchGithubToolName, - "Fetch README content from a GitHub repository URL", + "获取 GitHub 仓库的 README 内容。当用户询问某个 GitHub 项目,或你需要从 README 了解项目用途、安装步骤或使用方式时,请使用此工具。", { url: z.string().min(1).refine( (url) => validateGithubUrl(url), @@ -330,11 +414,11 @@ export const setupTools = (server: McpServer): void => { }; } } catch (error) { - console.error('Failed to fetch GitHub README:', error); + console.error(`Failed to fetch GitHub README: ${getErrorMessage(error)}`); return { content: [{ type: 'text', - text: `Failed to fetch README: ${error instanceof Error ? error.message : 'Unknown error'}` + text: `Failed to fetch README: ${getErrorMessage(error)}` }], isError: true }; @@ -345,7 +429,7 @@ export const setupTools = (server: McpServer): void => { // 获取掘金文章工具 server.tool( fetchJuejinToolName, - "Fetch full article content from a Juejin(掘金) post URL", + "获取掘金(Juejin)文章的完整内容。当搜索结果中包含 juejin.cn 链接,且你需要全文来提供详细回答时,请使用此工具。", { url: z.string().url().refine( (url) => validateArticleUrl(url, 'juejin'), @@ -364,11 +448,11 @@ export const setupTools = (server: McpServer): void => { }] }; } catch (error) { - console.error('Failed to fetch Juejin article:', error); + console.error(`Failed to fetch Juejin article: ${getErrorMessage(error)}`); return { content: [{ type: 'text', - text: `Failed to fetch article: ${error instanceof Error ? error.message : 'Unknown error'}` + text: `Failed to fetch article: ${getErrorMessage(error)}` }], isError: true };