敖欣乐 7 месяцев назад
Сommit
3beb101005
45 измененных файлов с 26037 добавлено и 0 удалено
  1. 17 0
      lead-discovery/.editorconfig
  2. 42 0
      lead-discovery/.gitignore
  3. 4 0
      lead-discovery/.vscode/extensions.json
  4. 20 0
      lead-discovery/.vscode/launch.json
  5. 42 0
      lead-discovery/.vscode/tasks.json
  6. 27 0
      lead-discovery/README.md
  7. 124 0
      lead-discovery/angular.json
  8. 338 0
      lead-discovery/docs/BGCHECK_INTEGRATION_ANALYSIS.md
  9. 410 0
      lead-discovery/docs/FEASIBILITY_ANALYSIS.md
  10. 241 0
      lead-discovery/docs/MERGE_ANALYSIS.md
  11. 604 0
      lead-discovery/docs/OPTIMIZATION_PLAN.md
  12. 951 0
      lead-discovery/docs/PRD_LEAD_DISCOVERY.md
  13. 592 0
      lead-discovery/docs/PRODUCT_LOGIC_REDESIGN.md
  14. 69 0
      lead-discovery/docs/ltc.md
  15. 15374 0
      lead-discovery/package-lock.json
  16. 40 0
      lead-discovery/package.json
  17. BIN
      lead-discovery/public/favicon.ico
  18. 0 0
      lead-discovery/src/app/app.component.scss
  19. 130 0
      lead-discovery/src/app/app.component.ts
  20. 15 0
      lead-discovery/src/app/app.config.ts
  21. 28 0
      lead-discovery/src/app/app.routes.ts
  22. 179 0
      lead-discovery/src/app/components/deep-research-package/deep-research-package.component.html
  23. 268 0
      lead-discovery/src/app/components/deep-research-package/deep-research-package.component.scss
  24. 109 0
      lead-discovery/src/app/components/deep-research-package/deep-research-package.component.ts
  25. 145 0
      lead-discovery/src/app/components/screen-result-card/screen-result-card.component.html
  26. 266 0
      lead-discovery/src/app/components/screen-result-card/screen-result-card.component.scss
  27. 181 0
      lead-discovery/src/app/components/screen-result-card/screen-result-card.component.ts
  28. 312 0
      lead-discovery/src/app/models/lead.model.ts
  29. 1755 0
      lead-discovery/src/app/pages/dashboard/dashboard.component.ts
  30. 356 0
      lead-discovery/src/app/pages/kanban/kanban.component.ts
  31. 678 0
      lead-discovery/src/app/pages/lead-detail/lead-detail.component.ts
  32. 477 0
      lead-discovery/src/app/pages/lead-list/lead-list.component.ts
  33. 289 0
      lead-discovery/src/app/pages/list/list.component.html
  34. 278 0
      lead-discovery/src/app/pages/list/list.component.scss
  35. 198 0
      lead-discovery/src/app/pages/list/list.component.ts
  36. 394 0
      lead-discovery/src/app/pages/personas/personas.component.ts
  37. 190 0
      lead-discovery/src/app/pages/product-catalog/product-catalog.component.ts
  38. 465 0
      lead-discovery/src/app/services/mock-data.service.ts
  39. 210 0
      lead-discovery/src/app/services/quick-screen.service.ts
  40. 15 0
      lead-discovery/src/index.html
  41. 6 0
      lead-discovery/src/main.ts
  42. 135 0
      lead-discovery/src/styles.scss
  43. 15 0
      lead-discovery/tsconfig.app.json
  44. 33 0
      lead-discovery/tsconfig.json
  45. 15 0
      lead-discovery/tsconfig.spec.json

+ 17 - 0
lead-discovery/.editorconfig

@@ -0,0 +1,17 @@
+# Editor configuration, see https://editorconfig.org
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.ts]
+quote_type = single
+ij_typescript_use_double_quotes = false
+
+[*.md]
+max_line_length = off
+trim_trailing_whitespace = false

+ 42 - 0
lead-discovery/.gitignore

@@ -0,0 +1,42 @@
+# See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files.
+
+# Compiled output
+/dist
+/tmp
+/out-tsc
+/bazel-out
+
+# Node
+/node_modules
+npm-debug.log
+yarn-error.log
+
+# IDEs and editors
+.idea/
+.project
+.classpath
+.c9/
+*.launch
+.settings/
+*.sublime-workspace
+
+# Visual Studio Code
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+.history/*
+
+# Miscellaneous
+/.angular/cache
+.sass-cache/
+/connect.lock
+/coverage
+/libpeerconnection.log
+testem.log
+/typings
+
+# System files
+.DS_Store
+Thumbs.db

+ 4 - 0
lead-discovery/.vscode/extensions.json

@@ -0,0 +1,4 @@
+{
+  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
+  "recommendations": ["angular.ng-template"]
+}

+ 20 - 0
lead-discovery/.vscode/launch.json

@@ -0,0 +1,20 @@
+{
+  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+  "version": "0.2.0",
+  "configurations": [
+    {
+      "name": "ng serve",
+      "type": "chrome",
+      "request": "launch",
+      "preLaunchTask": "npm: start",
+      "url": "http://localhost:4200/"
+    },
+    {
+      "name": "ng test",
+      "type": "chrome",
+      "request": "launch",
+      "preLaunchTask": "npm: test",
+      "url": "http://localhost:9876/debug.html"
+    }
+  ]
+}

+ 42 - 0
lead-discovery/.vscode/tasks.json

@@ -0,0 +1,42 @@
+{
+  // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558
+  "version": "2.0.0",
+  "tasks": [
+    {
+      "type": "npm",
+      "script": "start",
+      "isBackground": true,
+      "problemMatcher": {
+        "owner": "typescript",
+        "pattern": "$tsc",
+        "background": {
+          "activeOnStart": true,
+          "beginsPattern": {
+            "regexp": "(.*?)"
+          },
+          "endsPattern": {
+            "regexp": "bundle generation complete"
+          }
+        }
+      }
+    },
+    {
+      "type": "npm",
+      "script": "test",
+      "isBackground": true,
+      "problemMatcher": {
+        "owner": "typescript",
+        "pattern": "$tsc",
+        "background": {
+          "activeOnStart": true,
+          "beginsPattern": {
+            "regexp": "(.*?)"
+          },
+          "endsPattern": {
+            "regexp": "bundle generation complete"
+          }
+        }
+      }
+    }
+  ]
+}

+ 27 - 0
lead-discovery/README.md

@@ -0,0 +1,27 @@
+# LeadDiscovery
+
+This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 18.2.21.
+
+## Development server
+
+Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files.
+
+## Code scaffolding
+
+Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
+
+## Build
+
+Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
+
+## Running unit tests
+
+Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
+
+## Running end-to-end tests
+
+Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
+
+## Further help
+
+To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.

+ 124 - 0
lead-discovery/angular.json

@@ -0,0 +1,124 @@
+{
+  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
+  "version": 1,
+  "newProjectRoot": "projects",
+  "projects": {
+    "lead-discovery": {
+      "projectType": "application",
+      "schematics": {
+        "@schematics/angular:component": {
+          "style": "scss",
+          "skipTests": true
+        },
+        "@schematics/angular:class": {
+          "skipTests": true
+        },
+        "@schematics/angular:directive": {
+          "skipTests": true
+        },
+        "@schematics/angular:guard": {
+          "skipTests": true
+        },
+        "@schematics/angular:interceptor": {
+          "skipTests": true
+        },
+        "@schematics/angular:pipe": {
+          "skipTests": true
+        },
+        "@schematics/angular:resolver": {
+          "skipTests": true
+        },
+        "@schematics/angular:service": {
+          "skipTests": true
+        }
+      },
+      "root": "",
+      "sourceRoot": "src",
+      "prefix": "app",
+      "architect": {
+        "build": {
+          "builder": "@angular-devkit/build-angular:application",
+          "options": {
+            "outputPath": "dist/lead-discovery",
+            "index": "src/index.html",
+            "browser": "src/main.ts",
+            "polyfills": [
+              "zone.js"
+            ],
+            "tsConfig": "tsconfig.app.json",
+            "inlineStyleLanguage": "scss",
+            "assets": [
+              {
+                "glob": "**/*",
+                "input": "public"
+              }
+            ],
+            "styles": [
+              "src/styles.scss"
+            ],
+            "scripts": []
+          },
+          "configurations": {
+            "production": {
+              "budgets": [
+                {
+                  "type": "initial",
+                  "maximumWarning": "2MB",
+                  "maximumError": "3MB"
+                },
+                {
+                  "type": "anyComponentStyle",
+                  "maximumWarning": "10kB",
+                  "maximumError": "20kB"
+                }
+              ],
+              "outputHashing": "all"
+            },
+            "development": {
+              "optimization": false,
+              "extractLicenses": false,
+              "sourceMap": true
+            }
+          },
+          "defaultConfiguration": "production"
+        },
+        "serve": {
+          "builder": "@angular-devkit/build-angular:dev-server",
+          "configurations": {
+            "production": {
+              "buildTarget": "lead-discovery:build:production"
+            },
+            "development": {
+              "buildTarget": "lead-discovery:build:development"
+            }
+          },
+          "defaultConfiguration": "development"
+        },
+        "extract-i18n": {
+          "builder": "@angular-devkit/build-angular:extract-i18n"
+        },
+        "test": {
+          "builder": "@angular-devkit/build-angular:karma",
+          "options": {
+            "polyfills": [
+              "zone.js",
+              "zone.js/testing"
+            ],
+            "tsConfig": "tsconfig.spec.json",
+            "inlineStyleLanguage": "scss",
+            "assets": [
+              {
+                "glob": "**/*",
+                "input": "public"
+              }
+            ],
+            "styles": [
+              "src/styles.scss"
+            ],
+            "scripts": []
+          }
+        }
+      }
+    }
+  }
+}

+ 338 - 0
lead-discovery/docs/BGCHECK_INTEGRATION_ANALYSIS.md

@@ -0,0 +1,338 @@
+# 背调功能集成可行性分析
+
+> 对比 nanchi(原有完整系统)与 demo-nanchi(当前DEMO系统)的流程差异,分析背调功能集成方案。
+
+---
+
+## 一、nanchi 原有流程总览
+
+### 1.1 邮件导入流程(email-import 组件)
+
+原有系统的邮件导入是一个**三段式流程**,功能非常完整:
+
+| 阶段 | 名称 | 描述 |
+|------|------|------|
+| Stage 1 | **输入/导入** | 支持 EML 文件导入,自动提取公司名、联系人、邮箱、官网、职位等信息 |
+| Stage 2 | **产品提取与预检** | 从邮件正文+附件提取产品需求,从官网爬取产品信息,进行产品匹配 |
+| Stage 3 | **Agent 价值分析** | AI Agent 评估线索价值,判断是否值得进行背调,支持人工改判 |
+
+关键特性:
+- ✅ 集成 `EmlImportService` 解析 .eml 文件
+- ✅ 集成 `GenerateApiService`(Google搜索 + Firecrawl爬虫)
+- ✅ 集成 `AgentValueAnalysisService` 进行 AI 价值评估
+- ✅ 集成 `EmailImportWorkflowService` 进行 WebSearch 验证
+- ✅ 产品提取:邮件提取 + 官网爬取 + 产品匹配
+- ✅ 支持后台自动触发背调(`canProceedToBackgroundCheck`)
+- ✅ 背调完成后居中通知(`bgCheckNotifyVisible`)
+
+### 1.2 背调流程(lead-collection-process 组件)
+
+原有系统的背调是一个**五阶段 AI 智能分析流程**:
+
+| 阶段 | 名称 | 数据维度 | 数据来源 |
+|------|------|---------|---------|
+| 阶段 1 | 初始化数据通过 | 验证输入信息 | 表单数据 |
+| 阶段 2 | 公司基础信息 | dimension1(公司实力) | 官网爬取、企业数据库 |
+| 阶段 3 | 社媒平台验证 | dimension1.social | LinkedIn/Twitter/Instagram/YouTube(TikHub API) |
+| 阶段 4 | 决策人调查 | dimension2(决策人) | LinkedIn 员工搜索、角色匹配 |
+| 阶段 5 | 综合评级与策略 | rating + risk + strategy | AI 综合分析 |
+
+核心服务依赖:
+- `LeadBackgroundCheckService` — 背调引擎核心
+- `TikHubApiService` — 社媒数据获取(LinkedIn/Instagram/YouTube/Twitter)
+- `EmailAnalysisWorkflowService` — 邮件深度分析
+- `EnterpriseContactService` — 企业联系人管理
+- `LeadWorkflowLogService` — 工作流日志
+- `UserPermissionService` — 权限控制
+
+背调输出(三维报告):
+```
+BackgroundCheckReport {
+  meta: { date, investigator, method, level }
+  overview: { companyName, website, country, completion }
+  dimension1: { basic, financial, social, product }    // 公司实力
+  dimension2: { contact, background, communication }   // 决策人
+  dimension3: { needs, budget, time, competition }     // 采购项目
+  rating: { overallScore, ... }                        // 综合评级
+  risk: { level, factors, ... }                        // 风险评估
+  strategy: { approach, actions, timeline }             // 销售策略
+}
+```
+
+### 1.3 背调结果查看(lead-collection-review 组件)
+
+- 从 Lead 对象加载 `backgroundCheckReport`
+- 完整展示三维报告所有维度
+- 支持社媒详情弹窗(`SocialMediaDetailDialogComponent`)
+- 支持来源追踪弹窗(`SourceDetailDialogComponent`)
+- 支持产品列表弹窗(`ProductListDialogComponent`)
+
+### 1.4 静态展示页(company-bgcheck 组件)
+
+- 基于 Henry Schein Medical 的**硬编码数据**
+- 5个标签页:企业信息、社交媒体、招聘分析、互联网线索、AI分析
+- 使用 Ionic UI,与 Material 风格不同
+- **纯展示用途**,无实际 API 调用
+
+---
+
+## 二、demo-nanchi 现有流程总览
+
+### 2.1 系统架构
+
+demo-nanchi 是一个**轻量级 DEMO 系统**,使用 Mock 数据模拟完整流程:
+
+| 模块 | 路由 | 功能 |
+|------|------|------|
+| AI 工作台 | `/dashboard` | 待验证线索 + 邮件导入 + 收件箱 |
+| 线索中心 | `/list` | 看板视图(等级/画像/阶段)+ 列表视图 + 统计视图 |
+| 线索详情 | `/leads/:id` | 画像分析 + 快速筛选结果 + AI调研报告 + 跟进 |
+| 画像知识库 | `/personas` | 6类客户画像定义与策略 |
+| 产品目录 | `/products` | 12款产品的完整目录 |
+
+### 2.2 邮件导入流程
+
+demo-nanchi 的邮件导入在 Dashboard 的 "导入线索" Tab 中:
+
+```
+用户上传 .eml → EML API 解析 → 自动填充表单 → 快速筛选 → 创建线索
+```
+
+| 步骤 | 实现方式 | 与 nanchi 对比 |
+|------|---------|--------------|
+| EML 解析 | ✅ 调用真实 API(`eml.brainwork.club:8900`) | ✅ 相同 |
+| 信息提取 | ✅ 公司名/联系人/邮箱/官网/职位/产品需求 | ✅ 相同 |
+| 附件分析 | ✅ 支持附件产品需求提取 | ✅ 相同 |
+| 快速筛选 | ⚡ 使用本地规则模拟 AI 分类 | ❌ nanchi 无此步骤 |
+| 价值分析 | ❌ 无 Agent 价值分析 | ✅ nanchi 有完整 Agent |
+| 背调触发 | ❌ 无背调流程 | ✅ nanchi 自动/手动触发 |
+
+### 2.3 快速筛选(QuickScreenService)
+
+这是 demo-nanchi **独有的**轻量级分类机制:
+
+```
+邮件域名 + 邮件标题 + 邮件内容 → 关键词匹配 → 画像分类(P1-P6) + 等级评估(S/A/B/C)
+```
+
+输出 `QuickScreenResult`:
+- 客户画像(P1-P6)+ 置信度
+- 价值等级(S/A/B/C)
+- 产品相关性
+- 推荐产品
+- 推荐行动
+- 匹配关键词
+
+### 2.4 客户画像体系(6类)
+
+| 画像 | 名称 | 策略 |
+|------|------|------|
+| P1 | 医药分销商 | 发送完整产品目录 + 价盘 |
+| P2 | 工业安全供应商 | 发送 OSHA 合规产品线 |
+| P3 | 政府/机构采购 | 准备资质文件包 |
+| P4 | 品牌OEM客户 | 发送 OEM 案例 + 定制能力介绍 |
+| P5 | 电商/零售商 | 发送爆款推荐 + 利润率分析 |
+| P6 | 低质量/无效线索 | 自动归档 |
+
+### 2.5 线索详情页
+
+当前 lead-detail 页面包含:
+- ✅ 客户画像分析(画像类型 + AI判断依据 + 推荐首步动作)
+- ✅ 快速筛选结果卡片
+- ✅ 产品推荐列表
+- ✅ AI 调研报告(仅 sample/quote/order 阶段有)
+- ✅ 跟进管理(阶段推进 + 备注)
+- ✅ 销售反馈(画像/等级确认或修正)
+- ⚠️ "启动深度分析" 按钮存在,但**功能未实现**
+
+---
+
+## 三、流程对比与差异分析
+
+### 3.1 核心流程对比
+
+```
+┌─────────────────────────────────────────────────────────────────┐
+│                    nanchi 完整流程                                │
+│                                                                  │
+│  邮件导入 → 产品提取 → Agent价值分析 → 背调(5阶段) → Lead创建   │
+│     ↓            ↓           ↓              ↓            ↓       │
+│  EML解析    邮件+官网     AI决策        三维报告      CRM入库    │
+│  附件分析   产品匹配     人工改判      社媒验证      Enterprise  │
+│                                       决策人调查     ContactInfo │
+└─────────────────────────────────────────────────────────────────┘
+
+┌─────────────────────────────────────────────────────────────────┐
+│                  demo-nanchi 当前流程                             │
+│                                                                  │
+│  邮件导入 → 快速筛选 → 创建线索 → 线索管理                      │
+│     ↓           ↓          ↓          ↓                          │
+│  EML解析    画像分类    Mock数据    看板/列表                    │
+│  附件分析   等级评估    本地存储    跟进管理                      │
+│             产品推荐                                              │
+│                                                                  │
+│  ❌ 缺少:Agent价值分析 / 背调流程 / 社媒验证 / 决策人调查       │
+└─────────────────────────────────────────────────────────────────┘
+```
+
+### 3.2 数据模型对比
+
+| 字段 | nanchi Lead | demo-nanchi Lead | 说明 |
+|------|------------|------------------|------|
+| 基础信息 | ✅ | ✅ | 公司名、联系人、邮箱等 |
+| 客户画像 | ❌ | ✅ P1-P6 | demo 独有的画像体系 |
+| 价值等级 | ❌ | ✅ S/A/B/C | demo 独有的等级体系 |
+| 快速筛选结果 | ❌ | ✅ QuickScreenResult | demo 独有 |
+| 背调报告 | ✅ backgroundCheckReport | ❌ | nanchi 独有 |
+| 决策人 | ✅ decisionMaker | ❌ | nanchi 独有 |
+| 需求信息 | ✅ requirements(深度) | ❌ | nanchi 独有 |
+| 风险评估 | ✅ risk | ❌ | nanchi 独有 |
+| 销售策略 | ✅ strategy | ❌ | nanchi 独有 |
+| AI调研报告 | ❌ | ✅ aiResearchReport | demo 的简化版 |
+| 销售反馈 | ❌ | ✅ salesFeedback | demo 独有 |
+| 跟进阶段 | ❌ | ✅ followUpStage | demo 独有 |
+| 产品推荐 | ✅ extractedProducts | ✅ suggestedProducts | 均有,维度不同 |
+
+---
+
+## 四、背调集成可行性评估
+
+### 4.1 ✅ 可以集成的理由
+
+1. **流程天然衔接**:demo-nanchi 的 "快速筛选" 之后,正好缺少深度分析环节,背调可以无缝填补这个空白
+2. **数据入口已就绪**:EML 导入已经能提取公司名、邮箱、官网等背调所需的核心输入
+3. **"启动深度分析" 按钮已存在**:lead-detail 页面已预留了深度分析的入口,但功能未实现
+4. **技术栈一致**:两个项目都是 Angular + Material Design,组件可以复用
+5. **画像体系可增强**:背调数据可以大幅提升画像分类的准确性和置信度
+
+### 4.2 ⚠️ 集成挑战
+
+| 挑战 | 说明 | 建议方案 |
+|------|------|---------|
+| 服务依赖复杂 | 背调依赖 6+ 个后端服务 | 分阶段集成,先 Mock 后真实 |
+| Parse Server | nanchi 使用 FmodeParse,demo 无后端 | 需要搭建或对接后端 |
+| TikHub API | 社媒数据需要 API Key 和付费 | 可先用 Mock 数据演示 |
+| 数据模型差异 | 两套 Lead 模型不同 | 需要模型合并或适配层 |
+| 流程复杂度 | 背调 5 阶段耗时较长(3-8分钟) | 可简化为关键阶段 |
+
+### 4.3 建议集成方案
+
+#### 方案一:轻量集成(推荐 · DEMO 级别)
+
+在现有 demo-nanchi 的基础上,增加一个**模拟背调流程**:
+
+```
+现有流程:邮件导入 → 快速筛选 → 创建线索
+新增流程:                              ↓
+                              线索详情 → 启动深度分析(背调)
+                                          ↓
+                              模拟 5 阶段进度展示
+                                          ↓
+                              展示三维背调报告(Mock数据)
+```
+
+**实现要点**:
+1. 在 `lead-detail` 页面实现 "启动深度分析" 功能
+2. 添加背调进度展示组件(5阶段进度条)
+3. 使用 Mock 数据生成背调报告
+4. 新增背调报告展示页面(复用 nanchi 的 review 组件设计)
+5. 将背调结果合并到 Lead 模型中
+
+**新增路由**:
+```typescript
+{ path: 'leads/:id/bgcheck', loadComponent: () => import('./pages/bgcheck/bgcheck.component') }
+```
+
+**新增数据模型扩展**:
+```typescript
+// 扩展 Lead 接口
+export interface Lead {
+  // ... 现有字段 ...
+
+  /** 背调相关 */
+  hasBackgroundCheck: boolean;
+  backgroundCheckAt?: Date;
+  backgroundCheckReport?: {
+    dimension1: { basic: any; financial: any; social: any; product: any };
+    dimension2: { contact: any; background: any; communication: any };
+    dimension3: { needs: any; budget: any; time: any };
+    rating: { overallScore: number; level: string };
+    risk: { level: string; factors: string[] };
+    strategy: { approach: string; actions: string[] };
+  };
+}
+```
+
+#### 方案二:深度集成(生产级别)
+
+将 nanchi 的完整背调服务移植到 demo-nanchi:
+
+1. 移植 `LeadBackgroundCheckService` 及其依赖
+2. 对接 Parse Server 后端
+3. 集成 TikHub API(社媒数据)
+4. 集成 Firecrawl(官网爬取)
+5. 合并两套 Lead 数据模型
+6. 实现完整的背调 → 报告 → CRM 入库流程
+
+---
+
+## 五、建议的集成路线图
+
+### Phase 1:UI 框架搭建(1-2天)
+
+- [ ] 新增背调结果展示页面 `/leads/:id/bgcheck`
+- [ ] 在 lead-detail 实现 "启动深度分析" 按钮功能
+- [ ] 添加背调进度展示组件(5阶段动画)
+- [ ] 使用 Mock 数据填充背调报告
+
+### Phase 2:数据模型融合(1天)
+
+- [ ] 扩展 `Lead` 接口,增加背调相关字段
+- [ ] 扩展 `MockDataService`,为部分线索生成模拟背调数据
+- [ ] 在 lead-detail 中展示背调摘要卡片
+
+### Phase 3:流程串联(1-2天)
+
+- [ ] 实现 "邮件导入 → 快速筛选 → 背调" 的完整流程
+- [ ] 在 Dashboard 待验证列表中增加 "一键背调" 按钮
+- [ ] 背调完成后自动更新画像置信度和价值等级
+
+### Phase 4:真实服务对接(可选 · 3-5天)
+
+- [ ] 对接 Parse Server 后端
+- [ ] 移植 `LeadBackgroundCheckService`
+- [ ] 集成 TikHub API
+- [ ] 实现真实的社媒验证和决策人调查
+
+---
+
+## 六、总结
+
+| 维度 | 结论 |
+|------|------|
+| **可行性** | ✅ 完全可行,demo-nanchi 的流程架构天然支持背调环节的插入 |
+| **切入点** | lead-detail 页面的 "启动深度分析" 按钮是最佳切入点 |
+| **最小可行方案** | 使用 Mock 数据模拟背调流程 + 展示三维报告,约 2-3 天可完成 |
+| **完整方案** | 移植 nanchi 的背调服务,需要后端支持,约 5-7 天 |
+| **核心价值** | 背调可以将画像置信度从 60-90% 提升到 85-95%,并提供决策人信息和销售策略 |
+
+### 推荐的集成位置
+
+```
+┌─────────────────────────────────────────────────────────────────┐
+│                  demo-nanchi 集成背调后的流程                     │
+│                                                                  │
+│  邮件导入 → 快速筛选 → 创建线索 → [背调] → 线索管理             │
+│     ↓           ↓          ↓         ↓          ↓                │
+│  EML解析    画像分类    本地存储   三维报告    看板/列表          │
+│  附件分析   等级评估               社媒验证    跟进管理           │
+│  产品提取   产品推荐               决策人      销售策略           │
+│                                    评级/风险                      │
+└─────────────────────────────────────────────────────────────────┘
+```
+
+---
+
+*文档生成时间:2026-02-12*
+*分析范围:nanchi/ltc-nanchi/src/modules/bgcheck + demo-nanchi/lead-discovery*
+

+ 410 - 0
lead-discovery/docs/FEASIBILITY_ANALYSIS.md

@@ -0,0 +1,410 @@
+# 犀牛急救 · 客户发掘系统 — 真实业务可行性分析
+
+> 分析日期:2026-02-11  
+> 分析对象:`lead-discovery` 前端 Demo 全部 7 个页面 + 2 个服务  
+> 分析维度:每个功能模块的**设计意图 → 当前实现 → 技术可行性 → 落地差距 → 建议方案**
+
+---
+
+## 一、系统全局架构评估
+
+### 当前架构
+
+```
+Angular 19 SPA(纯前端)
+├── MockDataService        ← 所有数据硬编码,无后端
+├── QuickScreenService     ← 模拟 AI 分类,规则写死
+├── EML 解析 API           ← 唯一的真实外部服务调用
+└── 7 个页面组件            ← 纯展示 + 本地状态操作
+```
+
+### 核心问题
+
+| 维度 | 现状 | 生产要求 |
+|------|------|----------|
+| 数据持久化 | 内存中的硬编码数组,刷新即丢 | 数据库 + API |
+| AI 能力 | if-else 关键词匹配 | LLM / ML 模型 |
+| 邮件接入 | 硬编码 6 封模拟邮件 | IMAP/SMTP 或邮件网关 |
+| 多用户 | 无认证、无权限 | 登录 + RBAC |
+| 数据来源 | 仅邮件 + 手动录入 | 展会、平台 API、爬虫等 |
+
+---
+
+## 二、逐页面/模块深度分析
+
+---
+
+### 1. AI 仪表盘(Dashboard)
+
+**设计意图**:一屏展示 AI 每日批量处理结果,销售人员只需验证。
+
+#### ✅ 可行的部分
+
+| 功能 | 可行性 | 说明 |
+|------|--------|------|
+| 今日统计卡片(新线索/待验证/已确认/管线总值) | ✅ 完全可行 | 标准 BI 聚合查询,任何数据库都能支持 |
+| AI 批次状态展示 | ✅ 可行 | 需要后端任务调度系统(如 Celery / BullMQ) |
+| 待验证线索列表 + 确认/无效操作 | ✅ 可行 | 标准 CRUD,加上状态机流转 |
+| 画像分布柱状图 | ✅ 可行 | 简单的 GROUP BY 聚合 |
+
+#### ⚠️ 需要补足的部分
+
+| 功能 | 当前状态 | 落地所需 |
+|------|----------|----------|
+| "AI 每日批量处理" | 硬编码的 `discoveryBatches` 数组 | 真实的定时任务系统:每日凌晨拉取新邮件 → 调用 LLM 分类 → 写入数据库 → 生成批次报告 |
+| 最近活动流 | 硬编码 6 条假数据 | 需要事件总线 / 操作日志表 |
+| 画像分类准确性 | if-else 关键词匹配 | 需要 LLM(GPT-4o / Claude)或微调模型 |
+
+#### 💡 技术建议
+
+- **定时批处理**:使用 Node.js + BullMQ 或 Python + Celery,每日 08:00 触发
+- **AI 分类**:GPT-4o 的 structured output 模式,输入邮件正文,输出 `{persona, grade, confidence, keywords}`
+- **预估成本**:每封邮件约 $0.01-0.03(GPT-4o-mini),日均 50 封 ≈ $0.5-1.5/天
+
+---
+
+### 2. 邮件收件箱(Inbox)
+
+**设计意图**:接收邮件 → 快速筛选 → 创建线索的核心工作流。
+
+#### ✅ 可行的部分
+
+| 功能 | 可行性 | 说明 |
+|------|--------|------|
+| 邮件列表 + 详情阅读 | ✅ 可行 | 对接 IMAP 协议即可(如 Gmail API / Microsoft Graph) |
+| 附件展示与下载 | ✅ 可行 | 邮件附件存储到 OSS/S3 |
+| EML 文件导入 + 解析 | ✅ **已实现** | 已对接 `eml.brainwork.club` API,含附件分析和产品需求提取 |
+| 快速筛选 → 创建线索 | ✅ 可行 | 筛选逻辑替换为 LLM 调用即可 |
+| 批量筛选 | ✅ 可行 | 并发调用 LLM API + 进度反馈 |
+
+#### ⚠️ 需要补足的部分
+
+| 功能 | 当前状态 | 落地所需 |
+|------|----------|----------|
+| 邮件实时接收 | 硬编码 6 封模拟邮件 | IMAP 轮询 / Webhook(Gmail Push / Microsoft Graph Subscription) |
+| 快速筛选 AI | `classifyByDomain()` 用 if-else | 替换为 LLM API 调用,Prompt 中嵌入 6 个画像定义 |
+| 筛选结果持久化 | 内存操作,刷新丢失 | 后端 API + 数据库 |
+| EML 导入后的线索关联 | 创建了线索但未持久化 | 需要后端存储 |
+
+#### 💡 技术建议
+
+- **邮件接入方案对比**:
+
+| 方案 | 复杂度 | 实时性 | 推荐场景 |
+|------|--------|--------|----------|
+| IMAP 轮询(每 5 分钟) | 低 | 中 | MVP 阶段 |
+| Gmail API + Pub/Sub | 中 | 高 | 用 Gmail 的团队 |
+| Microsoft Graph + Webhook | 中 | 高 | 用 Outlook 的团队 |
+| 自建邮件网关(Postfix) | 高 | 最高 | 需要完全控制 |
+
+- **AI 筛选 Prompt 设计**(已有良好基础):
+
+```
+你是一个外贸线索分类专家。根据以下邮件内容,判断客户画像:
+P1-医药分销商 / P2-工业安全供应商 / P3-政府机构采购 / P4-品牌OEM / P5-电商零售 / P6-低质量
+
+输出 JSON:{ persona, personaLabel, valueGrade, confidence, matchedKeywords[], mainBusiness }
+```
+
+- **EML 导入已具备真实能力**:当前的 EML 解析 API 是整个系统中**唯一真正可用的外部服务**,可直接用于生产
+
+---
+
+### 3. 线索看板(Kanban)
+
+**设计意图**:多维度可视化线索状态,支持按等级/画像/阶段三种视图。
+
+#### ✅ 可行的部分
+
+| 功能 | 可行性 | 说明 |
+|------|--------|------|
+| 三种看板视图切换 | ✅ 完全可行 | 纯前端 UI 逻辑,数据从 API 获取即可 |
+| 按客户类型过滤 | ✅ 可行 | 标准筛选查询 |
+| 线索卡片展示 | ✅ 可行 | 数据模型设计合理 |
+
+#### ⚠️ 需要补足的部分
+
+| 功能 | 当前状态 | 落地所需 |
+|------|----------|----------|
+| 拖拽排序/移动阶段 | ❌ 未实现 | 需要 Angular CDK DragDrop + 后端状态更新 API |
+| 实时协作 | ❌ 无 | WebSocket / SSE 推送(多人同时操作看板) |
+| 数据持久化 | 内存数据 | 后端 API |
+
+#### 💡 技术建议
+
+- 看板的 UI 设计已经很成熟,**落地成本低**
+- 拖拽功能用 `@angular/cdk/drag-drop` 即可,约 1-2 天工作量
+- 建议先不做实时协作,MVP 阶段用乐观更新 + 冲突提示
+
+---
+
+### 4. 线索管理(Lead List)
+
+**设计意图**:全量线索的表格视图 + 按画像分组 + 统计面板。
+
+#### ✅ 可行的部分
+
+| 功能 | 可行性 | 说明 |
+|------|--------|------|
+| 列表视图 + 搜索过滤 | ✅ 完全可行 | 标准数据表格 |
+| 按画像分组视图 | ✅ 可行 | 前端分组 + 折叠 |
+| 统计视图(画像/等级/阶段分布) | ✅ 可行 | 后端聚合查询 |
+
+#### ⚠️ 需要补足的部分
+
+| 功能 | 当前状态 | 落地所需 |
+|------|----------|----------|
+| 分页 | ❌ 无(全量加载) | 线索量超过 100 条后必须分页 |
+| 排序 | ❌ 无 | 服务端排序 |
+| 批量操作 | ❌ 无 | 批量确认/批量分配/批量导出 |
+| 导出 Excel | ❌ 无 | 后端生成 + 下载 |
+
+#### 💡 技术建议
+
+- 数据量 < 500 条时前端分页足够,> 500 条需服务端分页
+- 建议增加「导出 Excel」功能,外贸团队强需求
+
+---
+
+### 5. 线索详情(Lead Detail)
+
+**设计意图**:单条线索的全景视图 + AI 画像分析 + 销售验证 + 产品推荐 + 跟进管理。
+
+#### ✅ 可行的部分
+
+| 功能 | 可行性 | 说明 |
+|------|--------|------|
+| 客户画像分析卡片 | ✅ 可行 | 数据结构完善,展示逻辑清晰 |
+| 快速筛选结果展示 | ✅ 可行 | 已有完整的数据模型 |
+| 销售验证表单(确认/修改画像) | ✅ **高价值** | 人工反馈 → 可用于微调 AI 模型 |
+| 跟进阶段时间线 | ✅ 可行 | 状态机设计合理 |
+| 推荐产品列表 | ✅ 可行 | 基于客户类型的规则匹配 |
+
+#### ⚠️ 需要补足的部分
+
+| 功能 | 当前状态 | 落地所需 |
+|------|----------|----------|
+| AI 调研报告 | 硬编码模拟文本 | 需要真实的 AI 调研流程(见下方详述) |
+| "深度分析"按钮 | 点击后弹 SnackBar "Phase 3 上线" | 需要实现完整的深度分析 Pipeline |
+| 验证结果反馈循环 | 仅修改前端状态 | 需要存储反馈 → 定期用反馈数据优化 AI 模型 |
+
+#### 💡 AI 调研报告的真实实现方案
+
+这是系统中**技术挑战最大**的功能:
+
+```
+触发深度分析
+    ↓
+Step 1: 抓取公司官网(Puppeteer / Playwright)
+    ↓
+Step 2: 提取关键信息(LLM 结构化提取)
+    - 公司规模、主营业务、产品线
+    - 联系方式、社交媒体
+    ↓
+Step 3: 产品匹配分析(LLM + 本地产品库)
+    - 匹配我方产品 → 客户需求
+    - 计算利润空间
+    ↓
+Step 4: 竞品分析(可选,需要爬虫)
+    ↓
+Step 5: 生成销售策略建议(LLM)
+    ↓
+输出结构化报告(3-5 分钟)
+```
+
+**技术可行性**:✅ 可行,但需要注意:
+- 官网抓取可能被反爬(需要代理池)
+- 耗时较长(3-5 分钟),需要异步任务 + 进度推送
+- LLM 调用成本:每次深度分析约 $0.05-0.15
+
+---
+
+### 6. 客户画像知识库(Personas)
+
+**设计意图**:定义和管理 6 类客户画像,作为 AI 分类的知识基础。
+
+#### ✅ 可行的部分
+
+| 功能 | 可行性 | 说明 |
+|------|--------|------|
+| 6 类画像定义展示 | ✅ **设计优秀** | P1-P6 的定义、关键词、策略体系完整 |
+| AI 行动规则(4 步流程) | ✅ 可行 | 可直接作为 LLM Prompt 的一部分 |
+| 销售经验备注(可添加) | ✅ **高价值** | 团队知识沉淀,可反哺 AI |
+| 代表线索预览 | ✅ 可行 | 简单查询 |
+
+#### ⚠️ 需要补足的部分
+
+| 功能 | 当前状态 | 落地所需 |
+|------|----------|----------|
+| 画像定义编辑 | 硬编码在 `lead.model.ts` | 需要后端 CRUD API,支持管理员编辑画像规则 |
+| 关键词管理 | 固定数组 | 支持增删改关键词,修改后实时影响 AI 分类 |
+| 经验备注持久化 | 仅内存操作 | 需要数据库存储 |
+| 画像效果统计 | 硬编码的 `leadCount` 和 `conversionRate` | 需要从真实数据计算 |
+
+#### 💡 技术建议
+
+- 画像知识库是整个系统的**核心资产**,当前的 6 类画像定义质量很高
+- 建议将画像定义存入数据库,作为 LLM Prompt 的动态模板
+- 销售经验备注可以用 RAG(检索增强生成)方式注入 AI 上下文
+
+---
+
+### 7. 产品目录(Product Catalog)
+
+**设计意图**:展示公司产品线,支持搜索和按客户类型过滤。
+
+#### ✅ 可行的部分
+
+| 功能 | 可行性 | 说明 |
+|------|--------|------|
+| 产品卡片展示 | ✅ 完全可行 | 标准商品目录 |
+| 搜索 + 客户类型过滤 | ✅ 可行 | 简单查询 |
+| 价格展示(批发/零售) | ✅ 可行 | — |
+
+#### ⚠️ 需要补足的部分
+
+| 功能 | 当前状态 | 落地所需 |
+|------|----------|----------|
+| 产品图片 | ❌ 无图片 | 需要产品图片上传和 CDN |
+| 库存状态 | ❌ 无 | 对接 ERP/库存系统 |
+| 价格策略 | 固定价格 | 阶梯价格、客户专属价格 |
+| 产品编辑 | 硬编码 | 后台管理界面 |
+
+---
+
+### 8. 快速筛选服务(QuickScreenService)
+
+**设计意图**:模拟 AI 对邮件/手动输入进行快速分类。
+
+#### 当前实现 vs 真实需求
+
+| 维度 | 当前(模拟) | 生产(真实) |
+|------|-------------|-------------|
+| 分类方法 | `classifyByDomain()` — 关键词 if-else | LLM API 调用(GPT-4o / Claude) |
+| 国家识别 | 域名后缀推断(`.de` → DE) | IP 地理定位 + LLM 推断 |
+| 置信度 | 硬编码数值 | LLM 自评估 + 历史校准 |
+| 产品推荐 | 按客户类型固定映射 | LLM 理解需求 → 语义匹配产品库 |
+| 耗时 | `simulateDelay(1500ms)` | 真实 LLM 调用 2-5 秒 |
+
+#### 💡 真实实现方案
+
+```typescript
+// 生产环境的 screenEmail 伪代码
+async screenEmail(email: Email): Promise<QuickScreenResult> {
+  // 1. 调用 LLM 进行结构化分析
+  const llmResult = await this.openai.chat.completions.create({
+    model: 'gpt-4o-mini',
+    response_format: { type: 'json_schema', schema: screenResultSchema },
+    messages: [
+      { role: 'system', content: this.buildSystemPrompt() },  // 包含 6 个画像定义
+      { role: 'user', content: `邮件主题:${email.subject}\n正文:${email.body}` }
+    ]
+  });
+
+  // 2. 解析结果
+  const parsed = JSON.parse(llmResult.choices[0].message.content);
+
+  // 3. 基于画像匹配产品(规则 + 语义混合)
+  const products = await this.matchProducts(parsed.persona, email.body);
+
+  return { ...parsed, suggestedProducts: products };
+}
+```
+
+**可行性**:✅ 完全可行,GPT-4o-mini 的 JSON 模式输出稳定,成本低($0.01/次)
+
+---
+
+## 三、核心 AI 能力可行性总结
+
+| AI 功能 | 技术成熟度 | 准确率预估 | 成本/次 | 建议 |
+|---------|-----------|-----------|---------|------|
+| 邮件画像分类(P1-P6) | ⭐⭐⭐⭐⭐ | 85-92% | $0.01 | GPT-4o-mini,Prompt 中嵌入画像定义 |
+| 价值等级评估(S/A/B/C) | ⭐⭐⭐⭐ | 80-88% | 同上 | 与画像分类一起输出 |
+| 关键词提取 | ⭐⭐⭐⭐⭐ | 90%+ | 同上 | LLM 原生能力 |
+| 产品需求提取(从邮件) | ⭐⭐⭐⭐ | 85%+ | $0.02 | 已有 EML API 支持 |
+| 官网抓取 + 分析 | ⭐⭐⭐ | 75-85% | $0.05-0.15 | 需要 Puppeteer + LLM,反爬是挑战 |
+| 竞品分析 | ⭐⭐ | 60-75% | $0.10+ | 数据源有限,建议作为辅助参考 |
+| 销售话术生成 | ⭐⭐⭐⭐ | N/A | $0.02 | LLM 强项,但需要人工审核 |
+
+---
+
+## 四、数据源接入可行性
+
+### 当前系统支持的线索来源
+
+| 来源 | 代码中的 source 值 | 当前状态 | 真实接入方案 |
+|------|-------------------|----------|-------------|
+| 邮件 | `'email'` | ✅ 有 EML 导入 + 模拟收件箱 | IMAP 轮询 / Gmail API |
+| 手动录入 | `'manual'` | ✅ 有表单 | 已可用 |
+| 展会 | `'exhibition'` | ❌ 仅硬编码 | 批量 CSV 导入 / 名片 OCR |
+| 平台 | `'platform'` | ❌ 仅硬编码 | 阿里国际站 API / Made-in-China API |
+| AI 发现 | `'ai_discovery'` | ❌ 仅定义,无实现 | 定时爬虫 + LLM 筛选 |
+
+### 各来源接入难度
+
+| 来源 | 难度 | 工期 | 说明 |
+|------|------|------|------|
+| 邮件(IMAP) | ⭐⭐ | 1-2 周 | 成熟方案,`imapflow` 库 |
+| 邮件(Gmail API) | ⭐⭐ | 1 周 | 需要 OAuth 2.0 |
+| CSV 批量导入 | ⭐ | 2-3 天 | 前端解析 + 后端存储 |
+| 阿里国际站 | ⭐⭐⭐ | 2-3 周 | 需要开放平台账号 + API 对接 |
+| 名片 OCR | ⭐⭐ | 1 周 | 用现成 OCR API(百度/腾讯) |
+| 网络爬虫发现 | ⭐⭐⭐⭐ | 3-4 周 | 反爬、数据清洗、法律合规 |
+
+---
+
+## 五、落地路线图建议
+
+### Phase 1:MVP(4-6 周)— 让系统真正能用
+
+```
+✅ 后端 API + 数据库(NestJS/Express + PostgreSQL)
+✅ 用户认证(JWT)
+✅ 邮件接入(IMAP 轮询,每 5 分钟)
+✅ AI 快速筛选(GPT-4o-mini 替换 if-else)
+✅ 线索 CRUD + 持久化
+✅ EML 导入(已有,保留)
+✅ CSV 批量导入(展会/平台线索)
+```
+
+### Phase 2:增强(3-4 周)— 提升效率
+
+```
+✅ AI 每日批量处理(定时任务)
+✅ 看板拖拽
+✅ 画像知识库可编辑
+✅ 产品目录管理后台
+✅ 销售验证反馈收集
+✅ 数据导出(Excel)
+```
+
+### Phase 3:智能化(4-6 周)— AI 深度能力
+
+```
+✅ AI 深度调研报告(官网抓取 + 分析)
+✅ 产品语义匹配(向量搜索)
+✅ 销售话术自动生成
+✅ 基于反馈的模型优化
+✅ 平台 API 对接(阿里国际站等)
+```
+
+---
+
+## 六、结论
+
+### 整体评价
+
+| 维度 | 评分 | 说明 |
+|------|------|------|
+| **业务逻辑设计** | ⭐⭐⭐⭐⭐ | 画像体系、分类流程、跟进阶段设计专业且完整 |
+| **数据模型** | ⭐⭐⭐⭐⭐ | Lead / Email / Product / Persona 模型覆盖全面 |
+| **UI/UX 质量** | ⭐⭐⭐⭐ | Material Design 风格统一,交互流畅 |
+| **AI 功能真实性** | ⭐⭐ | 核心 AI 全部是模拟,需要替换为真实 LLM |
+| **数据持久化** | ⭐ | 无后端,刷新全丢 |
+| **生产就绪度** | ⭐⭐ | 优秀的原型,但距离生产还需 Phase 1 的全部工作 |
+
+### 一句话总结
+
+> **这是一个业务逻辑设计极其优秀的原型系统。** 画像体系(P1-P6)、分类流程、产品匹配规则都经过深思熟虑,可直接指导生产开发。当前最大的差距是**缺少后端和真实 AI 能力**,但所有设计的功能在 2026 年的技术条件下**均可实现**,核心 AI 分类功能使用 GPT-4o-mini 即可达到 85%+ 准确率,成本可控(日均 $1-3)。建议按 Phase 1 → 2 → 3 的路线图推进,4-6 周即可交付可用的 MVP。
+

+ 241 - 0
lead-discovery/docs/MERGE_ANALYSIS.md

@@ -0,0 +1,241 @@
+# 邮件收件箱 × AI 仪表盘 — 合并/取消可行性分析
+
+> 分析日期:2026-02-11  
+> 核心问题:邮件收件箱(Inbox)是否可以取消,或与 AI 仪表盘(Dashboard)合并?
+
+---
+
+## 一、先搞清楚:两个页面到底各做了什么?
+
+### Dashboard(AI 仪表盘)—— 处理的是「已经变成线索的结果」
+
+| 功能区块 | 做了什么 |
+|---------|---------|
+| 统计卡片 | 今日新线索数 / 待验证数 / 已确认数 / 管线总值 |
+| AI 批次状态 | 展示"AI 今日批次"处理了多少条、发现多少线索 |
+| 待验证列表 | 展示 AI 已经分类好的线索,销售确认/修改/标记无效 |
+| 画像分布图 | 本周各画像(P1-P6)的占比柱状图 |
+| 最近活动流 | 系统操作日志 |
+| 快捷操作 | 跳转到收件箱/看板/画像库的按钮 |
+
+**数据来源**:`mockData.leads`(已经是线索了)+ `mockData.discoveryBatches`
+
+### Inbox(邮件收件箱)—— 处理的是「还没变成线索的原始邮件」
+
+| 功能区块 | 做了什么 |
+|---------|---------|
+| 邮件列表 | 展示 6 封原始邮件,未读/已读/已筛选状态 |
+| 邮件详情 | 完整邮件正文 + 发件人/收件人/抄送 + 附件展示下载 |
+| 快速筛选 | 对单封邮件执行 AI 分类 → 输出画像/等级/推荐产品 |
+| 批量筛选 | 一键对所有未筛选邮件执行 AI 分类 |
+| 筛选结果卡片 | 展示分类结果 → 创建线索 / 深度分析 / 标记无效 |
+| EML 导入 | 上传 .eml 文件 → 调用真实 API 解析 → 自动填充表单 |
+| 产品需求提取 | 从邮件正文/附件中提取产品需求列表 |
+| 手动录入 | 填写公司名/联系人/邮箱 → 快速筛选 |
+
+**数据来源**:`mockData.emails`(原始邮件)+ EML 解析 API(真实外部服务)
+
+---
+
+## 二、两个页面的关系图
+
+```
+原始邮件(Inbox 处理)
+    │
+    ├── 邮件阅读 ← 只有 Inbox 有
+    ├── 附件查看/下载 ← 只有 Inbox 有
+    ├── EML 文件导入 ← 只有 Inbox 有
+    ├── 产品需求提取 ← 只有 Inbox 有
+    │
+    ▼ [快速筛选 / AI 分类]
+    │
+    ├── 筛选结果展示 ← Inbox 有(ScreenResultCard)
+    ├── 创建线索 ← Inbox 有
+    │
+    ▼
+线索(Dashboard 处理)
+    │
+    ├── 统计总览 ← 只有 Dashboard 有
+    ├── 待验证列表 ← 只有 Dashboard 有
+    ├── 确认/修改/标记无效 ← 只有 Dashboard 有
+    ├── 画像分布图 ← 只有 Dashboard 有
+    └── 活动流 ← 只有 Dashboard 有
+```
+
+**关键发现:两个页面处理的是同一条数据管线的「上游」和「下游」,几乎没有功能重叠。**
+
+---
+
+## 三、三种方案对比
+
+### 方案 A:直接取消 Inbox
+
+| 维度 | 评估 |
+|------|------|
+| **可行性** | ⚠️ **有风险** |
+| 丢失的功能 | ❌ 邮件正文阅读<br>❌ 附件查看/下载<br>❌ EML 文件导入(唯一真实 API)<br>❌ 产品需求提取<br>❌ 手动录入入口<br>❌ 单封邮件级别的筛选操作 |
+| 前提条件 | AI 必须 100% 自动处理所有邮件,销售人员永远不需要看原始邮件 |
+| 现实问题 | 销售人员经常需要回看邮件原文来判断 AI 分类是否正确 |
+
+**结论:不建议直接取消。** 除非 AI 准确率达到 95%+ 且不再需要 EML 导入功能。
+
+---
+
+### 方案 B:合并为一个页面(✅ 推荐)
+
+将 Dashboard 作为主页面,把 Inbox 的核心功能嵌入其中。
+
+#### 合并后的页面结构
+
+```
+AI 智能工作台(合并后)
+├── 📊 顶部统计栏(来自 Dashboard)
+│   └── 今日新线索 | 待验证 | 已确认 | 管线总值
+│
+├── 🤖 AI 批次状态(来自 Dashboard)
+│   └── "AI 今日处理 47 条,发现 12 条新线索"
+│
+├── 📋 主工作区(Tab 切换)
+│   ├── Tab 1: 待验证线索(来自 Dashboard 的待验证列表)
+│   │   └── 确认 / 修改 / 无效
+│   │
+│   ├── Tab 2: 新邮件处理(来自 Inbox 的核心功能)
+│   │   ├── 未处理邮件列表(精简版,不需要完整收件箱 UI)
+│   │   ├── 点击展开 → 邮件摘要 + 附件 + 快速筛选按钮
+│   │   └── 筛选结果 → 直接创建线索
+│   │
+│   └── Tab 3: 导入线索(来自 Inbox 的 EML 导入 + 手动录入)
+│       ├── EML 文件上传
+│       ├── 产品需求提取
+│       └── 手动填写表单
+│
+├── 📈 右侧面板
+│   ├── 画像分布图(来自 Dashboard)
+│   └── 最近活动(来自 Dashboard)
+```
+
+#### 合并的好处
+
+| 好处 | 说明 |
+|------|------|
+| **减少页面跳转** | 销售人员不再需要在 Dashboard ↔ Inbox 之间来回切换 |
+| **统一工作入口** | 打开系统 → 一个页面完成所有日常工作 |
+| **逻辑更清晰** | "AI 处理完 → 我来验证" 的流程在一个页面内闭环 |
+| **侧边栏更简洁** | 少一个导航项,降低认知负担 |
+
+#### 合并的代价
+
+| 代价 | 严重程度 | 解决方案 |
+|------|----------|----------|
+| 页面变复杂 | ⚠️ 中 | 用 Tab 切换分区,默认只显示"待验证" |
+| 邮件详情展示空间不够 | ⚠️ 中 | 用侧边抽屉(Drawer)展示邮件全文 |
+| 组件代码量大 | ⚠️ 低 | 拆分为子组件,保持可维护性 |
+
+---
+
+### 方案 C:保留两个页面,但改变定位
+
+| 页面 | 新定位 |
+|------|--------|
+| Dashboard | **日常工作台**:统计 + 待验证 + 快捷操作(保持不变) |
+| Inbox | **邮件管理**:仅保留 EML 导入 + 手动录入,去掉模拟收件箱 |
+
+这个方案的逻辑是:如果 AI 会自动处理邮件,那 Inbox 不再需要"收件箱"的 UI,只需要保留"导入"功能。
+
+---
+
+## 四、推荐方案:B(合并)的详细设计
+
+### 合并后的导航栏变化
+
+```
+之前(7 项):                    之后(6 项):
+├── AI 仪表盘                     ├── AI 工作台 ← 合并后
+├── 邮件收件箱 ← 取消              ├── 线索看板
+├── 线索看板                      ├── 线索管理
+├── 线索管理                      ├── 画像知识库
+├── 画像知识库                    ├── 产品目录
+├── 产品目录
+```
+
+### 合并后的数据流
+
+```
+                    ┌─────────────────────────────┐
+                    │     AI 智能工作台(合并后)      │
+                    │                             │
+  邮件自动拉取 ──────▶ AI 批量处理 ──▶ 待验证列表 ──▶ 确认/修改
+                    │                             │
+  EML 手动导入 ──────▶ AI 快速筛选 ──▶ 创建线索 ────▶ 进入看板
+                    │                             │
+  手动录入 ──────────▶ AI 快速筛选 ──▶ 创建线索 ────▶ 进入看板
+                    └─────────────────────────────┘
+```
+
+### 合并后需要保留的 Inbox 功能清单
+
+| Inbox 功能 | 保留? | 放在哪里 |
+|-----------|--------|---------|
+| 邮件列表(6封模拟邮件) | ❌ 不保留 | AI 自动处理,不再需要手动浏览 |
+| 邮件详情阅读 | ✅ 简化保留 | 待验证卡片上加"查看原始邮件"按钮,弹出抽屉 |
+| 附件展示/下载 | ✅ 保留 | 跟随邮件详情抽屉 |
+| 快速筛选(单封) | ❌ 不保留 | AI 已自动完成,不需要手动触发 |
+| 批量筛选 | ❌ 不保留 | AI 每日批次自动完成 |
+| EML 导入 | ✅ **必须保留** | 放在 Tab 3"导入线索"中 |
+| 产品需求提取 | ✅ **必须保留** | 跟随 EML 导入 |
+| 手动录入表单 | ✅ 保留 | 放在 Tab 3"导入线索"中 |
+| 筛选结果卡片 | ✅ 保留 | 用于导入后的即时反馈 |
+
+### 合并后的 AI 自动化流程(生产环境)
+
+```
+每日 08:00 自动触发
+    │
+    ├── 1. 拉取新邮件(IMAP / Gmail API)
+    ├── 2. 对每封邮件调用 LLM 分类
+    │      ├── 输出:画像(P1-P6) + 等级(S/A/B/C) + 置信度
+    │      └── 输出:匹配产品 + 推荐动作
+    ├── 3. 自动创建线索(状态=待验证)
+    ├── 4. 生成批次报告
+    │
+    ▼
+销售人员上班打开"AI 工作台"
+    │
+    ├── 看到:今日 AI 发现 12 条新线索
+    ├── 逐条验证:确认 / 修改画像 / 标记无效
+    ├── 需要时:点击"查看原始邮件"看邮件全文
+    └── 偶尔:手动导入 EML / 手动录入
+```
+
+**这就是你说的"AI 仪表盘会自动分析邮件"的完整实现。在这个流程下,销售人员确实不需要一个独立的"收件箱"页面。**
+
+---
+
+## 五、合并的技术工作量评估
+
+| 工作项 | 预估工时 | 说明 |
+|--------|---------|------|
+| Dashboard 组件重构(加 Tab) | 4h | 加入 MatTabsModule,分三个 Tab |
+| 迁移 EML 导入功能 | 2h | 从 Inbox 搬到新 Tab |
+| 迁移手动录入功能 | 1h | 从 Inbox 搬到新 Tab |
+| 添加"查看原始邮件"抽屉 | 3h | MatSidenav 或 Dialog 展示邮件全文 |
+| 迁移 ScreenResultCard 使用 | 1h | 导入后的筛选结果展示 |
+| 删除 Inbox 组件 + 路由 | 0.5h | 清理代码 |
+| 更新侧边栏导航 | 0.5h | 去掉"邮件收件箱"入口 |
+| 测试 | 2h | 确保所有功能正常 |
+| **总计** | **约 14h(2 天)** | |
+
+---
+
+## 六、最终结论
+
+| 方案 | 推荐度 | 理由 |
+|------|--------|------|
+| A. 直接取消 Inbox | ⭐⭐ | 丢失 EML 导入等关键功能,不推荐 |
+| **B. 合并到 Dashboard** | ⭐⭐⭐⭐⭐ | **最佳方案**。符合"AI 自动处理 → 人工验证"的核心逻辑,减少页面跳转,保留所有必要功能 |
+| C. 保留但精简 Inbox | ⭐⭐⭐ | 可行但不够彻底,用户仍需在两个页面间切换 |
+
+### 一句话回答
+
+> **可以合并,而且应该合并。** 你的直觉是对的——既然 AI 会自动分析邮件,销售人员就不需要一个独立的"收件箱"去手动浏览和筛选邮件。把 Inbox 的 EML 导入和手动录入功能嵌入 Dashboard 的一个 Tab 中,其余邮件浏览/手动筛选功能全部由 AI 自动化替代。合并后从 7 个页面精简为 6 个,工作量约 2 天。
+

+ 604 - 0
lead-discovery/docs/OPTIMIZATION_PLAN.md

@@ -0,0 +1,604 @@
+# 犀牛急救 · 客户发掘系统 — 会议总结 & Demo 优化方案
+
+> 📅 会议日期:2026-02-11  
+> 📋 文档版本:v1.0  
+> 🎯 核心主题:客户画像体系构建 + AI 主动线索挖掘 + 线索管理流程重塑
+
+---
+
+## 一、会议核心观点总结
+
+### 1.1 当前痛点
+
+| 痛点 | 现状 | 影响 |
+|------|------|------|
+| **客户画像粗糙** | 销售仅将客户分为 A/B/C 三类,缺乏深入画像定义 | AI 筛选建议被反馈"不够深入",判断与销售实际工作脱节 |
+| **工作流方向倒置** | 员工辛苦整理几百条线索 → AI 仅验证人工 5-10 分钟就能完成的事 | AI 价值未被充分释放,员工仍是瓶颈 |
+| **缺乏经验知识库** | 没有记录销售人工判断/经验判断的依据 | 系统只能通过数据结果(设备数量、产品数量)做判断,忽略了销售经验 |
+| **线索管理扁平化** | 线索列表是简单的时间顺序排列 | 无法分门别类管理不同画像客户的信息 |
+
+### 1.2 目标工作流(理想状态)
+
+```
+┌─────────────────────────────────────────────────────────────────┐
+│                      AI 主动挖掘(每日/每周/批量)                 │
+│                                                                   │
+│  ① 批量线索进入 → ② AI 自动贴标签(画像分类)                      │
+│  → ③ AI 调研产品清单/官网 → ④ AI 做出跟进判断建议                  │
+│  → ⑤ 整理到对应客户资料库                                          │
+│                                                                   │
+│                    ↓ 每天/每周 ↓                                   │
+│                                                                   │
+│  销售打开系统 → 看到 AI 挖掘的新客户/新线索数量                      │
+│  → 点进去查看 AI 判断结果                                           │
+│  → 正确 → 确认/采纳                                                │
+│  → 有误 → 人工重新判断 → 标注错误点 → 重新归类                      │
+└─────────────────────────────────────────────────────────────────┘
+```
+
+**核心转变:从"人找信息" → "AI 推信息给人验证"**
+
+### 1.3 关键需求清单
+
+1. **客户画像清单(Persona Catalog)**  
+   - 有多少种类的客户画像  
+   - 每种画像在官网上体现的特征关键词  
+   - 每种画像对应的行业属性、采购动机、决策链路
+
+2. **画像→策略映射**  
+   - 不同画像的跟进方式与归类方式  
+   - 完成初步信息索取后,是引导查看官网内容,还是深入挖掘产品信息  
+   - 每一步人工判断的经验是什么
+
+3. **线索价值分级标准**  
+   - 不同画像对应的价值评估维度  
+   - 超越简单 A/B/C 的多维度评分体系
+
+4. **AI 主动挖掘机制**  
+   - 每天/每周/月度批量线索自动处理  
+   - 自动贴标签 + 调研 + 判断 + 归档
+
+5. **智能线索管理**  
+   - 分门别类的客户资料库  
+   - AI 自动整理可获取的资料(EP 内容等)  
+   - 销售验证 → 确认/纠正 → 反馈闭环
+
+---
+
+## 二、客户画像体系设计
+
+### 2.1 画像分类(从 4 类扩展为 6 类细分画像)
+
+> 以犀牛急救(医疗急救用品制造商)的客户结构为基础
+
+| 画像编号 | 画像名称 | 典型客户 | 核心特征 | 官网关键词 |
+|----------|----------|----------|----------|------------|
+| **P1** | 医药分销商 | Acme Medical, MediTech Supply | 有自己的销售渠道,本身售卖产品,寻找低价中国代工厂进货 | distributor, wholesale, medical supply, catalog, product range, authorized dealer |
+| **P2** | 工业安全供应商 | SafetyFirst UK, BuildSafe AU | 面向企业客户的安全设备供应商,需 OSHA/ANSI 合规产品 | workplace safety, OSHA compliant, industrial, PPE, safety cabinet, first aid station |
+| **P3** | 政府/机构采购 | Polish Red Cross, Bundeswehr | 政府、军队、NGO、医院等机构,本身不售卖产品,无需产品信息 | tender, procurement, government, emergency, military, NGO, hospital, public health |
+| **P4** | 品牌 OEM 客户 | WildGear GmbH, TrailBlazer | 户外/运动品牌,需要贴牌定制,关注设计和品牌调性 | OEM, private label, custom branding, outdoor, adventure, brand, retail |
+| **P5** | 电商/零售商 | Amazon seller, Shopify store | 线上零售商,关注单品利润率和爆款潜力 | amazon, shopify, e-commerce, retail, FBA, dropship, best seller |
+| **P6** | 低质量/无效线索 | Global Trading 88 | 无明确需求、套价格、骗样品等 | wholesale everything, lowest price, all kinds, mixed container, free sample |
+
+### 2.2 画像特征关键词库
+
+```
+P1-医药分销商:
+  官网特征: product catalog, distribution network, authorized, healthcare facilities
+  邮件特征: bulk order, annual forecast, FDA/CE requirement, partnership, distributor
+  行为特征: 询问MOQ、认证文件、年采购量、渠道授权
+
+P2-工业安全供应商:
+  官网特征: workplace safety solutions, OSHA compliance, safety equipment, PPE
+  邮件特征: wall-mount cabinet, ANSI standard, workplace, construction site
+  行为特征: 询问合规认证、壁挂安装、定制标签
+
+P3-政府/机构采购:
+  官网特征: government agency, ministry, military, hospital, NGO, red cross
+  邮件特征: tender, RFP, procurement reference, delivery deadline, lot
+  行为特征: 正式招标流程、有截止日期、需要资质文件
+
+P4-品牌OEM客户:
+  官网特征: our brand, brand story, product design, retail partners
+  邮件特征: private label, custom color, brand guidelines, mood board, OEM
+  行为特征: 关注设计定制、品牌调性、包装、Pantone色号
+
+P5-电商/零售商:
+  官网特征: shop now, add to cart, amazon store, shopify
+  邮件特征: FBA, dropship, product listing, retail price, margin
+  行为特征: 关注单品利润、物流方式、产品图片
+
+P6-低质量线索:
+  官网特征: 无官网/免费邮箱/信息模糊
+  邮件特征: everything, lowest price, all kinds, ASAP, no specific product
+  行为特征: 无具体需求、不提供公司信息、要求免费样品
+```
+
+### 2.3 画像→后续策略映射
+
+| 画像 | 信息获取方式 | 首要动作 | 深度挖掘方向 | 销售策略重点 |
+|------|-------------|----------|-------------|-------------|
+| **P1-医药分销商** | ✅ 查看**产品清单页** | 发送完整产品目录 + 价盘 | 其现有产品线、竞品供应商、渠道覆盖范围 | 强调供应稳定性、认证齐全、复购支持 |
+| **P2-工业安全供应商** | ✅ 查看**产品清单页** | 发送 OSHA 合规产品线 | 其客户行业分布、采购频次、定制需求 | 强调合规认证、定制标签、壁挂方案 |
+| **P3-政府/机构采购** | ✅ 查看**官网**(了解机构背景) | 准备资质文件包 | 机构规模、历史采购记录、预算周期 | 强调资质齐全、大批量交付能力、投标经验 |
+| **P4-品牌OEM客户** | ✅ 查看**官网**(了解品牌调性) | 发送 OEM 案例 + 定制能力介绍 | 品牌定位、目标市场、设计风格 | 强调定制能力、打样速度、小批量起订 |
+| **P5-电商/零售商** | ✅ 查看**产品清单页** | 发送爆款推荐 + 利润率分析 | 其店铺品类、评价数据、竞品价格 | 强调高利润率、FBA 就绪、产品图片支持 |
+| **P6-低质量线索** | ❌ 不做深入调研 | 自动归档 | - | 定期群发营销邮件,不投入人工 |
+
+---
+
+## 三、Demo 界面优化方案
+
+### 3.1 当前 Demo 页面清单 & 状态
+
+| 页面 | 路由 | 当前状态 | 优化方向 |
+|------|------|---------|---------|
+| 邮件收件箱 | `/inbox` | ✅ 已实现邮件列表 + 快速筛选 + EML 导入 | 增加 AI 挖掘仪表盘入口 |
+| 线索看板 | `/kanban` | ✅ 按价值等级 S/A/B/C 四列看板 | 增加按画像分组视图 |
+| 线索列表 | `/leads` | ✅ 表格视图,支持搜索筛选 | 升级为智能分类视图 |
+| 线索详情 | `/leads/:id` | ✅ 快速筛选结果 + 跟进状态 + 推荐产品 | 增加画像卡片 + AI 调研报告 + 销售验证交互 |
+| 产品目录 | `/products` | ✅ 产品列表 | 保持不变 |
+
+### 3.2 新增页面/模块
+
+#### 🆕 3.2.1 AI 挖掘仪表盘(Dashboard)
+
+> 路由:`/dashboard`  
+> 定位:销售每天打开系统的**第一个页面**
+
+**核心内容:**
+
+```
+┌─────────────────────────────────────────────────┐
+│  📊 AI 挖掘仪表盘                    2026-02-11  │
+├─────────────────────────────────────────────────┤
+│                                                   │
+│  ┌──────┐  ┌──────┐  ┌──────┐  ┌──────────────┐ │
+│  │ 🆕 12 │  │ ⏳ 5  │  │ ✅ 38 │  │ 💰 $1.2M     │ │
+│  │ 今日新 │  │ 待验证│  │ 已确认│  │ 管线总值     │ │
+│  └──────┘  └──────┘  └──────┘  └──────────────┘ │
+│                                                   │
+│  📬 AI 今日发现(需要您验证)                      │
+│  ┌─────────────────────────────────────────────┐ │
+│  │ 🏥 MedPharma GmbH        P1-医药分销商       │ │
+│  │    AI判断:S级 · 年采购$200K · 建议查看产品清单│ │
+│  │    [✅ 确认] [✏️ 修改] [❌ 无效]              │ │
+│  ├─────────────────────────────────────────────┤ │
+│  │ 🏛️ UK Ministry of Defence  P3-政府采购       │ │
+│  │    AI判断:S级 · 招标$500K · 建议查看官网      │ │
+│  │    [✅ 确认] [✏️ 修改] [❌ 无效]              │ │
+│  ├─────────────────────────────────────────────┤ │
+│  │ 🛒 OutdoorKing (Amazon)   P5-电商零售商       │ │
+│  │    AI判断:B级 · 预估$15K · 建议推爆款         │ │
+│  │    [✅ 确认] [✏️ 修改] [❌ 无效]              │ │
+│  └─────────────────────────────────────────────┘ │
+│                                                   │
+│  📈 本周画像分布                                   │
+│  P1-医药分销商  ████████░░ 42%                     │
+│  P3-政府采购    ███░░░░░░░ 18%                     │
+│  P4-品牌OEM     ██░░░░░░░░ 12%                     │
+│  P2-工业安全    ██░░░░░░░░ 11%                     │
+│  P5-电商零售    █░░░░░░░░░  8%                     │
+│  P6-低质量      █░░░░░░░░░  9%                     │
+└─────────────────────────────────────────────────┘
+```
+
+**设计要点:**
+- 顶部统计卡片:今日新线索数、待验证数、已确认数、管线总值
+- AI 发现列表:每条线索显示画像标签 + AI 判断结果 + 快速操作按钮
+- 销售只需点击 ✅ 确认 / ✏️ 修改 / ❌ 无效
+- 画像分布图:本周/本月的客户画像分布比例
+
+#### 🆕 3.2.2 画像知识库页面(Persona Catalog)
+
+> 路由:`/personas`  
+> 定位:系统的**知识引擎**,记录销售经验
+
+**核心内容:**
+
+```
+┌─────────────────────────────────────────────────┐
+│  📚 客户画像知识库                                │
+├─────────────────────────────────────────────────┤
+│                                                   │
+│  ┌─ P1 医药分销商 ──────────────────────────────┐│
+│  │ 📝 定义:拥有销售渠道的医疗用品经销商,         ││
+│  │         寻找低价中国代工厂进货                  ││
+│  │                                                ││
+│  │ 🔑 识别关键词:                                ││
+│  │   distributor | wholesale | medical supply     ││
+│  │   catalog | authorized dealer | FDA            ││
+│  │                                                ││
+│  │ 📋 AI 行动规则:                               ││
+│  │   ① 初步接触 → 查看产品清单页                  ││
+│  │   ② 深度挖掘 → 分析其现有产品线和竞品供应商    ││
+│  │   ③ 销售策略 → 强调供应稳定性、认证齐全        ││
+│  │                                                ││
+│  │ 💡 销售经验备注:                               ││
+│  │   "这类客户最关心认证文件是否齐全,             ││
+│  │    首次接触一定要附上 FDA/CE/ISO 证书"          ││
+│  │                                                ││
+│  │ 📊 统计:当前 42 条线索 | 转化率 28%           ││
+│  └────────────────────────────────────────────────┘│
+│                                                   │
+│  ┌─ P3 政府/机构采购 ─────────────────────────────┐│
+│  │ 📝 定义:政府、军队、NGO、医院等机构,           ││
+│  │         本身不售卖产品,无需产品信息              ││
+│  │                                                ││
+│  │ 🔑 识别关键词:                                ││
+│  │   tender | government | procurement | military ││
+│  │                                                ││
+│  │ 📋 AI 行动规则:                               ││
+│  │   ① 初步接触 → 查看官网(了解机构背景)        ││
+│  │   ② 深度挖掘 → 历史采购记录、预算周期          ││
+│  │   ③ 销售策略 → 强调资质齐全、大批量交付能力    ││
+│  │                                                ││
+│  │ 💡 销售经验备注:                               ││
+│  │   "政府采购有固定流程和截止日期,                ││
+│  │    一定要在截止前 2 周准备好所有资质文件"        ││
+│  └────────────────────────────────────────────────┘│
+└─────────────────────────────────────────────────┘
+```
+
+**设计要点:**
+- 每个画像是一张可展开的知识卡片
+- 包含:定义、识别关键词、AI 行动规则、销售经验备注、统计数据
+- 销售可以编辑"经验备注",形成知识沉淀
+- AI 根据这些规则执行自动化判断
+
+### 3.3 现有页面优化
+
+#### 📬 3.3.1 收件箱(`/inbox`)优化
+
+**新增内容:**
+- 顶部增加 **AI 挖掘状态栏**:显示"今日 AI 已处理 47 封邮件,发现 12 条新线索"
+- 每封邮件卡片增加 **AI 画像标签**:如 `P1-医药分销商` 标签
+- 增加 **批量操作**:选中多封邮件 → 批量运行 AI 筛选
+
+#### 📋 3.3.2 线索列表(`/leads`)升级为智能分类视图
+
+**当前问题:** 线索按时间顺序平铺,无法分门别类管理
+
+**优化方案:**
+
+```
+┌─────────────────────────────────────────────────┐
+│  📋 线索管理                                      │
+│                                                   │
+│  视图切换:[📋 列表] [📂 按画像分组] [📊 统计]    │
+│                                                   │
+│  ── 📂 按画像分组视图 ──                          │
+│                                                   │
+│  ▼ P1-医药分销商 (15条)                           │
+│  ┌─────────────────────────────────────────────┐ │
+│  │ Acme Medical    S级  $120K  已触达  02/11   │ │
+│  │ MediTech Supply A级  $85K   寄样中  02/14   │ │
+│  │ NordicMed AB    S级  $95K   已触达  02/12   │ │
+│  │ ... 展开更多                                  │ │
+│  └─────────────────────────────────────────────┘ │
+│                                                   │
+│  ▼ P2-工业安全供应商 (8条)                        │
+│  ┌─────────────────────────────────────────────┐ │
+│  │ SafetyFirst UK  A级  $45K   已触达  02/13   │ │
+│  │ BuildSafe AU    B级  $20K   已筛选  02/18   │ │
+│  └─────────────────────────────────────────────┘ │
+│                                                   │
+│  ▼ P3-政府/机构采购 (5条)                         │
+│  ┌─────────────────────────────────────────────┐ │
+│  │ Polish Red Cross S级 $200K  已筛选  02/12   │ │
+│  │ Bundeswehr       A级 $350K  报价中  02/16   │ │
+│  └─────────────────────────────────────────────┘ │
+│                                                   │
+│  ▶ P4-品牌OEM客户 (4条)                          │
+│  ▶ P5-电商/零售商 (2条)                          │
+│  ▶ P6-低质量线索 (3条) ← 灰色折叠               │
+└─────────────────────────────────────────────────┘
+```
+
+**设计要点:**
+- 三种视图模式切换:列表(现有)、按画像分组(新增)、统计(新增)
+- 按画像分组视图:每个画像下折叠显示所属线索
+- P6 低质量线索默认折叠 + 灰色显示
+- 每个分组头显示线索数量 + 总金额 + 转化率
+
+#### 📊 3.3.3 线索详情(`/leads/:id`)增强
+
+**新增模块:**
+
+```
+┌─────────────────────────────────────────────────┐
+│  ① 客户画像卡片(新增)                           │
+│  ┌─────────────────────────────────────────────┐ │
+│  │ 🏥 P1-医药分销商                             │ │
+│  │                                               │ │
+│  │ AI 判断依据:                                  │ │
+│  │ • 官网包含 "distributor", "medical supply"    │ │
+│  │ • 邮件提及 "bulk IFAK kits", "hospital"       │ │
+│  │ • 公司规模:120+ 医院客户                      │ │
+│  │                                               │ │
+│  │ 推荐策略:查看产品清单 → 发送完整目录 + 价盘   │ │
+│  │                                               │ │
+│  │ 销售验证:[✅ AI判断正确] [✏️ 修改画像]       │ │
+│  └─────────────────────────────────────────────┘ │
+│                                                   │
+│  ② AI 调研报告(增强现有深度分析)                 │
+│  ┌─────────────────────────────────────────────┐ │
+│  │ 📄 官网分析                                    │ │
+│  │ • 产品线:IFAK, Trauma Kit, Cabinet (共 45 SKU)│ │
+│  │ • 认证:FDA 510(k), ISO 13485, CE MDR        │ │
+│  │ • 覆盖区域:美国中西部 120+ 医院               │ │
+│  │                                               │ │
+│  │ 📦 产品清单匹配                                │ │
+│  │ • 我方 SE IFAK Pro → 匹配其 Tactical IFAK 需求│ │
+│  │ • 我方壁挂急救箱 → 匹配其 Cabinet 需求         │ │
+│  │ • 利润空间分析:批发 $30 vs 其零售 $89 (66%)  │ │
+│  │                                               │ │
+│  │ 🏭 竞品分析                                    │ │
+│  │ • 当前供应商:North American Rescue (推测)      │ │
+│  │ • 我方优势:价格低 40%、交期快 2 周             │ │
+│  └─────────────────────────────────────────────┘ │
+│                                                   │
+│  ③ 销售验证区域(新增)                            │
+│  ┌─────────────────────────────────────────────┐ │
+│  │ 您对 AI 的判断结果满意吗?                      │ │
+│  │                                               │ │
+│  │ 画像分类:P1-医药分销商  [✅ 正确] [✏️ 修改]  │ │
+│  │ 价值等级:S级            [✅ 正确] [✏️ 修改]  │ │
+│  │ 推荐产品:SE IFAK Pro    [✅ 正确] [✏️ 修改]  │ │
+│  │                                               │ │
+│  │ 备注(可选):                                  │ │
+│  │ ┌───────────────────────────────────────────┐ │ │
+│  │ │ 这个客户之前在 MEDICA 展会见过面,          │ │ │
+│  │ │ 对方对认证文件特别在意...                    │ │ │
+│  │ └───────────────────────────────────────────┘ │ │
+│  │                                               │ │
+│  │ [💾 保存验证结果]                              │ │
+│  └─────────────────────────────────────────────┘ │
+└─────────────────────────────────────────────────┘
+```
+
+#### 🔄 3.3.4 看板(`/kanban`)优化
+
+**新增功能:**
+- 增加 **按画像分组** 的看板视图(除了现有的按等级分列)
+- 视图切换:`按等级` | `按画像` | `按跟进阶段`
+- 每张线索卡片增加画像标签色带
+
+---
+
+## 四、数据模型升级
+
+### 4.1 新增:客户画像类型(CustomerPersona)
+
+```typescript
+// 画像类型
+export type CustomerPersona = 'P1' | 'P2' | 'P3' | 'P4' | 'P5' | 'P6';
+
+export interface PersonaDefinition {
+  id: CustomerPersona;
+  name: string;                    // 画像名称
+  description: string;             // 画像定义
+  icon: string;                    // Material icon
+  color: string;                   // 主题色
+  identifyKeywords: string[];      // 识别关键词(官网+邮件)
+  infoStrategy: 'product_catalog' | 'website' | 'none';  // 信息获取方式
+  firstAction: string;             // 首要动作
+  deepDiveDirection: string;       // 深度挖掘方向
+  salesStrategy: string;           // 销售策略重点
+  salesExperienceNotes: string[];  // 销售经验备注(可编辑)
+  leadCount: number;               // 当前线索数
+  conversionRate: number;          // 转化率
+}
+```
+
+### 4.2 升级:Lead 对象
+
+```typescript
+export interface Lead {
+  // ... 现有字段 ...
+
+  // 新增字段
+  persona: CustomerPersona;              // 客户画像类型
+  personaLabel: string;                  // 画像名称
+  personaConfidence: number;             // AI 画像判断置信度
+  personaVerified: boolean;              // 销售是否已验证画像
+  personaVerifiedBy?: string;            // 验证人
+  personaVerifiedAt?: Date;              // 验证时间
+
+  aiResearchReport?: {                   // AI 调研报告
+    websiteAnalysis?: string;            // 官网分析摘要
+    productMatching?: ProductMatch[];    // 产品匹配结果
+    competitorAnalysis?: string;         // 竞品分析
+    generatedAt: Date;
+  };
+
+  salesFeedback?: {                      // 销售反馈
+    isPersonaCorrect: boolean;
+    correctedPersona?: CustomerPersona;
+    isGradeCorrect: boolean;
+    correctedGrade?: ValueGrade;
+    notes: string;
+    feedbackAt: Date;
+  };
+
+  source: 'email' | 'manual' | 'exhibition' | 'platform'
+        | 'ai_discovery';               // 新增:AI 主动发现
+}
+```
+
+### 4.3 新增:AI 挖掘批次(AiDiscoveryBatch)
+
+```typescript
+export interface AiDiscoveryBatch {
+  id: string;
+  runAt: Date;
+  triggerType: 'daily' | 'weekly' | 'monthly' | 'manual';
+  totalProcessed: number;           // 处理的线索总数
+  newLeadsFound: number;            // 发现的新线索数
+  personaBreakdown: Record<CustomerPersona, number>;  // 按画像分布
+  gradeBreakdown: Record<ValueGrade, number>;         // 按等级分布
+  pendingVerification: number;      // 待验证数
+  verified: number;                 // 已验证数
+  status: 'running' | 'completed' | 'failed';
+}
+```
+
+---
+
+## 五、AI 主动挖掘流程设计
+
+### 5.1 批量处理流水线
+
+```
+输入:100-200 条原始线索(来自邮件/展会名片/平台询盘)
+        │
+        ▼
+┌─ Step 1:自动画像分类 ─────────────────────┐
+│  • 提取公司域名、邮件内容关键词               │
+│  • 匹配画像知识库中的识别关键词               │
+│  • 输出:CustomerPersona + 置信度            │
+└─────────────────────┬─────────────────────┘
+                      │
+                      ▼
+┌─ Step 2:按画像执行信息获取 ───────────────┐
+│  P1/P2/P5 → 调研产品清单页                   │
+│  P3/P4    → 抓取官网信息                     │
+│  P6       → 跳过,直接归档                   │
+└─────────────────────┬─────────────────────┘
+                      │
+                      ▼
+┌─ Step 3:深度挖掘 & 匹配 ─────────────────┐
+│  • 分析客户产品线 vs 我方产品目录             │
+│  • 竞品供应商分析                             │
+│  • 利润空间计算                               │
+│  • 生成 AI 调研报告                          │
+└─────────────────────┬─────────────────────┘
+                      │
+                      ▼
+┌─ Step 4:价值评估 & 分级 ─────────────────┐
+│  • 基于画像 + 调研结果 → S/A/B/C 分级       │
+│  • 生成跟进建议(基于画像策略映射)           │
+│  • 推荐产品列表                               │
+└─────────────────────┬─────────────────────┘
+                      │
+                      ▼
+┌─ Step 5:归档到客户资料库 ─────────────────┐
+│  • 按画像分类存入对应资料库                   │
+│  • 整理 EP 内容、官网截图等资料               │
+│  • 标记为"待销售验证"                        │
+└─────────────────────┬─────────────────────┘
+                      │
+                      ▼
+     销售打开仪表盘 → 看到待验证列表 → 逐条确认/修改
+```
+
+### 5.2 调度策略
+
+| 触发条件 | 处理内容 | 频率 |
+|----------|---------|------|
+| 每日定时 | 前一天新收邮件 + 新增手动录入 | 每天早 8:00 |
+| 每周汇总 | 本周所有新线索的深度分析报告 | 每周一早 9:00 |
+| 批量导入 | 展会名片批量导入(100-200条) | 手动触发 |
+| 实时触发 | 单条 EML 导入后立即运行 | 实时 |
+
+---
+
+## 六、实施路线图
+
+### Phase 1(当前 → 2 周内):画像体系 + 知识库
+
+| 任务 | 优先级 | 状态 |
+|------|--------|------|
+| 与客户深度沟通,梳理完整画像清单 | 🔴 P0 | ⬜ 待启动 |
+| 收集销售团队的经验判断依据 | 🔴 P0 | ⬜ 待启动 |
+| 定义 6 类画像的识别关键词库 | 🔴 P0 | ⬜ 待启动 |
+| 定义每类画像的跟进策略映射 | 🟡 P1 | ⬜ 待启动 |
+| 升级 Lead 数据模型(增加 persona 字段) | 🟡 P1 | ⬜ 待启动 |
+| 实现画像知识库页面 `/personas` | 🟡 P1 | ⬜ 待启动 |
+
+### Phase 2(2-4 周):AI 仪表盘 + 智能分类
+
+| 任务 | 优先级 | 状态 |
+|------|--------|------|
+| 实现 AI 挖掘仪表盘 `/dashboard` | 🔴 P0 | ⬜ 待启动 |
+| 升级线索列表为按画像分组视图 | 🟡 P1 | ⬜ 待启动 |
+| 线索详情增加画像卡片 + 销售验证区域 | 🟡 P1 | ⬜ 待启动 |
+| 看板增加按画像分组视图 | 🟢 P2 | ⬜ 待启动 |
+| 邮件收件箱增加 AI 状态栏 + 画像标签 | 🟢 P2 | ⬜ 待启动 |
+
+### Phase 3(4-8 周):AI 自动化 + 反馈闭环
+
+| 任务 | 优先级 | 状态 |
+|------|--------|------|
+| 实现 AI 自动画像分类引擎 | 🔴 P0 | ⬜ 待启动 |
+| 实现按画像的差异化信息获取(产品清单 vs 官网) | 🔴 P0 | ⬜ 待启动 |
+| 实现 AI 调研报告自动生成 | 🟡 P1 | ⬜ 待启动 |
+| 实现批量线索处理流水线 | 🟡 P1 | ⬜ 待启动 |
+| 实现每日/每周自动调度 | 🟡 P1 | ⬜ 待启动 |
+| 实现销售反馈 → AI 学习闭环 | 🟢 P2 | ⬜ 待启动 |
+
+---
+
+## 七、需要与客户确认的问题清单
+
+> ⚠️ 以下问题需要与销售团队深度沟通后才能推进
+
+### 7.1 画像相关
+
+1. **当前 A/B/C 三类客户的具体定义是什么?** 每类的判断依据是什么?
+2. **除了医药分销商、政府机构,还有哪些典型客户类型?** 是否有我们遗漏的画像?
+3. **每种画像客户的首次接触话术有什么区别?** 销售团队的经验是什么?
+4. **哪些画像的客户转化率最高?** 哪些画像的客户最容易流失?
+5. **不同画像客户的决策周期有多长?** 从首次接触到下单通常需要多久?
+
+### 7.2 策略相关
+
+6. **"查看产品清单"和"查看官网"分别对应什么具体操作?** 销售是如何决定的?
+7. **什么情况下会把一个客户从一个画像重新归类到另一个画像?** 触发条件是什么?
+8. **S/A/B/C 等级的判断除了金额,还有哪些维度?** 销售的经验判断依据是什么?
+9. **当 AI 判断与销售经验冲突时,应该以谁为准?** 期望的处理流程是什么?
+
+### 7.3 数据相关
+
+10. **目前每天/每周/每月收到多少条新线索?** 各渠道的比例是多少?
+11. **展会名片通常一次导入多少条?** 格式是什么?
+12. **是否有历史线索数据可以用来训练 AI 模型?** 大概有多少条?
+13. **销售团队目前使用什么工具管理客户?** CRM?Excel?
+
+---
+
+## 八、附录:当前 Demo 技术架构
+
+```
+lead-discovery/
+├── src/app/
+│   ├── models/
+│   │   └── lead.model.ts          # 数据模型(Lead, Email, Product, QuickScreenResult)
+│   ├── services/
+│   │   ├── mock-data.service.ts   # 模拟数据(6封邮件, 10条线索, 12个产品)
+│   │   └── quick-screen.service.ts # 快速筛选逻辑(模拟AI分类)
+│   ├── components/
+│   │   └── screen-result-card/    # 筛选结果卡片组件
+│   ├── pages/
+│   │   ├── inbox/                 # 📬 收件箱(含EML导入)
+│   │   ├── kanban/                # 📋 看板(S/A/B/C四列)
+│   │   ├── lead-list/             # 📊 线索列表
+│   │   ├── lead-detail/           # 📄 线索详情
+│   │   └── product-catalog/       # 📦 产品目录
+│   ├── app.component.ts           # 主框架(侧边栏导航)
+│   ├── app.routes.ts              # 路由配置
+│   └── app.config.ts              # 应用配置
+├── angular.json
+└── package.json
+```
+
+**当前客户分类体系:**
+- A-医疗渠道 → 对应新画像 P1
+- B-工业安全 → 对应新画像 P2
+- C-应急政府 → 对应新画像 P3
+- D-品牌OEM → 对应新画像 P4
+- (新增)P5-电商/零售商
+- (新增)P6-低质量/无效线索
+
+**当前价值分级:** S → A → B → C(保持不变,但评估维度需扩展)
+

+ 951 - 0
lead-discovery/docs/PRD_LEAD_DISCOVERY.md

@@ -0,0 +1,951 @@
+# PRD:客户发掘系统 - 从线索到客户建档及价值判断
+
+**版本**:v1.0  
+**创建日期**:2026-02-12  
+**产品经理**:待定  
+**技术负责人**:待定  
+
+---
+
+## 一、产品概述
+
+### 1.1 产品背景
+
+外贸业务员每天收到大量询盘邮件,需要快速判断哪些值得跟进、如何跟进。现有系统存在以下问题:
+- **nanchi 背调系统**:流程过重(3-8分钟),信息过载,缺少分层机制
+- **demo-nanchi 画像系统**:快速筛选太粗,深度分析是空壳,缺少行动指导
+
+### 1.2 产品定位
+
+**"10秒告诉你值不值得跟进,3分钟帮你准备好跟进弹药"**
+
+一个以行动为导向的线索价值判断与跟进准备系统,通过三层漏斗(信息提取 → 快速研判 → 深度调研)帮助业务员高效处理询盘。
+
+### 1.3 目标用户
+
+- **主要用户**:外贸业务员(每天处理 20-50 封询盘)
+- **次要用户**:销售主管(查看团队线索质量与跟进情况)
+
+### 1.4 产品目标
+
+| 目标 | 指标 |
+|------|------|
+| **提升效率** | 单封邮件处理时间从 5-10 分钟降至 1-3 分钟 |
+| **提升准确度** | 线索价值判断准确率 ≥ 85%(与业务员直觉一致) |
+| **提升转化率** | S/A 级线索跟进率 ≥ 90%,B 级线索跟进率 ≥ 50% |
+
+---
+
+## 二、功能需求
+
+### 2.1 第一层:邮件摄入 & 信息提取
+
+#### 2.1.1 功能描述
+
+将非结构化邮件自动解析为结构化数据,提取关键信息。
+
+#### 2.1.2 输入方式
+
+- **方式一**:上传 .eml 文件(支持拖拽)
+- **方式二**:手动录入(复制粘贴邮件内容)
+- **方式三**:API 接入(未来支持邮箱集成)
+
+#### 2.1.3 提取维度
+
+| 维度 | 提取规则 | 数据格式 | 优先级 |
+|------|---------|---------|--------|
+| **联系人** | 签名块解析(姓名 + 职位) | `{ name: string, title: string }` | P0 |
+| **公司名** | 签名块 + 邮箱域名推断 | `string` | P0 |
+| **邮箱** | From 字段 | `string` | P0 |
+| **邮箱域名** | @ 后缀提取 | `string` | P0 |
+| **国家** | 签名块地址 + 域名后缀推断 | `string` | P0 |
+| **产品需求** | 正文 + 附件 NLP 提取 | `Array<{ product: string, quantity: number, unit: string }>` | P0 |
+| **数量级** | 数字提取 + 单位识别 | `{ total: number, unit: string }` | P0 |
+| **认证要求** | 关键词匹配(FDA/CE/ISO/OSHA等) | `Array<string>` | P0 |
+| **贸易术语** | 关键词匹配(FOB/CIF/DDP等) | `Array<string>` | P1 |
+| **紧迫性信号** | 截止日期提取 + 催促语气识别 | `{ hasDeadline: boolean, deadline?: Date, urgencyLevel: 'high'\|'medium'\|'low' }` | P0 |
+| **附件清单** | 文件名 + 类型 + 大小 | `Array<{ name: string, type: string, size: number, isImportant: boolean }>` | P0 |
+
+**特殊标注规则**:
+- 附件文件名包含 "Company Profile" / "Requirements Spec" / "Tender" / "RFP" → `isImportant: true`
+- 邮件中有具体数量(如 "5,000 units/year")→ 自动计算预估年采购额
+
+#### 2.1.4 输出数据结构
+
+```typescript
+interface EmailExtractionResult {
+  emailId: string;                    // 邮件唯一ID
+  extractedAt: string;                // 提取时间
+  source: 'eml_file' | 'manual' | 'api';
+  
+  // 基础信息
+  contact: {
+    name: string;
+    title?: string;
+    email: string;
+    phone?: string;
+    address?: string;
+  };
+  company: {
+    name: string;
+    domain?: string;
+    country?: string;
+  };
+  
+  // 需求信息
+  productRequirements: Array<{
+    product: string;                   // 产品名称/描述
+    quantity: number;                  // 数量
+    unit: string;                      // 单位(units/year, pieces, etc.)
+    specifications?: string[];          // 规格要求
+  }>;
+  certifications: string[];           // 认证要求
+  tradeTerms: string[];                // 贸易术语
+  
+  // 紧迫性
+  urgency: {
+    hasDeadline: boolean;
+    deadline?: string;                 // ISO 8601
+    urgencyLevel: 'high' | 'medium' | 'low';
+    urgencySignals: string[];          // 催促性语言片段
+  };
+  
+  // 附件
+  attachments: Array<{
+    name: string;
+    type: string;
+    size: number;
+    isImportant: boolean;               // 是否为公司资料/需求文档
+  }>;
+  
+  // 原始内容(保留)
+  originalEmail: {
+    subject: string;
+    body: string;                      // 纯文本
+    htmlBody?: string;                  // HTML(如有)
+    from: string;
+    to: string[];
+    cc?: string[];
+    date: string;
+  };
+  
+  // 元数据
+  metadata: {
+    hasSignature: boolean;             // 是否有完整签名块
+    hasAttachments: boolean;
+    ccCount: number;                    // 抄送人数
+    mentionsTradeShow?: string;         // 提到的展会
+  };
+}
+```
+
+#### 2.1.5 验收标准
+
+- [ ] 支持 .eml 文件解析,准确率 ≥ 95%
+- [ ] 联系人/公司名提取准确率 ≥ 90%
+- [ ] 产品需求提取准确率 ≥ 85%(有具体数量时)
+- [ ] 附件重要度标注准确率 ≥ 90%
+- [ ] 单封邮件处理时间 < 5 秒
+
+---
+
+### 2.2 第二层:快速研判(核心功能)
+
+#### 2.2.1 功能描述
+
+基于五维评分体系,10 秒内给出线索价值判断和行动建议。
+
+#### 2.2.2 五维评分体系
+
+**维度一:需求明确度(Demand Clarity)**
+
+| 信号 | 得分 | 检测规则 |
+|------|------|---------|
+| 提到具体产品名 | +20 | NLP 识别产品关键词(IFAK, cabinet, refill 等) |
+| 有明确数量 | +25 | 数字 + 单位(如 "5,000 units/year") |
+| 有规格要求 | +15 | 关键词(MOLLE, MARCH-P, custom, etc.) |
+| 有认证要求 | +10 | 认证关键词(FDA, CE, ISO, OSHA 等) |
+| 询问价格/MOQ/交期 | +15 | 关键词(pricing, MOQ, lead time, FOB, etc.) |
+| 只说"send catalog" | +5 | 仅包含 "catalog" / "brochure" 等 |
+| 无任何具体需求 | 0 | 以上均无 |
+
+**维度二:可信度(Credibility)**
+
+| 信号 | 得分 | 检测规则 |
+|------|------|---------|
+| 企业域名邮箱 | +15 | 域名非 gmail/hotmail/yahoo 等免费邮箱 |
+| 免费邮箱 | -10 | gmail/hotmail/yahoo/outlook 等 |
+| 完整签名块 | +20 | 包含职位 + 电话 + 地址 |
+| 有附件(公司资料) | +20 | 附件文件名包含 "Company Profile" / "Profile" |
+| 有附件(需求文档) | +15 | 附件文件名包含 "Requirements" / "Spec" / "Tender" |
+| 有抄送 | +10 | CC 字段非空 |
+| 提到展会/面谈 | +15 | 关键词(trade show, expo, meeting, conversation) |
+| 无附件+无签名+模糊 | 0 | 以上均无 |
+
+**维度三:商业规模(Business Scale)**
+
+| 信号 | 得分 | 检测规则 |
+|------|------|---------|
+| 提到公司规模/营收 | +20 | 数字 + 单位(如 "$45M revenue", "200 employees") |
+| 提到下游客户数量 | +15 | 数字 + 客户类型(如 "120 hospitals") |
+| 年采购量 > $100K | +25 | 基于产品需求 × 我方单价计算 |
+| 年采购量 $30K-$100K | +15 | 同上 |
+| 年采购量 < $30K | +5 | 同上 |
+| 无法判断规模 | 0 | 无相关信号 |
+
+**维度四:供需匹配(Product Fit)**
+
+| 信号 | 得分 | 检测规则 |
+|------|------|---------|
+| 提到的产品我方有对应 SKU | +25/匹配项 | 产品关键词匹配我方产品库 |
+| 认证要求我方可满足 | +15 | 认证列表匹配我方认证库 |
+| 需要定制但我方有能力 | +10 | 关键词(OEM, custom, private label)且我方支持 |
+| 产品完全不匹配 | -20 | 无任何匹配 |
+
+**维度五:紧迫度(Urgency)**
+
+| 信号 | 得分 | 检测规则 |
+|------|------|---------|
+| 有明确截止日期 | +30 | 日期提取(如 "March 15, 2026") |
+| 催促性语言 | +15 | 关键词(ASAP, urgent, prompt, immediate) |
+| 提到正在比价/选供应商 | +10 | 关键词(looking for, selecting, comparing) |
+| 提到长期合作/代理 | +5 | 关键词(long-term, distributor, agent) |
+| 无紧迫信号 | 0 | 以上均无 |
+
+#### 2.2.3 综合评级算法
+
+```typescript
+// 权重配置
+const WEIGHTS = {
+  demandClarity: 0.25,
+  credibility: 0.25,
+  businessScale: 0.20,
+  productFit: 0.15,
+  urgency: 0.15
+};
+
+// 总分计算
+const totalScore = 
+  demandClarity * WEIGHTS.demandClarity +
+  credibility * WEIGHTS.credibility +
+  businessScale * WEIGHTS.businessScale +
+  productFit * WEIGHTS.productFit +
+  urgency * WEIGHTS.urgency;
+
+// 等级判定
+function getGrade(totalScore: number, credibility: number, demandClarity: number): 'S' | 'A' | 'B' | 'C' {
+  if (totalScore >= 80 && credibility >= 60) return 'S';
+  if (totalScore >= 60 && demandClarity >= 40) return 'A';
+  if (totalScore >= 35) return 'B';
+  return 'C';
+}
+```
+
+**等级定义**:
+- **S级(立即跟进)**:总分 ≥ 80 且可信度 ≥ 60 → 24h 内跟进
+- **A级(3天内跟进)**:总分 ≥ 60 且需求明确度 ≥ 40 → 3 天内跟进
+- **B级(7天内跟进)**:总分 ≥ 35 → 7 天内跟进
+- **C级(归档观察)**:总分 < 35 → 归档,定期群发营销邮件
+
+#### 2.2.4 客户画像识别(P1-P6)
+
+**识别逻辑**(不再只看关键词,综合考虑邮件结构特征):
+
+| 画像 | 核心识别逻辑 | 置信度阈值 |
+|------|------------|-----------|
+| **P1 医药分销商** | 企业邮箱 + ("distributor"/"wholesale") + (FDA/ISO需求) + 有具体SKU级需求 | ≥ 70% |
+| **P2 工业安全供应商** | (OSHA/ANSI) + (壁挂箱/急救站需求) + 企业客户导向 | ≥ 70% |
+| **P3 政府/机构采购** | (标书编号/招标通知) + ("tender"/"procurement"/"lot") + 有截止日期 | ≥ 80% |
+| **P4 品牌OEM客户** | ("OEM"/"private label"/"custom branding") + 有品牌设计要求 + 关注打样 | ≥ 70% |
+| **P5 电商/零售商** | (Amazon/Shopify/FBA) + 关注单品利润率 + 小批量 | ≥ 70% |
+| **P6 低质量/无效** | 免费邮箱 + 无具体需求 + 无附件 + 模糊语言 | ≥ 60% |
+
+**画像判断依据**(展示给业务员):
+- 匹配的关键词列表
+- 邮件结构特征(附件/签名块/抄送)
+- 置信度百分比
+
+#### 2.2.5 产品匹配
+
+**匹配逻辑**:
+1. 提取客户需求中的产品关键词
+2. 与我方产品库进行语义匹配(支持同义词)
+3. 返回匹配产品列表,包含:
+   - 产品名称 + SKU
+   - 匹配度(0-100%)
+   - 匹配依据(客户提到的关键词)
+
+**预估采购额计算**:
+```typescript
+estimatedAnnualValue = sum(
+  productRequirements.map(req => 
+    req.quantity * matchedProduct.wholesalePrice
+  )
+);
+```
+
+#### 2.2.6 输出:快速研判卡片
+
+**UI 组件结构**:
+
+```
+┌─────────────────────────────────────────────────────┐
+│  [公司Logo/图标] 公司名                     [国旗] 国家 │
+│  ─────────────────────────────────────────────────── │
+│  [画像标签] [等级标签] [行动标签]                      │
+│                                                      │
+│  📦 需求摘要                                         │
+│  · 产品1 × 数量1                                     │
+│  · 产品2 × 数量2                                     │
+│  💰 预估年采购额:$XXX,XXX                           │
+│                                                      │
+│  ✅ 可信度:[高/中/低]                               │
+│  · 企业邮箱 · 完整签名块 · X份附件(含公司简介)     │
+│                                                      │
+│  🎯 我方匹配产品                                     │
+│  · 产品A (SKU) → 匹配 需求X                          │
+│  · 产品B (SKU) → 匹配 需求Y                          │
+│                                                      │
+│  📊 评分详情(可展开)                               │
+│  · 需求明确度:XX分                                  │
+│  · 可信度:XX分                                      │
+│  · 商业规模:XX分                                    │
+│  · 供需匹配:XX分                                    │
+│  · 紧迫度:XX分                                      │
+│                                                      │
+│  📌 推荐行动                                         │
+│  [时效]内发送:[文件1] + [文件2] + [文件3]           │
+│                                                      │
+│  [📧 查看原文]  [🔍 深度调研]  [✅ 确认并建档]       │
+└─────────────────────────────────────────────────────┘
+```
+
+**数据结构**:
+
+```typescript
+interface QuickAssessmentResult {
+  leadId: string;
+  assessedAt: string;
+  
+  // 画像与等级
+  persona: {
+    type: 'P1' | 'P2' | 'P3' | 'P4' | 'P5' | 'P6';
+    confidence: number;                 // 0-100
+    reasoning: string[];                // 判断依据
+  };
+  grade: 'S' | 'A' | 'B' | 'C';
+  followUpDeadline: string;             // ISO 8601(基于等级计算)
+  
+  // 五维评分
+  scores: {
+    demandClarity: number;              // 0-100
+    credibility: number;
+    businessScale: number;
+    productFit: number;
+    urgency: number;
+    total: number;
+  };
+  
+  // 需求快照
+  demandSnapshot: {
+    products: Array<{
+      name: string;
+      quantity: number;
+      unit: string;
+    }>;
+    estimatedAnnualValue: number;       // USD
+    certifications: string[];
+  };
+  
+  // 产品匹配
+  matchedProducts: Array<{
+    productName: string;
+    sku: string;
+    matchReason: string;                // 为什么匹配
+    matchScore: number;                 // 0-100
+  }>;
+  
+  // 推荐行动
+  recommendedActions: {
+    timeframe: string;                  // "24h内" / "3天内" / "7天内"
+    filesToSend: string[];               // 文件列表
+    keyPoints: string[];                // 重点强调的内容
+  };
+}
+```
+
+#### 2.2.7 验收标准
+
+- [ ] 快速研判耗时 < 10 秒
+- [ ] 五维评分准确率 ≥ 85%(与业务员直觉一致)
+- [ ] 画像识别准确率 ≥ 80%
+- [ ] 产品匹配准确率 ≥ 75%
+- [ ] 预估采购额误差 ≤ 30%(基于我方产品单价)
+
+---
+
+### 2.3 第三层:深度调研(按需触发)
+
+#### 2.3.1 触发条件
+
+- **自动触发**:S/A 级线索(快速研判后自动执行)
+- **手动触发**:B 级线索(业务员点击"深度调研"按钮)
+- **不触发**:C 级线索(直接归档)
+
+#### 2.3.2 按画像差异化的调研策略
+
+**P1 医药分销商 → 重点调研:渠道覆盖 + 认证匹配**
+
+```typescript
+async function deepResearchP1(context: ResearchContext): Promise<ResearchResult> {
+  // 1. 搜索公司官网
+  const website = await scrapeCompanyWebsite(context.domain);
+  const companyProfile = {
+    productLines: extractProductLines(website),
+    coverage: extractCoverage(website),        // 覆盖区域
+    partners: extractPartners(website),        // 合作品牌
+  };
+  
+  // 2. 检查 LinkedIn
+  const linkedInData = await fetchLinkedInProfile(context.company);
+  const companyScale = {
+    employees: linkedInData.employeeCount,
+    foundedYear: linkedInData.foundedYear,
+  };
+  
+  // 3. 匹配认证
+  const certificationMatch = checkCertificationMatch(
+    context.requiredCerts,
+    ourCertifications
+  );
+  
+  // 4. 生成报价建议
+  const pricingSuggestion = calculatePricing(
+    context.productRequirements,
+    ourProducts,
+    { volumeDiscount: true }
+  );
+  
+  return {
+    companyProfile,
+    companyScale,
+    certificationMatch,
+    pricingSuggestion,
+    recommendedFiles: [
+      '完整产品目录.pdf',
+      'FDA_510k证书.pdf',
+      'ISO_13485证书.pdf',
+      'CE_Marking证书.pdf'
+    ],
+    suggestedScript: generateScript('P1', context),
+  };
+}
+```
+
+**P3 政府/机构采购 → 重点调研:资质准备 + 投标要点**
+
+```typescript
+async function deepResearchP3(context: ResearchContext): Promise<ResearchResult> {
+  // 1. 解析标书附件
+  const tenderDoc = await parseTenderDocument(context.attachments);
+  const tenderAnalysis = {
+    technicalSpecs: tenderDoc.technicalRequirements,
+    scoringCriteria: tenderDoc.scoringCriteria,
+    deadline: tenderDoc.deadline,
+    lots: tenderDoc.lots,                      // 标段
+  };
+  
+  // 2. 检查资质要求
+  const qualificationCheck = checkQualifications(
+    tenderDoc.requiredQualifications,
+    ourQualifications
+  );
+  
+  // 3. 计算报价
+  const quote = calculateQuote(
+    tenderDoc.lots,
+    ourProducts,
+    { includeShipping: true, includeCert: true }
+  );
+  
+  return {
+    tenderAnalysis,
+    qualificationCheck,
+    quote,
+    recommendedFiles: [
+      '资质文件包.zip',
+      '投标方案.pdf',
+      '合规性检查报告.pdf'
+    ],
+    actionPlan: {
+      deadline: tenderDoc.deadline,
+      tasks: [
+        { task: '准备资质文件', dueDate: '...' },
+        { task: '准备投标方案', dueDate: '...' },
+        { task: '提交投标', dueDate: tenderDoc.deadline },
+      ],
+    },
+    suggestedScript: generateScript('P3', context),
+  };
+}
+```
+
+**P4 品牌OEM客户 → 重点调研:品牌调性 + 定制可行性**
+
+```typescript
+async function deepResearchP4(context: ResearchContext): Promise<ResearchResult> {
+  // 1. 搜索品牌官网
+  const brandWebsite = await scrapeBrandWebsite(context.domain);
+  const brandProfile = {
+    positioning: extractBrandPositioning(brandWebsite),
+    targetMarket: extractTargetMarket(brandWebsite),
+    designStyle: extractDesignStyle(brandWebsite),  // 从图片/色彩分析
+  };
+  
+  // 2. 评估定制需求
+  const customizationReq = context.customRequirements;  // 从邮件提取
+  const feasibility = assessCustomizationFeasibility(
+    customizationReq,
+    ourCapabilities
+  );
+  
+  // 3. 计算打样成本
+  const sampleCost = calculateSampleCost(
+    customizationReq,
+    ourProducts
+  );
+  
+  // 4. 查找类似案例
+  const similarCases = findSimilarOEMCases(
+    brandProfile,
+    ourOEMHistory
+  );
+  
+  return {
+    brandProfile,
+    feasibility,
+    sampleCost,
+    similarCases,
+    recommendedFiles: [
+      'OEM方案书.pdf',
+      '打样报价单.pdf',
+      '类似案例参考.pdf'
+    ],
+    suggestedScript: generateScript('P4', context),
+  };
+}
+```
+
+**P6 低质量线索 → 不执行深度调研**
+
+```typescript
+// 直接归档,不执行任何调研
+function handleP6(context: ResearchContext): void {
+  archiveLead(context.leadId);
+  scheduleBulkEmail(context.email, 'marketing_template');
+}
+```
+
+#### 2.3.3 输出:跟进准备包
+
+**UI 组件结构**:
+
+```
+┌─────────────────────────────────────────────────────┐
+│  📋 跟进准备包 — [公司名]                            │
+│  ─────────────────────────────────────────────────── │
+│                                                      │
+│  🏢 公司画像                                         │
+│  · [公司简介]                                        │
+│  · 覆盖区域:[区域]                                  │
+│  · LinkedIn: [员工数]                                │
+│  · 官网产品线:[产品线列表]                          │
+│                                                      │
+│  👤 联系人画像                                       │
+│  · [姓名] — [职位]                                   │
+│  · 决策权限:[高/中/低]                              │
+│  · LinkedIn: [背景摘要]                              │
+│                                                      │
+│  📦 需求 vs 我方产品匹配                             │
+│  ┌──────────────┬──────────────┬──────────┐          │
+│  │ 客户需求      │ 推荐产品      │ 年采购额  │         │
+│  ├──────────────┼──────────────┼──────────┤          │
+│  │ [需求1]      │ [产品1]      │ $XXX,XXX │          │
+│  │ [需求2]      │ [产品2]      │ $XXX,XXX │          │
+│  └──────────────┴──────────────┴──────────┘          │
+│  💰 预估年采购总额:$XXX,XXX                         │
+│                                                      │
+│  ✅ 认证匹配检查                                     │
+│  · [认证1] → ✅ 我方已有 / ❌ 我方无                  │
+│  · [认证2] → ✅ 我方已有 / ❌ 我方无                  │
+│                                                      │
+│  🎯 建议跟进策略                                     │
+│  1. [时效]内回复邮件,附上:                          │
+│     · [文件1]                                        │
+│     · [文件2]                                        │
+│     · [文件3]                                        │
+│  2. 邮件中[具体建议]                                 │
+│  3. 重点强调:[要点1], [要点2]                       │
+│                                                      │
+│  📝 建议回复话术(可编辑)                           │
+│  ──────────────────────────────────────              │
+│  [AI 生成的个性化回复草稿]                            │
+│  ──────────────────────────────────────              │
+│                                                      │
+│  [✏️ 编辑话术]  [📧 发送邮件]  [✅ 建档并设置提醒]   │
+└─────────────────────────────────────────────────────┘
+```
+
+**数据结构**:
+
+```typescript
+interface DeepResearchResult {
+  leadId: string;
+  researchedAt: string;
+  persona: 'P1' | 'P2' | 'P3' | 'P4' | 'P5' | 'P6';
+  
+  // 公司画像
+  companyProfile: {
+    description: string;
+    coverage?: string[];
+    employees?: number;
+    foundedYear?: string;
+    productLines?: string[];
+    website?: string;
+  };
+  
+  // 联系人画像
+  contactProfile: {
+    name: string;
+    title: string;
+    decisionPower: 'high' | 'medium' | 'low';
+    linkedInSummary?: string;
+  };
+  
+  // 产品匹配详情
+  productMatching: Array<{
+    customerNeed: string;
+    recommendedProduct: {
+      name: string;
+      sku: string;
+    };
+    annualValue: number;
+  }>;
+  totalEstimatedValue: number;
+  
+  // 认证匹配
+  certificationMatch: Array<{
+    required: string;
+    status: 'matched' | 'missing';
+    ourCert?: string;                   // 我方证书名称
+  }>;
+  
+  // 跟进策略
+  followUpStrategy: {
+    timeframe: string;
+    filesToSend: string[];
+    keyPoints: string[];
+    additionalActions?: string[];
+  };
+  
+  // 回复话术
+  suggestedScript: {
+    draft: string;                      // AI 生成的草稿
+    editable: boolean;
+  };
+  
+  // 特殊字段(按画像类型)
+  personaSpecificData?: {
+    // P1: 报价建议
+    pricingSuggestion?: any;
+    // P3: 投标计划
+    tenderActionPlan?: any;
+    // P4: 打样成本
+    sampleCost?: any;
+  };
+}
+```
+
+#### 2.3.4 验收标准
+
+- [ ] 深度调研耗时:P1/P2/P4 ≤ 2 分钟,P3 ≤ 3 分钟
+- [ ] 公司画像准确率 ≥ 80%(与官网信息一致)
+- [ ] 联系人决策权限判断准确率 ≥ 75%
+- [ ] 认证匹配准确率 100%(基于我方认证库)
+- [ ] 回复话术生成质量:业务员直接使用率 ≥ 60%
+
+---
+
+### 2.4 客户建档(自然沉淀)
+
+#### 2.4.1 数据模型
+
+```typescript
+interface Lead {
+  // === 基础信息(第一层自动填充) ===
+  id: string;
+  createdAt: string;
+  updatedAt: string;
+  
+  contact: {
+    name: string;
+    title?: string;
+    email: string;
+    phone?: string;
+    address?: string;
+  };
+  company: {
+    name: string;
+    domain?: string;
+    country?: string;
+  };
+  
+  originalEmail: {
+    subject: string;
+    body: string;
+    attachments: Array<{ name: string, url: string }>;
+    emailId: string;
+  };
+  
+  // === 快速研判结果(第二层自动填充) ===
+  persona?: {
+    type: 'P1' | 'P2' | 'P3' | 'P4' | 'P5' | 'P6';
+    confidence: number;
+    reasoning: string[];
+  };
+  grade?: 'S' | 'A' | 'B' | 'C';
+  scores?: {
+    demandClarity: number;
+    credibility: number;
+    businessScale: number;
+    productFit: number;
+    urgency: number;
+    total: number;
+  };
+  demandSnapshot?: {
+    products: Array<{ name: string, quantity: number, unit: string }>;
+    estimatedAnnualValue: number;
+    certifications: string[];
+  };
+  matchedProducts?: Array<{
+    productName: string;
+    sku: string;
+    matchScore: number;
+  }>;
+  
+  // === 深度调研结果(第三层按需填充) ===
+  deepResearch?: DeepResearchResult;
+  
+  // === 跟进状态 ===
+  status: 'new' | 'assessed' | 'researched' | 'contacted' | 'replied' | 'quoted' | 'archived';
+  followUpDeadline?: string;
+  assignedTo?: string;                 // 业务员ID
+  
+  // === 跟进记录(持续积累) ===
+  communications: Array<{
+    date: string;
+    type: 'email' | 'call' | 'meeting';
+    summary: string;
+    attachments?: string[];
+  }>;
+  quotes: Array<{
+    date: string;
+    products: Array<{ sku: string, price: number, quantity: number }>;
+    status: 'sent' | 'accepted' | 'rejected' | 'pending';
+  }>;
+  samples: Array<{
+    date: string;
+    product: string;
+    status: 'sent' | 'received' | 'approved' | 'rejected';
+  }>;
+  notes: Array<{
+    date: string;
+    author: string;
+    content: string;
+  }>;
+  
+  // === 销售验证 ===
+  salesFeedback?: {
+    verifiedPersona?: 'P1' | 'P2' | 'P3' | 'P4' | 'P5' | 'P6';
+    verifiedGrade?: 'S' | 'A' | 'B' | 'C';
+    notes?: string;
+    verifiedAt?: string;
+  };
+}
+```
+
+#### 2.4.2 状态流转
+
+```
+new (邮件摄入)
+  ↓
+assessed (快速研判完成)
+  ↓
+researched (深度调研完成,可选)
+  ↓
+contacted (业务员确认并建档)
+  ↓
+replied (客户回复)
+  ↓
+quoted (已报价)
+  ↓
+[成交] / [归档]
+```
+
+#### 2.4.3 验收标准
+
+- [ ] 线索自动创建(邮件摄入后)
+- [ ] 数据逐层自动填充(无需手动录入)
+- [ ] 状态流转清晰,支持回退
+- [ ] 跟进记录可追溯
+
+---
+
+## 三、非功能需求
+
+### 3.1 性能要求
+
+| 指标 | 要求 |
+|------|------|
+| 邮件解析 | < 5 秒 |
+| 快速研判 | < 10 秒 |
+| 深度调研 | P1/P2/P4 ≤ 2 分钟,P3 ≤ 3 分钟 |
+| 页面加载 | 首屏 < 2 秒 |
+| API 响应 | P95 < 500ms |
+
+### 3.2 可用性要求
+
+- 系统可用性 ≥ 99.5%
+- 支持并发用户数 ≥ 50
+- 数据备份:每日自动备份
+
+### 3.3 安全要求
+
+- 邮件内容加密存储
+- 用户权限控制(业务员只能看自己的线索)
+- 审计日志(记录所有操作)
+
+### 3.4 兼容性要求
+
+- 浏览器:Chrome 90+, Firefox 88+, Safari 14+, Edge 90+
+- 移动端:响应式设计,支持手机查看
+
+---
+
+## 四、用户流程
+
+### 4.1 主流程:邮件处理
+
+```
+1. 业务员上传 .eml 文件
+   ↓
+2. 系统自动解析邮件(< 5秒)
+   ↓
+3. 系统自动执行快速研判(< 10秒)
+   ↓
+4. 显示快速研判卡片
+   ↓
+5a. S/A 级 → 自动触发深度调研
+5b. B 级 → 业务员选择是否深度调研
+5c. C 级 → 直接归档
+   ↓
+6. 显示跟进准备包
+   ↓
+7. 业务员确认并建档
+   ↓
+8. 进入跟进管道
+```
+
+### 4.2 子流程:画像验证
+
+```
+1. 业务员查看快速研判结果
+   ↓
+2. 发现画像判断有误
+   ↓
+3. 点击"验证画像"
+   ↓
+4. 选择正确画像 + 填写备注
+   ↓
+5. 系统记录反馈,用于模型优化
+```
+
+---
+
+## 五、技术实现要点
+
+### 5.1 核心技术栈
+
+- **前端**:Angular 17+ (与现有 demo-nanchi 保持一致)
+- **后端**:Node.js / Python (待定)
+- **AI 服务**:LLM API (用于 NLP 提取、话术生成)
+- **数据存储**:PostgreSQL (结构化数据) + 文件存储 (附件)
+
+### 5.2 关键算法
+
+- **邮件解析**:使用现有 EML 解析库 + NLP 提取
+- **产品匹配**:语义相似度计算(向量化 + 余弦相似度)
+- **画像识别**:规则引擎 + 机器学习(未来优化)
+- **话术生成**:LLM Prompt Engineering
+
+### 5.3 第三方服务
+
+- **社媒数据**:LinkedIn API(如可用)/ 网页爬取
+- **官网爬取**:Firecrawl / 自建爬虫
+- **企业数据**:可选集成企业信息查询 API
+
+---
+
+## 六、优先级与里程碑
+
+### 6.1 功能优先级
+
+| 优先级 | 功能 | 预计工时 |
+|--------|------|---------|
+| **P0** | 邮件摄入 & 信息提取 | 2 周 |
+| **P0** | 快速研判(五维评分) | 3 周 |
+| **P0** | 客户画像识别(P1-P6) | 2 周 |
+| **P0** | 产品匹配 | 2 周 |
+| **P0** | 快速研判卡片 UI | 1 周 |
+| **P1** | 深度调研(P1 流程) | 2 周 |
+| **P1** | 深度调研(P3 流程) | 2 周 |
+| **P1** | 深度调研(P4 流程) | 2 周 |
+| **P1** | 跟进准备包 UI | 1 周 |
+| **P1** | 客户建档(数据模型) | 1 周 |
+| **P2** | 回复话术生成 | 2 周 |
+| **P2** | 画像验证机制 | 1 周 |
+| **P2** | 看板视图(按等级/画像) | 1 周 |
+
+### 6.2 里程碑
+
+| 里程碑 | 时间 | 交付物 |
+|--------|------|--------|
+| **M1: MVP** | 第 8 周 | 邮件摄入 + 快速研判 + 基础建档 |
+| **M2: 深度调研** | 第 12 周 | P1/P3/P4 深度调研流程 |
+| **M3: 完整功能** | 第 16 周 | 全部功能上线 |
+
+---
+
+## 七、验收标准总结
+
+### 7.1 功能验收
+
+- [ ] 邮件解析准确率 ≥ 95%
+- [ ] 快速研判耗时 < 10 秒
+- [ ] 五维评分准确率 ≥ 85%
+- [ ] 画像识别准确率 ≥ 80%
+- [ ] 产品匹配准确率 ≥ 75%
+- [ ] 深度调研耗时符合要求
+- [ ] 回复话术直接使用率 ≥ 60%
+
+### 7.2 业务验收
+
+- [ ] 单封邮件处理时间从 5-10 分钟降至 1-3 分钟
+- [ ] S/A 级线索跟进率 ≥ 90%
+- [ ] 业务员满意度 ≥ 4.0/5.0
+
+---
+
+*PRD 文档版本:v1.0*  
+*最后更新:2026-02-12*
+

+ 592 - 0
lead-discovery/docs/PRODUCT_LOGIC_REDESIGN.md

@@ -0,0 +1,592 @@
+# 产品逻辑重新梳理:从线索到客户建档及价值判断
+
+> 以产品经理视角,从原始邮件数据和真实业务场景出发,重新梳理"客户发掘"全链路产品逻辑。
+
+---
+
+## 一、从原始数据看真实业务场景
+
+### 1.1 六封样本邮件的深度拆解
+
+逐封回到原始邮件,提炼**业务员真正需要判断的东西**:
+
+#### 邮件 e1 — Acme Medical Supplies(John Smith)
+
+| 原文信号 | 业务员真正关心的问题 |
+|---------|-------------------|
+| "Head of Procurement" | 这人是采购负责人,能拍板吗? |
+| "120 hospitals and 350 urgent care clinics" | 客户渠道有多大?这个网络规模意味着什么量级? |
+| "5,000 units/year IFAK + 10,000 refills + 800 cabinets" | 有明确的品类和数量,能算出年采购额吗? |
+| "FDA registered, ISO 13485, CE" | 我们的认证能不能满足? |
+| "FOB pricing, Lead time, MOQ" | 对方已经在比价阶段了,紧迫性如何? |
+| 附件:Company Profile + Requirements Spec + Hospital Network List | 对方是认真的,提供了详细资料 |
+
+**业务员的核心判断**:这是一个美国医疗分销商,渠道规模大(120+医院),需求明确具体,认证要求我方可满足,年采购额预估 $120K+。**应该立即跟进**。
+
+#### 邮件 e2 — SafetyFirst UK(Sarah Johnson)
+
+| 原文信号 | 业务员真正关心的问题 |
+|---------|-------------------|
+| "Following our conversation at the Birmingham Safety Expo" | 展会上已经聊过,有前期信任基础 |
+| "5,000 commercial and industrial clients" | 客户自己的下游覆盖面 |
+| "1,200 + 600 units cabinets, 3,000 + 1,500 refills/year" | 具体品类和数量 |
+| "Custom labeling with SafetyFirst branding" | 需要白标/OEM,利润空间如何? |
+| "DDP terms preferred" | 对贸易术语有要求,运费成本要算进去 |
+
+**业务员的核心判断**:英国工业安全供应商,展会已建立联系,需求具体(壁挂箱+补充包),有白标需求。**3天内跟进,先报价**。
+
+#### 邮件 e3 — Polish Red Cross(Marek Kowalski)
+
+| 原文信号 | 业务员真正关心的问题 |
+|---------|-------------------|
+| "TENDER NOTICE" + Reference Number | 正式招标,有截止日期(Mar 15) |
+| "EU-funded" | 有预算保障,不用担心付款能力 |
+| "Lot 1/2/3" + 具体数量和规格 | 需求极其明确,按标书来 |
+| "SUBMISSION DEADLINE: March 15, 2026" | **时间紧迫**,只有一个月 |
+| "CE + ISO 13485 mandatory" | 硬性认证门槛 |
+| 4个附件包括完整标书 | 这是正式采购流程 |
+
+**业务员的核心判断**:正式招标项目,有EU资金支持,金额大(500个大包+2000个IFAK+3000补充包,预估 $200K+),但**截止日期紧迫**,需要立即准备标书和资质文件。
+
+#### 邮件 e4 — WildGear GmbH(Alexander Müller)
+
+| 原文信号 | 业务员真正关心的问题 |
+|---------|-------------------|
+| "Product Development Manager" | 产品开发经理,不是采购,决策链不同 |
+| "12 years in the market, 200+ retail partners" | 品牌有历史有渠道 |
+| "private-label first aid kits" | OEM贴牌需求,利润模式不同 |
+| "Pantone colors, custom insert card, QR code" | 定制化程度高,打样成本要考虑 |
+| "Target retail price: €29.99" | 对方已经定好零售价,我方利润空间有限 |
+| Brand Guidelines + Mood Board | 对品牌调性要求很高 |
+
+**业务员的核心判断**:德国户外品牌的OEM需求,定制化程度高,首单量不大(3000+5000+2000),但年度预测量可观(10K-20K/年)。**需要评估打样成本和利润率后再跟进**。
+
+#### 邮件 e5 — Global Trading 88(Mike Chen)
+
+| 原文信号 | 业务员真正关心的问题 |
+|---------|-------------------|
+| "Hello friend" | 群发式开头 |
+| "all kinds of products", "We buy everything" | 没有任何具体需求 |
+| "lowest price for big quantity" | 只关心价格 |
+| "clearance or overstock items", "B-grade products" | 想要尾货和次品 |
+| 无附件,免费邮箱域名 | 没有任何公司背景佐证 |
+
+**业务员的核心判断**:典型的套价格/无效询盘。没有具体产品需求,没有公司背景,不值得花时间。**直接归档**。
+
+#### 邮件 e6 — MediTech Supply Canada(Lisa Wang)
+
+| 原文信号 | 业务员真正关心的问题 |
+|---------|-------------------|
+| "Business Development Director" | BD总监,有战略合作意图 |
+| "15 years, 800+ facilities, CAD $45M revenue" | 公司实力数据非常详细 |
+| "MEDICA trade show" | 在展会上已经看过我们产品 |
+| "Exclusive distribution rights for Canada" | 想做独家代理 |
+| "Annual minimum purchase commitment: USD $200,000" | 主动承诺最低采购额 |
+| 5个附件包括 Company Profile, Network Map, Partnership Proposal, Import License | 准备非常充分 |
+
+**业务员的核心判断**:加拿大头部医疗分销商,主动寻求独家代理,年承诺 $200K,公司实力强($45M营收),已在展会了解过产品。**这是最高优先级的战略合作机会**。
+
+---
+
+### 1.2 从邮件数据中提炼:业务员的判断维度
+
+回到原始数据,业务员拿到一封邮件后,**真正在脑子里做的判断**不是"这个客户属于P几",而是在回答以下几个问题:
+
+```
+① 这个人/公司是真的吗?(真实性)
+   → 有没有公司域名邮箱?有没有官网?有没有附件佐证?
+   → 能不能在 LinkedIn/Google 上搜到?
+
+② 他要什么?(需求明确度)
+   → 有没有提到具体产品?有没有数量?有没有规格要求?
+   → 是泛泛地问"你们有什么",还是精确地说"我要500个R9背包"?
+
+③ 他能买多少?(商业规模)
+   → 公司有多大?渠道覆盖多广?年采购额大概多少?
+   → 是一次性小单还是持续复购?
+
+④ 我们能不能做?(供需匹配)
+   → 他要的产品我们有没有?认证能不能满足?
+   → 如果是OEM,我们的产能和定制能力够不够?
+
+⑤ 现在该做什么?(行动决策)
+   → 是发目录?报价?准备标书?还是直接忽略?
+   → 紧迫性如何?有没有截止日期?
+```
+
+---
+
+## 二、现有系统的问题诊断
+
+### 2.1 nanchi 原系统的问题
+
+nanchi 的背调系统功能强大但**过于工程化**,存在以下产品问题:
+
+| 问题 | 具体表现 |
+|------|---------|
+| **流程过重** | 一次背调 5 个阶段,3-8 分钟,对于"先快速判断值不值得跟进"这个需求来说太重了 |
+| **信息过载** | 三维报告(公司实力/决策人/采购项目)输出大量信息,但业务员最需要的"我现在该做什么"被淹没了 |
+| **缺少分层** | 所有线索都走同一条重量级背调流水线,没有"先快筛再深挖"的分层机制 |
+| **与邮件脱节** | 背调报告和邮件原文是分开的,业务员需要来回切换才能将背调结果与客户需求对应起来 |
+| **没有画像体系** | 没有"这是什么类型的客户"的快速分类,每次都要从头看完整报告才能理解客户 |
+
+### 2.2 demo-nanchi 的问题
+
+demo-nanchi 的画像体系设计有亮点,但也有明显的产品逻辑问题:
+
+| 问题 | 具体表现 |
+|------|---------|
+| **画像分类过于静态** | P1-P6 是预定义的,但现实中客户类型更复杂(比如一个既做分销又做OEM的客户) |
+| **等级评估维度缺失** | S/A/B/C 等级主要靠关键词匹配,没有考虑"需求明确度""公司真实性"等关键因素 |
+| **快速筛选太粗** | 只做了关键词匹配,没有结合邮件附件、产品数量、认证要求等结构化信息 |
+| **深度分析是空壳** | "启动深度分析"按钮存在但无实现,画像验证后没有后续动作 |
+| **产品匹配太机械** | 按 Category → SKU 的固定映射,没有考虑客户邮件中提到的具体产品和数量 |
+| **缺少"为什么"** | 告诉业务员"这是P1-医药分销商",但没有充分解释"为什么这么判断" |
+
+---
+
+## 三、重新设计的产品逻辑
+
+### 3.1 核心设计原则
+
+> **"先快后深,分层决策,以行动为导向"**
+
+1. **先快后深**:先用 10 秒给出初步判断(值不值得看),再花 3 分钟做深度分析(怎么跟进)
+2. **分层决策**:不同价值的线索走不同深度的分析流程,不浪费资源
+3. **以行动为导向**:每一步输出的不是"信息",而是"你现在应该做什么"
+
+### 3.2 重新设计的三层漏斗
+
+```
+┌─────────────────────────────────────────────────────────────────┐
+│                                                                  │
+│   第一层:邮件摄入 & 信息提取(自动 · <5秒)                     │
+│   ─────────────────────────────────────────                      │
+│   输入:.eml 文件 / 手动录入                                     │
+│   输出:结构化邮件数据(联系人/公司/产品需求/附件)               │
+│   价值:把非结构化邮件变成结构化数据                              │
+│                                                                  │
+│         ┌──────────────┐                                         │
+│         │  全部邮件进入 │                                         │
+│         └──────┬───────┘                                         │
+│                ▼                                                  │
+│   第二层:快速研判(自动 · <10秒)                                │
+│   ─────────────────────────────────                              │
+│   输入:结构化邮件数据                                           │
+│   输出:① 客户画像(是谁)                                      │
+│         ② 需求快照(要什么)                                     │
+│         ③ 可信度评分(真不真)                                   │
+│         ④ 紧迫度标记(急不急)                                   │
+│         ⑤ 行动建议(做什么)                                     │
+│   价值:让业务员 10 秒内决定"要不要花时间看这封邮件"             │
+│                                                                  │
+│         ┌────────┐  ┌────────┐  ┌────────┐                      │
+│         │ 立即跟进│  │ 计划跟进│  │  归档   │                     │
+│         │ (S/A级) │  │ (B级)  │  │ (C级)  │                      │
+│         └───┬────┘  └───┬────┘  └────────┘                      │
+│             ▼           ▼                                        │
+│   第三层:深度调研(按需 · 1-3分钟)                              │
+│   ──────────────────────────────────                             │
+│   输入:快速研判结果 + 公司域名/官网                              │
+│   输出:① 公司实力验证(官网/社媒/企业数据)                     │
+│         ② 产品匹配分析(客户需求 vs 我方产品)                   │
+│         ③ 决策人画像(联系人的职位/权限/背景)                   │
+│         ④ 竞品与定价建议                                         │
+│         ⑤ 个性化跟进策略 & 话术                                  │
+│   价值:帮业务员准备好"第一次接触客户"所需的全部弹药             │
+│                                                                  │
+│         ┌──────────────────────┐                                 │
+│         │  客户建档 & 跟进计划  │                                 │
+│         └──────────────────────┘                                 │
+│                                                                  │
+└─────────────────────────────────────────────────────────────────┘
+```
+
+---
+
+### 3.3 第一层:邮件摄入 & 信息提取
+
+**目标**:将一封非结构化的邮件变成结构化的数据卡片。
+
+**提取维度**(基于6封样本邮件的共性分析):
+
+| 维度 | 提取方式 | 示例(e1 Acme Medical) |
+|------|---------|----------------------|
+| **联系人** | 签名块解析 | John Smith, Head of Procurement |
+| **公司名** | 签名块 + 域名 | Acme Medical Supplies |
+| **邮箱域名** | @后缀 | acmemedical.com |
+| **国家** | 签名块地址 + 域名后缀 | US (Ohio) |
+| **产品需求** | 正文 + 附件 NLP | IFAK 5000/yr, Refill 10000/yr, Cabinet 800 |
+| **数量级** | 数字提取 | 年采购 15,800 件 |
+| **认证要求** | 关键词 | FDA, ISO 13485, CE |
+| **贸易术语** | 关键词 | FOB |
+| **紧迫性信号** | 截止日期/催促语气 | "prompt reply" → 中等 |
+| **附件清单** | 文件名 + 类型 | 3个附件(公司简介/需求规格/医院网络列表) |
+
+**关键产品决策**:
+- 附件中的"Company Profile"和"Requirements Spec"要**特别标注**,因为这类附件意味着对方是认真的
+- 如果邮件中有具体数量(如"5,000 units/year"),要自动计算预估年采购额
+
+---
+
+### 3.4 第二层:快速研判(核心重新设计)
+
+**目标**:10 秒内告诉业务员"这封邮件值不值得花时间"。
+
+#### 3.4.1 重新设计的评估维度
+
+不再是简单的关键词匹配,而是基于**业务员真实判断逻辑**的多维评估:
+
+```
+快速研判 = f(需求明确度, 可信度, 商业规模, 供需匹配, 紧迫度)
+```
+
+**维度一:需求明确度(Demand Clarity)**
+
+| 信号 | 得分规则 | 邮件举例 |
+|------|---------|---------|
+| 提到具体产品名 | +20 | "IFAK kits", "wall-mounted cabinets" |
+| 有明确数量 | +25 | "5,000 units/year" |
+| 有规格要求 | +15 | "MOLLE compatible", "MARCH-P protocol" |
+| 有认证要求 | +10 | "FDA registered", "ISO 13485" |
+| 询问价格/MOQ/交期 | +15 | "FOB pricing", "Lead time" |
+| 只说"send catalog" | +5 | e5: "send us your full catalog" |
+| 无任何具体需求 | 0 | e5: "all kinds of products" |
+
+**维度二:可信度(Credibility)**
+
+| 信号 | 得分规则 | 邮件举例 |
+|------|---------|---------|
+| 企业域名邮箱 | +15 | @acmemedical.com ✅ |
+| 免费邮箱(gmail等) | -10 | @globaltrading88.com ⚠️ |
+| 有完整签名块(职位+电话+地址) | +20 | e1/e2/e3/e4/e6 全部有 |
+| 有附件(公司资料/需求文档) | +20 | e1: 3个附件, e6: 5个附件 |
+| 有抄送(说明有组织流程) | +10 | e3: cc logistics + legal |
+| 提到展会/面谈经历 | +15 | e2: "Birmingham Safety Expo" |
+| 无附件+无签名+模糊内容 | 0 | e5 全部缺失 |
+
+**维度三:商业规模(Business Scale)**
+
+| 信号 | 得分规则 | 邮件举例 |
+|------|---------|---------|
+| 提到公司规模/营收 | +20 | e6: "CAD $45M revenue" |
+| 提到下游客户数量 | +15 | e1: "120 hospitals, 350 clinics" |
+| 年采购量 > $100K | +25 | e3: ~$200K, e6: $200K承诺 |
+| 年采购量 $30K-$100K | +15 | e1: ~$120K |
+| 年采购量 < $30K | +5 | e4: ~$35K |
+| 无法判断规模 | 0 | e5 |
+
+**维度四:供需匹配(Product Fit)**
+
+| 信号 | 得分规则 | 邮件举例 |
+|------|---------|---------|
+| 提到的产品我方有对应 SKU | +25/匹配项 | e1: IFAK→CPIK0501, Cabinet→CPHW0056 |
+| 认证要求我方可满足 | +15 | FDA/CE/ISO 13485 ✅ |
+| 需要定制但我方有能力 | +10 | e4: OEM定制 |
+| 产品完全不匹配 | -20 | — |
+
+**维度五:紧迫度(Urgency)**
+
+| 信号 | 得分规则 | 邮件举例 |
+|------|---------|---------|
+| 有明确截止日期 | +30 | e3: "March 15, 2026" |
+| 催促性语言 | +15 | "prompt reply", "ASAP" |
+| 提到正在比价/选供应商 | +10 | "looking for a reliable manufacturer" |
+| 提到长期合作/代理 | +5(长期但不急) | e6: "authorized distributor" |
+| 无紧迫信号 | 0 | e5 |
+
+#### 3.4.2 综合评级算法
+
+```
+总分 = 需求明确度 × 0.25 + 可信度 × 0.25 + 商业规模 × 0.20 + 供需匹配 × 0.15 + 紧迫度 × 0.15
+
+S级(立即跟进 · 24h内):总分 ≥ 80,且可信度 ≥ 60
+A级(3天内跟进)       :总分 ≥ 60,且需求明确度 ≥ 40
+B级(7天内跟进)       :总分 ≥ 35
+C级(归档观察)        :总分 < 35
+```
+
+**用6封邮件验证**:
+
+| 邮件 | 需求 | 可信 | 规模 | 匹配 | 紧迫 | 总分 | 等级 | 符合直觉? |
+|------|------|------|------|------|------|------|------|-----------|
+| e1 Acme Medical | 85 | 85 | 75 | 80 | 50 | **76** | **S** | ✅ 大型医疗分销商,需求明确 |
+| e2 SafetyFirst | 80 | 80 | 65 | 70 | 40 | **69** | **A** | ✅ 展会认识的,有具体需求 |
+| e3 Red Cross | 95 | 90 | 85 | 75 | 95 | **89** | **S** | ✅ 正式招标,金额大,时间紧 |
+| e4 WildGear | 70 | 75 | 50 | 60 | 30 | **59** | **B→A** | ✅ OEM需求明确但规模中等 |
+| e5 Global Trading | 5 | 15 | 0 | 10 | 10 | **8** | **C** | ✅ 典型无效询盘 |
+| e6 MediTech | 75 | 95 | 90 | 85 | 35 | **78** | **S** | ✅ 战略合作机会 |
+
+> 结论:这个评分体系与业务员的直觉判断**高度一致**。
+
+#### 3.4.3 客户画像(保留但重新定义)
+
+画像的目的不是"分类",而是**帮业务员快速理解"这是什么类型的客户,应该用什么方式对待"**。
+
+保留 P1-P6 的框架,但重新定义其**触发逻辑**和**行动指导**:
+
+| 画像 | 核心识别逻辑(不只是关键词) | 差异化行动 |
+|------|---------------------------|-----------|
+| **P1 医药分销商** | 企业邮箱 + 提到"distributor/wholesale" + 有FDA/ISO需求 + 有具体SKU级需求 | 发完整产品目录+认证文件包,强调供应稳定性 |
+| **P2 工业安全供应商** | 提到OSHA/ANSI + 壁挂箱/急救站需求 + 企业客户导向 | 发OSHA合规产品线,强调定制标签能力 |
+| **P3 政府/机构采购** | 有标书编号/招标通知 + 提到tender/procurement/lot + 有截止日期 | 立即准备资质文件包+投标方案,注意截止日期 |
+| **P4 品牌OEM客户** | 提到OEM/private label/custom branding + 有品牌设计要求 + 关注打样 | 发OEM案例+定制能力介绍,评估打样成本 |
+| **P5 电商/零售商** | 提到Amazon/Shopify/FBA + 关注单品利润率 + 小批量 | 推荐爆款+利润率分析,强调产品图片支持 |
+| **P6 低质量/无效** | 免费邮箱 + 无具体需求 + 无附件 + 模糊语言("all kinds", "lowest price") | 自动归档,不投入人工 |
+
+**关键改进**:画像判断不再只看关键词,而是综合考虑**邮件结构特征**(有无附件、签名块完整度、抄送人数量等),这些特征比关键词更能反映真实意图。
+
+#### 3.4.4 快速研判的输出卡片
+
+业务员看到的不是一堆分数,而是一张**一眼能看懂的决策卡片**:
+
+```
+┌─────────────────────────────────────────────────────┐
+│  🏥 Acme Medical Supplies                     🇺🇸 US │
+│  ─────────────────────────────────────────────────── │
+│  📋 P1-医药分销商 · S级 · 立即跟进                   │
+│                                                      │
+│  📦 需求摘要                                         │
+│  · IFAK战术急救包 × 5,000/年                         │
+│  · 补充套件 × 10,000/年                              │
+│  · 壁挂式急救箱 × 800                                │
+│  💰 预估年采购额:$120,000+                          │
+│                                                      │
+│  ✅ 可信度:高                                       │
+│  · 企业邮箱 · 完整签名块 · 3份附件(含公司简介)     │
+│                                                      │
+│  🎯 我方匹配产品                                     │
+│  · SE IFAK Pro (CPIK0501) → 匹配 IFAK 需求          │
+│  · 17A补充套件 (CPTK0301) → 匹配 Refill 需求        │
+│  · 壁挂式急救箱 (CPHW0056) → 匹配 Cabinet 需求      │
+│                                                      │
+│  📌 推荐行动                                         │
+│  24h内发送:产品目录 + FOB报价单 + 认证文件包        │
+│  (FDA 510k + ISO 13485 + CE)                         │
+│                                                      │
+│  [📧 查看原文]  [🔍 深度调研]  [✅ 确认并建档]       │
+└─────────────────────────────────────────────────────┘
+```
+
+> 这张卡片回答了业务员的全部核心问题:是谁、要什么、多大规模、我们能不能做、现在该做什么。
+
+---
+
+### 3.5 第三层:深度调研(按需触发)
+
+**触发条件**:S/A级线索自动触发,B级线索业务员手动触发。
+
+**与 nanchi 背调的关键区别**:
+
+| 维度 | nanchi 原背调 | 重新设计的深度调研 |
+|------|-------------|------------------|
+| 目的 | 生成完整的三维报告 | **帮业务员准备好"第一次接触客户"的弹药** |
+| 时长 | 3-8分钟 | 1-3分钟(按画像类型差异化执行) |
+| 输出 | 信息密集的报告 | **行动导向的跟进准备包** |
+| 流程 | 所有客户走同一流程 | **按画像类型走差异化流程** |
+
+#### 3.5.1 按画像差异化的调研策略
+
+这是关键创新——**不同类型的客户,需要调研的方向完全不同**:
+
+**P1 医药分销商 → 重点调研:渠道覆盖 + 认证匹配**
+```
+① 搜索公司官网 → 提取产品线、覆盖区域、合作品牌
+② 检查 LinkedIn → 公司规模、员工数
+③ 匹配认证 → 客户要求的认证 vs 我方已有认证
+④ 生成:报价建议 + 认证文件清单 + 建议话术
+```
+
+**P3 政府/机构采购 → 重点调研:资质准备 + 投标要点**
+```
+① 解析标书附件 → 提取技术规格、评分标准、截止日期
+② 检查资质要求 → 我方是否满足全部硬性条件
+③ 计算报价 → 基于数量和规格的报价方案
+④ 生成:资质文件清单 + 投标时间表 + 合规性检查报告
+```
+
+**P4 品牌OEM客户 → 重点调研:品牌调性 + 定制可行性**
+```
+① 搜索品牌官网 → 了解品牌定位、目标市场、设计风格
+② 评估定制需求 → Pantone色号/Logo/包装的可行性
+③ 计算打样成本 → 基于定制要求的打样费用和时间
+④ 生成:OEM方案书 + 打样报价 + 类似案例参考
+```
+
+**P6 低质量线索 → 不执行深度调研**
+```
+直接归档,定期群发营销邮件
+```
+
+#### 3.5.2 深度调研的输出:跟进准备包
+
+不是一份"报告",而是一个**可直接用于行动的准备包**:
+
+```
+┌─────────────────────────────────────────────────────┐
+│  📋 跟进准备包 — Acme Medical Supplies               │
+│  ─────────────────────────────────────────────────── │
+│                                                      │
+│  🏢 公司画像                                         │
+│  · 美国俄亥俄州医疗耗材分销商                        │
+│  · 覆盖 120+ 医院、350+ 诊所(中西部地区)           │
+│  · LinkedIn: 约 200 员工                             │
+│  · 官网产品线:急救用品、手术耗材、PPE               │
+│                                                      │
+│  👤 联系人画像                                       │
+│  · John Smith — 采购负责人                           │
+│  · 有权限做采购决策(Head of Procurement)            │
+│  · LinkedIn: 在 Acme 工作 5 年+                      │
+│                                                      │
+│  📦 需求 vs 我方产品匹配                             │
+│  ┌──────────────┬──────────────┬──────────┐          │
+│  │ 客户需求      │ 推荐产品      │ 年采购额  │         │
+│  ├──────────────┼──────────────┼──────────┤          │
+│  │ IFAK 5000/yr │ SE IFAK Pro  │ $150,000 │          │
+│  │ Refill 10000 │ 17A套件袋    │ $250,000 │          │
+│  │ Cabinet 800  │ 壁挂式急救箱  │ $28,000  │          │
+│  └──────────────┴──────────────┴──────────┘          │
+│  💰 预估年采购总额:$428,000                         │
+│                                                      │
+│  ✅ 认证匹配检查                                     │
+│  · FDA 510(k) → ✅ 我方已有                          │
+│  · ISO 13485  → ✅ 我方已有                          │
+│  · CE Marking → ✅ 我方已有                          │
+│                                                      │
+│  🎯 建议跟进策略                                     │
+│  1. 24h内回复邮件,附上:                            │
+│     · 完整产品目录(PDF)                            │
+│     · 针对性报价单(基于其数量需求)                  │
+│     · FDA/ISO/CE 认证文件包                          │
+│  2. 邮件中提议安排视频会议(对方已主动提出)          │
+│  3. 重点强调:供应稳定性、认证齐全、复购支持          │
+│                                                      │
+│  📝 建议回复话术(可编辑)                           │
+│  ──────────────────────────────────────              │
+│  Dear Mr. Smith,                                     │
+│  Thank you for your inquiry regarding IFAK kits...   │
+│  [AI 生成的个性化回复草稿]                           │
+│  ──────────────────────────────────────              │
+│                                                      │
+│  [✏️ 编辑话术]  [📧 发送邮件]  [✅ 建档并设置提醒]   │
+└─────────────────────────────────────────────────────┘
+```
+
+---
+
+### 3.6 客户建档(自然沉淀,而非独立步骤)
+
+**关键理念**:客户建档不应该是一个"额外的步骤",而应该是**跟进过程中的自然沉淀**。
+
+```
+邮件进入 → 自动创建线索卡片(含提取的结构化数据)
+           ↓
+快速研判 → 自动填充画像、等级、匹配产品
+           ↓
+深度调研 → 自动补充公司信息、联系人画像、认证匹配
+           ↓
+业务员确认 → 线索升级为"客户",进入跟进管道
+           ↓
+跟进过程 → 持续积累沟通记录、报价历史、样品寄送记录
+```
+
+**客户档案的数据结构**(逐步丰富,而非一次性填充):
+
+```
+客户档案 = {
+  // === 第一层自动填充(邮件摄入时) ===
+  基础信息: { 公司名, 联系人, 邮箱, 国家 },
+  原始邮件: { 主题, 正文, 附件列表 },
+
+  // === 第二层自动填充(快速研判时) ===
+  画像分类: { 画像类型, 置信度, 判断依据 },
+  价值等级: { 等级, 各维度得分 },
+  需求快照: { 产品需求列表, 数量, 认证要求, 预估采购额 },
+  产品匹配: { 匹配产品列表, 匹配度 },
+
+  // === 第三层按需填充(深度调研时) ===
+  公司画像: { 官网信息, 社媒数据, 规模, 行业 },
+  联系人画像: { LinkedIn, 职位权限, 决策能力 },
+  竞品情报: { 当前供应商, 竞品价格 },
+  跟进策略: { 推荐行动, 话术草稿, 认证文件清单 },
+
+  // === 第四层持续积累(跟进过程中) ===
+  沟通记录: [{ 日期, 方式, 内容摘要 }],
+  报价历史: [{ 日期, 产品, 价格, 状态 }],
+  样品记录: [{ 日期, 产品, 状态 }],
+  业务员备注: [{ 日期, 内容 }]
+}
+```
+
+---
+
+## 四、与现有系统的融合建议
+
+### 4.1 保留 demo-nanchi 的优势
+
+| 保留 | 原因 |
+|------|------|
+| P1-P6 画像体系 | 框架合理,但需要加强识别逻辑 |
+| S/A/B/C 等级体系 | 与跟进时效直接挂钩,业务员易理解 |
+| 画像知识库页面 | 让业务员理解和参与画像定义,形成经验沉淀 |
+| EML 导入 + 产品需求提取 | 已有真实 API 对接,可直接复用 |
+| 看板视图(按等级/画像/阶段) | 多维度管理线索的 UI 设计优秀 |
+| 销售验证机制 | 人机协同,AI判断+人工确认 |
+
+### 4.2 从 nanchi 吸收的能力
+
+| 吸收 | 原因 |
+|------|------|
+| 社媒验证(LinkedIn/Instagram) | 公司可信度验证的关键数据源 |
+| 官网爬取与分析 | 了解客户产品线和业务范围 |
+| 决策人调查 | 判断联系人是否有采购决策权 |
+| Agent 价值分析的五维度框架 | 但简化为更轻量的版本 |
+| 产品提取(邮件+官网双源) | 丰富需求理解 |
+
+### 4.3 需要新增的能力
+
+| 新增 | 原因 |
+|------|------|
+| **需求明确度评分** | 当前系统没有评估"客户需求有多具体" |
+| **预估采购额自动计算** | 基于提取的产品×数量×我方单价 |
+| **认证匹配检查** | 自动比对客户要求的认证 vs 我方已有认证 |
+| **按画像差异化的调研流程** | 不同客户类型走不同的深度调研路径 |
+| **跟进准备包(而非报告)** | 输出以行动为导向,而非以信息为导向 |
+| **回复话术生成** | 基于画像+需求+策略,生成个性化回复草稿 |
+
+---
+
+## 五、总结:产品逻辑的核心转变
+
+```
+┌──────────────────────────────────────────────────────────┐
+│                                                           │
+│   旧逻辑:邮件 → 背调(重) → 报告(信息密集) → 人工判断 │
+│                                                           │
+│   新逻辑:邮件 → 快速研判(轻) → 行动建议 → 按需深挖     │
+│                      ↓                                    │
+│              "10秒告诉你值不值得跟进"                      │
+│              "3分钟帮你准备好跟进弹药"                     │
+│                                                           │
+└──────────────────────────────────────────────────────────┘
+```
+
+**三个核心转变**:
+
+1. **从"信息输出"到"行动输出"**
+   - 旧:给你一份详细的背调报告,你自己判断怎么做
+   - 新:直接告诉你"现在发这三个文件给对方,用这个话术"
+
+2. **从"一刀切"到"差异化"**
+   - 旧:所有客户走同一条背调流水线
+   - 新:P1 重点查认证匹配,P3 重点查标书合规,P4 重点查品牌调性
+
+3. **从"先调研后判断"到"先判断后调研"**
+   - 旧:花 5 分钟背调完才知道值不值得跟进
+   - 新:10 秒先判断值不值得,值得的再花 3 分钟深挖
+
+---
+
+*文档生成时间:2026-02-12*
+*分析基础:6封原始邮件样本 + nanchi 背调系统 + demo-nanchi 画像系统*
+

+ 69 - 0
lead-discovery/docs/ltc.md

@@ -0,0 +1,69 @@
+这份资料是**AI赋能B2B销售的实战工作坊内容**,核心围绕**LTC(Leads to Cash,从线索到现金)** 全链路销售体系展开,结合AI工具与实战方法论,重构B2B销售的全流程运作逻辑,最终实现价值成交。以下是核心内容的系统总结,分为**LTC核心框架、价值成交体系、AI赋能落地、各环节实战方法论**四大模块,逻辑清晰且贴合B2B销售实操:
+
+# 一、LTC销售全链路核心框架
+LTC是B2B销售的核心运作体系,以**线索获取到现金回款**为全流程,强调**端到端的流程管控、团队协作和数智化支撑**,是B2B销售的底层逻辑。
+1. **LTC全流程节点**:收集生成线索→验证分发线索→跟踪培育线索→验证机会点→制定提交方案→谈判生成合同→合同执行/交付→开票回款→合同关闭评价,覆盖从线索到回款的全生命周期。
+2. **核心团队架构**:以**CC3铁三角(AR客户经理+SR解决方案经理+FR交付经理)** 为核心,端到端负责项目运作,明确各角色职责。
+3. **关键管控点**:设置立项、投标、签约、合同关闭等**销售/交付决策点**,以及投标评审、合同评审等**专业评审点**,同时把控合同签订、风险防控等**质量/风险点**,规范流程并提升效率。
+4. **支撑体系**:以**数智化平台**为地基,结合团队、机制、业务设计,实现LTC全流程的高效运转。
+
+# 二、价值成交的核心体系:五维控盘
+成交的本质是**撬动客户“痛苦-收益”天平**(放大现状痛苦,让改变的收益清晰可见),核心公式为:**成交=(价值定位×痛点挖掘)×信任构建×流程控制**,并落地为**五维控盘实战体系**,从认知到流程实现全维度控局,摆脱传统被动销售模式:
+1. **刷认知**:从“推销员”升级为“商业顾问”,用**3T法则(Teach教学/传递商业洞察、Tailor定制/结合客户KPI、Take Control主导/把控购买流程)** 重构客户认知,顶尖销售中40%为“挑战者”型,远高于7%的“关系先生”型。
+2. **理情报**:绘制客户**权力地图**,识别决策链中的关键角色(EB经济决策者/TB技术决策者/UB使用决策者/Coach内线等),区分**组织架构图(形式权力)** 和**影响力地图(实际权力)**,避免被“隐形否决者”影响。
+3. **探需求**:用**SPIN提问法**将客户**隐性需求转化为显性采购订单**,即S现状→P难点→I暗示(放大痛点后果)→N需求效益(引导客户说出解决方案价值),同时用**四F框架(Future未来/First首要/Failure失效/Finest最佳)** 深挖核心痛点。
+4. **建信任**:构建**五层信任阶梯(可靠→专业→亲近→共情→共创)**,落地**信任公式T=(C可信度+R可靠度+I亲密度)/S自我导向**(自我导向是唯一减分项,需始终聚焦客户利益),并通过服务补救“正义铁三角”(结果/互动/程序公平)化解信任危机。
+5. **控流程**:从“管理销售动作”升级为“设计销售系统”,以**结果为导向**管控流程,设置各阶段**通关标准**,追踪**阶段转化率、销售周期、管道速度**三大核心指标,打造可预测的增长引擎。
+
+# 三、AI对LTC全链路的赋能:重塑智能销售之旅
+AI是LTC全流程的核心工具,并非单纯的效率提升手段,而是**从线索到回款各环节的智能化重构**,实现“人+AI”的高效协同,核心落地场景覆盖LTC全链路:
+1. **线索阶段**:智能线索生成与评分,从海量数据中筛选高价值潜客,替代人工筛选;通过AI实现**线索评级五步法(市场聚焦→价值建模→线索验证→线索评估→分级)**,精准定位优质线索。
+2. **商机培育**:AI驱动**个性化商机培育**,千人千面推送内容,通过智能互动建立客户信任;辅助绘制**客户权力地图**,快速识别关键角色与立场。
+3. **方案设计**:基于客户真实需求,**秒级生成高度定制化解决方案**,结合RAG/Agent等技术实现方案/标书的自动生成与审查,精准匹配客户痛点。
+4. **谈判签约**:AI**数据驱动谈判策略制定**,智能分析谈判态势并提供最优策略;自动审查**合同风险**,标准化合同拟定与评审,降低法务风险。
+5. **交付实施**:**预测性交付与监控**,提前预警项目交付风险,实现资源动态优化与全流程可视化;AI调度物流/生产排程,保障交付效率。
+6. **回款复盘**:智能回款跟踪,**预测回款延迟与客户流失风险**;AI分析赢单/输单原因,复盘项目经验,反哺后续销售流程优化。
+7. **配套工具**:搭建**LTC教练平台**(基于华为铁三角理论),实现销售体系的AI诊断与评估;通过AI Agent完成客户痛点挖掘、价值定位、信任构建等专业工作,降低销售专业门槛。
+
+# 四、LTC各关键环节的实战方法论
+资料围绕LTC核心环节,给出了**可落地、可复制的实战工具与方法**,是B2B销售的核心实操指南,核心重点如下:
+## 1. 价值定位:直击客户价值靶心,跳出同质化陷阱
+B2B销售的核心痛点是**信息过载+注意力缺失**,且采购决策由6-10人共同参与,传统“功能/价格”价值主张已失效,需构建**多层次价值定位体系**:
+- 核心框架:**B2B价值金字塔**(源自贝恩30年研究,基于马斯洛需求层次),从基础要求→功能价值→便利价值→个人价值→理想价值,兼顾**组织客观需求、业务功能需求、个人情感需求**。
+- 客户真实需求:客户“嘴上谈成本/风险,心里重品质/省心”,价格未进入驱动忠诚度的前十,**专业知识、响应速度、集成能力**才是核心决策因素。
+- 落地方法:①用**JTBD(用户目标达成理论)** 洞察客户真实任务;②绘制**竞争格局**,找到市场空白;③用**3要素公式(相关性+可量化价值+独特性)** 定义核心价值主张;④针对采购委员会不同角色,**适配价值沟通语言**(如对CFO谈ROI,对IT总监谈安全/集成,对业务用户谈效率)。
+- 工具:**价值定位画布**(左侧价值地图:痛点缓释/收益创造;右侧客户视角:客户任务/痛点/收益)、**竞争定位矩阵**。
+
+## 2. 权力地图:决胜客户内部决策迷宫
+B2B交易失败的核心原因并非产品/价格,而是**未导航客户内部复杂的决策体系**,权力地图是破解这一问题的核心工具,落地四步法:
+1. **识别关键角色**:采购委员会的10大角色(决策核心层+执行评估团队+风险合规层+外部影响者),重点锁定**冠军/教练、决策者、技术评估者、最终使用者**四大核心角色,警惕“假冠军”(5大信号:信息模糊、拒绝引荐、只谈产品、缺乏行动、关键时刻消失)。
+2. **厘清权限立场**:用**权力/利益矩阵**分类角色,对**高权力高利益者重点管理(投入80%精力)**,高权力低利益者保持满意,低权力高利益者随时告知。
+3. **绘制可视化地图**:用节点/层级/关系线/颜色标记(绿支持/黄中立/红反对)呈现角色间的影响力流向,明确核心战场与突破口。
+4. **设计赢-结果沟通策略**:停止谈产品,转而谈**产品为客户带来的具体、可衡量的胜利**,针对不同角色用其“语言”沟通(如对CEO谈战略/市场份额,对生产总监谈效率/错误率)。
+
+## 3. 痛点挖掘:从销售到战略顾问的蜕变
+客户痛点分为**表面抱怨→潜在问题→根本痛点(含个人情感/职业痛点)**,需穿透表象挖掘核心,核心方法:
+- 痛点维度:企业客户五大痛点(财务/生产力/流程/支持/人才与文化)。
+- 提问技巧:用**SPIN逻辑放大痛点**,重点用**牵连问题**揭示小问题的大影响(业务→情绪→战略三层牵连);使用**高阶诊断问题清单**(障碍追问/失败复盘/隐藏成本等)实现痛点“穿刺”。
+- 深度洞察:听懂“说的”更要听懂“没说的”,捕捉关键词、观察非语言信号、拥抱沉默,将痛点与权力地图的关键角色挂钩,实现痛点的精准匹配。
+
+## 4. 信任构建:成交的终极核心
+AI时代信任的价值被放大,信任是**动态资产而非一劳永逸的存款**,核心落地要点:
+- 信任核心:降低**自我导向**(信任公式的超级杠杆),让客户感受到你的焦点是**其成功而非你的业绩**。
+- 危机转化:利用**服务补救悖论**,一次成功的补救能将愤怒客户变为忠实拥护者,落地**正义铁三角**(结果公平/互动公平/程序公平)。
+- 全流程融入:将信任构建融入线索获取到售后服务的全环节(如线索阶段提供行业白皮书建可信度,谈判阶段透明合同条款建可靠度)。
+- 团队赋能:打造高信任度销售铁军,从**文化(客户第一)、培训(信任方程式+顾问式销售)、考核(引入客户满意度/续约率KPI)** 三方面落地。
+
+## 5. 流程控制:打造可预测的增长引擎
+流程控制是LTC的收尾与保障,核心是**从“动作管理”到“结果管理”**,落地要点:
+- 流程六环节:线索生成→商机培育→方案设计→谈判签约→交付实施→回款复盘,明确各环节负责角色(市场/客户经理/解决方案经理/交付经理/财务)。
+- 通关标准:为每个阶段设置**客观、可验证的通关条件**(如商机培育通关需确认BANT/3个核心痛点/关键影响者认可),杜绝“感觉良好”的盲目推进。
+- 核心指标:追踪**阶段转化率、销售周期长度、管道速度**三大指标,其中**管道速度=(商机数×平均单价×赢率)/销售周期**是衡量营收机器的终极指标。
+- 实操行动:三步夺回销售控制权→审计现状(复盘停滞商机)→定义标准(设置问题阶段的通关条件)→开始追踪(聚焦核心指标每周监控)。
+
+# 五、核心结论
+1. B2B销售的本质不是卖产品,而是**卖信任、卖价值、卖解决方案**,成交是价值匹配、痛点解决、信任构建、流程管控的自然结果;
+2. LTC是B2B销售的**全流程管理体系**,而非单一环节的技巧,需实现端到端的标准化、智能化、团队化运作;
+3. AI是LTC的**核心赋能工具**,覆盖从线索筛选到回款复盘的全环节,实现“效率提升+决策优化+专业赋能”,让销售从“忙碌低效”变为“精准高效”;
+4. 传统“关系型销售”已失效,新时代B2B销售的核心是**成为客户的商业顾问**,用洞察重构客户认知,用价值解决客户痛点,用信任建立长期合作。
+

+ 15374 - 0
lead-discovery/package-lock.json

@@ -0,0 +1,15374 @@
+{
+  "name": "lead-discovery",
+  "version": "0.0.0",
+  "lockfileVersion": 3,
+  "requires": true,
+  "packages": {
+    "": {
+      "name": "lead-discovery",
+      "version": "0.0.0",
+      "dependencies": {
+        "@angular/animations": "^19.2.18",
+        "@angular/cdk": "^19.2.19",
+        "@angular/common": "^19.2.18",
+        "@angular/compiler": "^19.2.18",
+        "@angular/core": "^19.2.18",
+        "@angular/forms": "^19.2.18",
+        "@angular/material": "^19.2.19",
+        "@angular/platform-browser": "^19.2.18",
+        "@angular/platform-browser-dynamic": "^19.2.18",
+        "@angular/router": "^19.2.18",
+        "rxjs": "~7.8.0",
+        "tslib": "^2.3.0",
+        "zone.js": "~0.15.1"
+      },
+      "devDependencies": {
+        "@angular-devkit/build-angular": "^19.2.19",
+        "@angular/cli": "^19.2.19",
+        "@angular/compiler-cli": "^19.2.18",
+        "@types/jasmine": "~5.1.0",
+        "jasmine-core": "~5.2.0",
+        "karma": "~6.4.0",
+        "karma-chrome-launcher": "~3.2.0",
+        "karma-coverage": "~2.2.0",
+        "karma-jasmine": "~5.1.0",
+        "karma-jasmine-html-reporter": "~2.1.0",
+        "typescript": "~5.5.2"
+      }
+    },
+    "node_modules/@ampproject/remapping": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.3.0.tgz",
+      "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.24"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@angular-devkit/architect": {
+      "version": "0.1902.19",
+      "resolved": "https://registry.npmmirror.com/@angular-devkit/architect/-/architect-0.1902.19.tgz",
+      "integrity": "sha512-iexYDIYpGAeAU7T60bGcfrGwtq1bxpZixYxWuHYiaD1b5baQgNSfd1isGEOh37GgDNsf4In9i2LOLPm0wBdtgQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@angular-devkit/core": "19.2.19",
+        "rxjs": "7.8.1"
+      },
+      "engines": {
+        "node": "^18.19.1 || ^20.11.1 || >=22.0.0",
+        "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+        "yarn": ">= 1.13.0"
+      }
+    },
+    "node_modules/@angular-devkit/architect/node_modules/@angular-devkit/core": {
+      "version": "19.2.19",
+      "resolved": "https://registry.npmmirror.com/@angular-devkit/core/-/core-19.2.19.tgz",
+      "integrity": "sha512-JbLL+4IMLMBgjLZlnPG4lYDfz4zGrJ/s6Aoon321NJKuw1Kb1k5KpFu9dUY0BqLIe8xPQ2UJBpI+xXdK5MXMHQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ajv": "8.17.1",
+        "ajv-formats": "3.0.1",
+        "jsonc-parser": "3.3.1",
+        "picomatch": "4.0.2",
+        "rxjs": "7.8.1",
+        "source-map": "0.7.4"
+      },
+      "engines": {
+        "node": "^18.19.1 || ^20.11.1 || >=22.0.0",
+        "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+        "yarn": ">= 1.13.0"
+      },
+      "peerDependencies": {
+        "chokidar": "^4.0.0"
+      },
+      "peerDependenciesMeta": {
+        "chokidar": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@angular-devkit/architect/node_modules/chokidar": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-4.0.3.tgz",
+      "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "readdirp": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 14.16.0"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/@angular-devkit/architect/node_modules/readdirp": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-4.1.2.tgz",
+      "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "peer": true,
+      "engines": {
+        "node": ">= 14.18.0"
+      },
+      "funding": {
+        "type": "individual",
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/@angular-devkit/architect/node_modules/rxjs": {
+      "version": "7.8.1",
+      "resolved": "https://registry.npmmirror.com/rxjs/-/rxjs-7.8.1.tgz",
+      "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "tslib": "^2.1.0"
+      }
+    },
+    "node_modules/@angular-devkit/build-angular": {
+      "version": "19.2.19",
+      "resolved": "https://registry.npmmirror.com/@angular-devkit/build-angular/-/build-angular-19.2.19.tgz",
+      "integrity": "sha512-uIxi6Vzss6+ycljVhkyPUPWa20w8qxJL9lEn0h6+sX/fhM8Djt0FHIuTQjoX58EoMaQ/1jrXaRaGimkbaFcG9A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@ampproject/remapping": "2.3.0",
+        "@angular-devkit/architect": "0.1902.19",
+        "@angular-devkit/build-webpack": "0.1902.19",
+        "@angular-devkit/core": "19.2.19",
+        "@angular/build": "19.2.19",
+        "@babel/core": "7.26.10",
+        "@babel/generator": "7.26.10",
+        "@babel/helper-annotate-as-pure": "7.25.9",
+        "@babel/helper-split-export-declaration": "7.24.7",
+        "@babel/plugin-transform-async-generator-functions": "7.26.8",
+        "@babel/plugin-transform-async-to-generator": "7.25.9",
+        "@babel/plugin-transform-runtime": "7.26.10",
+        "@babel/preset-env": "7.26.9",
+        "@babel/runtime": "7.26.10",
+        "@discoveryjs/json-ext": "0.6.3",
+        "@ngtools/webpack": "19.2.19",
+        "@vitejs/plugin-basic-ssl": "1.2.0",
+        "ansi-colors": "4.1.3",
+        "autoprefixer": "10.4.20",
+        "babel-loader": "9.2.1",
+        "browserslist": "^4.21.5",
+        "copy-webpack-plugin": "12.0.2",
+        "css-loader": "7.1.2",
+        "esbuild-wasm": "0.25.4",
+        "fast-glob": "3.3.3",
+        "http-proxy-middleware": "3.0.5",
+        "istanbul-lib-instrument": "6.0.3",
+        "jsonc-parser": "3.3.1",
+        "karma-source-map-support": "1.4.0",
+        "less": "4.2.2",
+        "less-loader": "12.2.0",
+        "license-webpack-plugin": "4.0.2",
+        "loader-utils": "3.3.1",
+        "mini-css-extract-plugin": "2.9.2",
+        "open": "10.1.0",
+        "ora": "5.4.1",
+        "picomatch": "4.0.2",
+        "piscina": "4.8.0",
+        "postcss": "8.5.2",
+        "postcss-loader": "8.1.1",
+        "resolve-url-loader": "5.0.0",
+        "rxjs": "7.8.1",
+        "sass": "1.85.0",
+        "sass-loader": "16.0.5",
+        "semver": "7.7.1",
+        "source-map-loader": "5.0.0",
+        "source-map-support": "0.5.21",
+        "terser": "5.39.0",
+        "tree-kill": "1.2.2",
+        "tslib": "2.8.1",
+        "webpack": "5.98.0",
+        "webpack-dev-middleware": "7.4.2",
+        "webpack-dev-server": "5.2.2",
+        "webpack-merge": "6.0.1",
+        "webpack-subresource-integrity": "5.1.0"
+      },
+      "engines": {
+        "node": "^18.19.1 || ^20.11.1 || >=22.0.0",
+        "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+        "yarn": ">= 1.13.0"
+      },
+      "optionalDependencies": {
+        "esbuild": "0.25.4"
+      },
+      "peerDependencies": {
+        "@angular/compiler-cli": "^19.0.0 || ^19.2.0-next.0",
+        "@angular/localize": "^19.0.0 || ^19.2.0-next.0",
+        "@angular/platform-server": "^19.0.0 || ^19.2.0-next.0",
+        "@angular/service-worker": "^19.0.0 || ^19.2.0-next.0",
+        "@angular/ssr": "^19.2.19",
+        "@web/test-runner": "^0.20.0",
+        "browser-sync": "^3.0.2",
+        "jest": "^29.5.0",
+        "jest-environment-jsdom": "^29.5.0",
+        "karma": "^6.3.0",
+        "ng-packagr": "^19.0.0 || ^19.2.0-next.0",
+        "protractor": "^7.0.0",
+        "tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0",
+        "typescript": ">=5.5 <5.9"
+      },
+      "peerDependenciesMeta": {
+        "@angular/localize": {
+          "optional": true
+        },
+        "@angular/platform-server": {
+          "optional": true
+        },
+        "@angular/service-worker": {
+          "optional": true
+        },
+        "@angular/ssr": {
+          "optional": true
+        },
+        "@web/test-runner": {
+          "optional": true
+        },
+        "browser-sync": {
+          "optional": true
+        },
+        "jest": {
+          "optional": true
+        },
+        "jest-environment-jsdom": {
+          "optional": true
+        },
+        "karma": {
+          "optional": true
+        },
+        "ng-packagr": {
+          "optional": true
+        },
+        "protractor": {
+          "optional": true
+        },
+        "tailwindcss": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/core": {
+      "version": "19.2.19",
+      "resolved": "https://registry.npmmirror.com/@angular-devkit/core/-/core-19.2.19.tgz",
+      "integrity": "sha512-JbLL+4IMLMBgjLZlnPG4lYDfz4zGrJ/s6Aoon321NJKuw1Kb1k5KpFu9dUY0BqLIe8xPQ2UJBpI+xXdK5MXMHQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ajv": "8.17.1",
+        "ajv-formats": "3.0.1",
+        "jsonc-parser": "3.3.1",
+        "picomatch": "4.0.2",
+        "rxjs": "7.8.1",
+        "source-map": "0.7.4"
+      },
+      "engines": {
+        "node": "^18.19.1 || ^20.11.1 || >=22.0.0",
+        "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+        "yarn": ">= 1.13.0"
+      },
+      "peerDependencies": {
+        "chokidar": "^4.0.0"
+      },
+      "peerDependenciesMeta": {
+        "chokidar": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@angular-devkit/build-angular/node_modules/chokidar": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-4.0.3.tgz",
+      "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "readdirp": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 14.16.0"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/@angular-devkit/build-angular/node_modules/postcss": {
+      "version": "8.5.2",
+      "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.2.tgz",
+      "integrity": "sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/postcss"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "nanoid": "^3.3.8",
+        "picocolors": "^1.1.1",
+        "source-map-js": "^1.2.1"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      }
+    },
+    "node_modules/@angular-devkit/build-angular/node_modules/readdirp": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-4.1.2.tgz",
+      "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "peer": true,
+      "engines": {
+        "node": ">= 14.18.0"
+      },
+      "funding": {
+        "type": "individual",
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/@angular-devkit/build-angular/node_modules/rxjs": {
+      "version": "7.8.1",
+      "resolved": "https://registry.npmmirror.com/rxjs/-/rxjs-7.8.1.tgz",
+      "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "tslib": "^2.1.0"
+      }
+    },
+    "node_modules/@angular-devkit/build-webpack": {
+      "version": "0.1902.19",
+      "resolved": "https://registry.npmmirror.com/@angular-devkit/build-webpack/-/build-webpack-0.1902.19.tgz",
+      "integrity": "sha512-x2tlGg5CsUveFzuRuqeHknSbGirSAoRynEh+KqPRGK0G3WpMViW/M8SuVurecasegfIrDWtYZ4FnVxKqNbKwXQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@angular-devkit/architect": "0.1902.19",
+        "rxjs": "7.8.1"
+      },
+      "engines": {
+        "node": "^18.19.1 || ^20.11.1 || >=22.0.0",
+        "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+        "yarn": ">= 1.13.0"
+      },
+      "peerDependencies": {
+        "webpack": "^5.30.0",
+        "webpack-dev-server": "^5.0.2"
+      }
+    },
+    "node_modules/@angular-devkit/build-webpack/node_modules/rxjs": {
+      "version": "7.8.1",
+      "resolved": "https://registry.npmmirror.com/rxjs/-/rxjs-7.8.1.tgz",
+      "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "tslib": "^2.1.0"
+      }
+    },
+    "node_modules/@angular-devkit/schematics": {
+      "version": "19.2.19",
+      "resolved": "https://registry.npmmirror.com/@angular-devkit/schematics/-/schematics-19.2.19.tgz",
+      "integrity": "sha512-J4Jarr0SohdrHcb40gTL4wGPCQ952IMWF1G/MSAQfBAPvA9ZKApYhpxcY7PmehVePve+ujpus1dGsJ7dPxz8Kg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@angular-devkit/core": "19.2.19",
+        "jsonc-parser": "3.3.1",
+        "magic-string": "0.30.17",
+        "ora": "5.4.1",
+        "rxjs": "7.8.1"
+      },
+      "engines": {
+        "node": "^18.19.1 || ^20.11.1 || >=22.0.0",
+        "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+        "yarn": ">= 1.13.0"
+      }
+    },
+    "node_modules/@angular-devkit/schematics/node_modules/@angular-devkit/core": {
+      "version": "19.2.19",
+      "resolved": "https://registry.npmmirror.com/@angular-devkit/core/-/core-19.2.19.tgz",
+      "integrity": "sha512-JbLL+4IMLMBgjLZlnPG4lYDfz4zGrJ/s6Aoon321NJKuw1Kb1k5KpFu9dUY0BqLIe8xPQ2UJBpI+xXdK5MXMHQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ajv": "8.17.1",
+        "ajv-formats": "3.0.1",
+        "jsonc-parser": "3.3.1",
+        "picomatch": "4.0.2",
+        "rxjs": "7.8.1",
+        "source-map": "0.7.4"
+      },
+      "engines": {
+        "node": "^18.19.1 || ^20.11.1 || >=22.0.0",
+        "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+        "yarn": ">= 1.13.0"
+      },
+      "peerDependencies": {
+        "chokidar": "^4.0.0"
+      },
+      "peerDependenciesMeta": {
+        "chokidar": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@angular-devkit/schematics/node_modules/chokidar": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-4.0.3.tgz",
+      "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "readdirp": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 14.16.0"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/@angular-devkit/schematics/node_modules/readdirp": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-4.1.2.tgz",
+      "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "peer": true,
+      "engines": {
+        "node": ">= 14.18.0"
+      },
+      "funding": {
+        "type": "individual",
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/@angular-devkit/schematics/node_modules/rxjs": {
+      "version": "7.8.1",
+      "resolved": "https://registry.npmmirror.com/rxjs/-/rxjs-7.8.1.tgz",
+      "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "tslib": "^2.1.0"
+      }
+    },
+    "node_modules/@angular/animations": {
+      "version": "19.2.18",
+      "resolved": "https://registry.npmmirror.com/@angular/animations/-/animations-19.2.18.tgz",
+      "integrity": "sha512-c76x1t+OiSstPsvJdHmV8Q4taF+8SxWKqiY750fOjpd01it4jJbU6YQqIroC6Xie7154zZIxOTHH2uTj+nm5qA==",
+      "license": "MIT",
+      "dependencies": {
+        "tslib": "^2.3.0"
+      },
+      "engines": {
+        "node": "^18.19.1 || ^20.11.1 || >=22.0.0"
+      },
+      "peerDependencies": {
+        "@angular/common": "19.2.18",
+        "@angular/core": "19.2.18"
+      }
+    },
+    "node_modules/@angular/build": {
+      "version": "19.2.19",
+      "resolved": "https://registry.npmmirror.com/@angular/build/-/build-19.2.19.tgz",
+      "integrity": "sha512-SFzQ1bRkNFiOVu+aaz+9INmts7tDUrsHLEr9HmARXr9qk5UmR8prlw39p2u+Bvi6/lCiJ18TZMQQl9mGyr63lg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@ampproject/remapping": "2.3.0",
+        "@angular-devkit/architect": "0.1902.19",
+        "@babel/core": "7.26.10",
+        "@babel/helper-annotate-as-pure": "7.25.9",
+        "@babel/helper-split-export-declaration": "7.24.7",
+        "@babel/plugin-syntax-import-attributes": "7.26.0",
+        "@inquirer/confirm": "5.1.6",
+        "@vitejs/plugin-basic-ssl": "1.2.0",
+        "beasties": "0.3.2",
+        "browserslist": "^4.23.0",
+        "esbuild": "0.25.4",
+        "fast-glob": "3.3.3",
+        "https-proxy-agent": "7.0.6",
+        "istanbul-lib-instrument": "6.0.3",
+        "listr2": "8.2.5",
+        "magic-string": "0.30.17",
+        "mrmime": "2.0.1",
+        "parse5-html-rewriting-stream": "7.0.0",
+        "picomatch": "4.0.2",
+        "piscina": "4.8.0",
+        "rollup": "4.34.8",
+        "sass": "1.85.0",
+        "semver": "7.7.1",
+        "source-map-support": "0.5.21",
+        "vite": "6.4.1",
+        "watchpack": "2.4.2"
+      },
+      "engines": {
+        "node": "^18.19.1 || ^20.11.1 || >=22.0.0",
+        "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+        "yarn": ">= 1.13.0"
+      },
+      "optionalDependencies": {
+        "lmdb": "3.2.6"
+      },
+      "peerDependencies": {
+        "@angular/compiler": "^19.0.0 || ^19.2.0-next.0",
+        "@angular/compiler-cli": "^19.0.0 || ^19.2.0-next.0",
+        "@angular/localize": "^19.0.0 || ^19.2.0-next.0",
+        "@angular/platform-server": "^19.0.0 || ^19.2.0-next.0",
+        "@angular/service-worker": "^19.0.0 || ^19.2.0-next.0",
+        "@angular/ssr": "^19.2.19",
+        "karma": "^6.4.0",
+        "less": "^4.2.0",
+        "ng-packagr": "^19.0.0 || ^19.2.0-next.0",
+        "postcss": "^8.4.0",
+        "tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0",
+        "typescript": ">=5.5 <5.9"
+      },
+      "peerDependenciesMeta": {
+        "@angular/localize": {
+          "optional": true
+        },
+        "@angular/platform-server": {
+          "optional": true
+        },
+        "@angular/service-worker": {
+          "optional": true
+        },
+        "@angular/ssr": {
+          "optional": true
+        },
+        "karma": {
+          "optional": true
+        },
+        "less": {
+          "optional": true
+        },
+        "ng-packagr": {
+          "optional": true
+        },
+        "postcss": {
+          "optional": true
+        },
+        "tailwindcss": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@angular/cdk": {
+      "version": "19.2.19",
+      "resolved": "https://registry.npmmirror.com/@angular/cdk/-/cdk-19.2.19.tgz",
+      "integrity": "sha512-PCpJagurPBqciqcq4Z8+3OtKLb7rSl4w/qBJoIMua8CgnrjvA1i+SWawhdtfI1zlY8FSwhzLwXV0CmWWfFzQPg==",
+      "license": "MIT",
+      "dependencies": {
+        "parse5": "^7.1.2",
+        "tslib": "^2.3.0"
+      },
+      "peerDependencies": {
+        "@angular/common": "^19.0.0 || ^20.0.0",
+        "@angular/core": "^19.0.0 || ^20.0.0",
+        "rxjs": "^6.5.3 || ^7.4.0"
+      }
+    },
+    "node_modules/@angular/cli": {
+      "version": "19.2.19",
+      "resolved": "https://registry.npmmirror.com/@angular/cli/-/cli-19.2.19.tgz",
+      "integrity": "sha512-e9tAzFNOL4mMWfMnpC9Up83OCTOp2siIj8W41FCp8jfoEnw79AXDDLh3d70kOayiObchksTJVShslTogLUyhMw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@angular-devkit/architect": "0.1902.19",
+        "@angular-devkit/core": "19.2.19",
+        "@angular-devkit/schematics": "19.2.19",
+        "@inquirer/prompts": "7.3.2",
+        "@listr2/prompt-adapter-inquirer": "2.0.18",
+        "@schematics/angular": "19.2.19",
+        "@yarnpkg/lockfile": "1.1.0",
+        "ini": "5.0.0",
+        "jsonc-parser": "3.3.1",
+        "listr2": "8.2.5",
+        "npm-package-arg": "12.0.2",
+        "npm-pick-manifest": "10.0.0",
+        "pacote": "20.0.0",
+        "resolve": "1.22.10",
+        "semver": "7.7.1",
+        "symbol-observable": "4.0.0",
+        "yargs": "17.7.2"
+      },
+      "bin": {
+        "ng": "bin/ng.js"
+      },
+      "engines": {
+        "node": "^18.19.1 || ^20.11.1 || >=22.0.0",
+        "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+        "yarn": ">= 1.13.0"
+      }
+    },
+    "node_modules/@angular/cli/node_modules/@angular-devkit/core": {
+      "version": "19.2.19",
+      "resolved": "https://registry.npmmirror.com/@angular-devkit/core/-/core-19.2.19.tgz",
+      "integrity": "sha512-JbLL+4IMLMBgjLZlnPG4lYDfz4zGrJ/s6Aoon321NJKuw1Kb1k5KpFu9dUY0BqLIe8xPQ2UJBpI+xXdK5MXMHQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ajv": "8.17.1",
+        "ajv-formats": "3.0.1",
+        "jsonc-parser": "3.3.1",
+        "picomatch": "4.0.2",
+        "rxjs": "7.8.1",
+        "source-map": "0.7.4"
+      },
+      "engines": {
+        "node": "^18.19.1 || ^20.11.1 || >=22.0.0",
+        "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+        "yarn": ">= 1.13.0"
+      },
+      "peerDependencies": {
+        "chokidar": "^4.0.0"
+      },
+      "peerDependenciesMeta": {
+        "chokidar": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@angular/cli/node_modules/chokidar": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-4.0.3.tgz",
+      "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "readdirp": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 14.16.0"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/@angular/cli/node_modules/readdirp": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-4.1.2.tgz",
+      "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "peer": true,
+      "engines": {
+        "node": ">= 14.18.0"
+      },
+      "funding": {
+        "type": "individual",
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/@angular/cli/node_modules/rxjs": {
+      "version": "7.8.1",
+      "resolved": "https://registry.npmmirror.com/rxjs/-/rxjs-7.8.1.tgz",
+      "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "tslib": "^2.1.0"
+      }
+    },
+    "node_modules/@angular/common": {
+      "version": "19.2.18",
+      "resolved": "https://registry.npmmirror.com/@angular/common/-/common-19.2.18.tgz",
+      "integrity": "sha512-CrV02Omzw/QtfjlEVXVPJVXipdx83NuA+qSASZYrxrhKFusUZyK3P/Zznqg+wiAeNDbedQwMUVqoAARHf0xQrw==",
+      "license": "MIT",
+      "dependencies": {
+        "tslib": "^2.3.0"
+      },
+      "engines": {
+        "node": "^18.19.1 || ^20.11.1 || >=22.0.0"
+      },
+      "peerDependencies": {
+        "@angular/core": "19.2.18",
+        "rxjs": "^6.5.3 || ^7.4.0"
+      }
+    },
+    "node_modules/@angular/compiler": {
+      "version": "19.2.18",
+      "resolved": "https://registry.npmmirror.com/@angular/compiler/-/compiler-19.2.18.tgz",
+      "integrity": "sha512-3MscvODxRVxc3Cs0ZlHI5Pk5rEvE80otfvxZTMksOZuPlv1B+S8MjWfc3X3jk9SbyUEzODBEH55iCaBHD48V3g==",
+      "license": "MIT",
+      "dependencies": {
+        "tslib": "^2.3.0"
+      },
+      "engines": {
+        "node": "^18.19.1 || ^20.11.1 || >=22.0.0"
+      }
+    },
+    "node_modules/@angular/compiler-cli": {
+      "version": "19.2.18",
+      "resolved": "https://registry.npmmirror.com/@angular/compiler-cli/-/compiler-cli-19.2.18.tgz",
+      "integrity": "sha512-N4TMtLfImJIoMaRL6mx7885UBeQidywptHH6ACZj71Ar6++DBc1mMlcwuvbeJCd3r3y8MQ5nLv5PZSN/tHr13w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/core": "7.26.9",
+        "@jridgewell/sourcemap-codec": "^1.4.14",
+        "chokidar": "^4.0.0",
+        "convert-source-map": "^1.5.1",
+        "reflect-metadata": "^0.2.0",
+        "semver": "^7.0.0",
+        "tslib": "^2.3.0",
+        "yargs": "^17.2.1"
+      },
+      "bin": {
+        "ng-xi18n": "bundles/src/bin/ng_xi18n.js",
+        "ngc": "bundles/src/bin/ngc.js",
+        "ngcc": "bundles/ngcc/index.js"
+      },
+      "engines": {
+        "node": "^18.19.1 || ^20.11.1 || >=22.0.0"
+      },
+      "peerDependencies": {
+        "@angular/compiler": "19.2.18",
+        "typescript": ">=5.5 <5.9"
+      }
+    },
+    "node_modules/@angular/compiler-cli/node_modules/@babel/core": {
+      "version": "7.26.9",
+      "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.26.9.tgz",
+      "integrity": "sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@ampproject/remapping": "^2.2.0",
+        "@babel/code-frame": "^7.26.2",
+        "@babel/generator": "^7.26.9",
+        "@babel/helper-compilation-targets": "^7.26.5",
+        "@babel/helper-module-transforms": "^7.26.0",
+        "@babel/helpers": "^7.26.9",
+        "@babel/parser": "^7.26.9",
+        "@babel/template": "^7.26.9",
+        "@babel/traverse": "^7.26.9",
+        "@babel/types": "^7.26.9",
+        "convert-source-map": "^2.0.0",
+        "debug": "^4.1.0",
+        "gensync": "^1.0.0-beta.2",
+        "json5": "^2.2.3",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/babel"
+      }
+    },
+    "node_modules/@angular/compiler-cli/node_modules/@babel/core/node_modules/convert-source-map": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz",
+      "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@angular/compiler-cli/node_modules/@babel/core/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/@angular/compiler-cli/node_modules/chokidar": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-4.0.3.tgz",
+      "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "readdirp": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 14.16.0"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/@angular/compiler-cli/node_modules/readdirp": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-4.1.2.tgz",
+      "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 14.18.0"
+      },
+      "funding": {
+        "type": "individual",
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/@angular/core": {
+      "version": "19.2.18",
+      "resolved": "https://registry.npmmirror.com/@angular/core/-/core-19.2.18.tgz",
+      "integrity": "sha512-+QRrf0Igt8ccUWXHA+7doK5W6ODyhHdqVyblSlcQ8OciwkzIIGGEYNZom5OZyWMh+oI54lcSeyV2O3xaDepSrQ==",
+      "license": "MIT",
+      "dependencies": {
+        "tslib": "^2.3.0"
+      },
+      "engines": {
+        "node": "^18.19.1 || ^20.11.1 || >=22.0.0"
+      },
+      "peerDependencies": {
+        "rxjs": "^6.5.3 || ^7.4.0",
+        "zone.js": "~0.15.0"
+      }
+    },
+    "node_modules/@angular/forms": {
+      "version": "19.2.18",
+      "resolved": "https://registry.npmmirror.com/@angular/forms/-/forms-19.2.18.tgz",
+      "integrity": "sha512-pe40934jWhoS7DyGl7jyZdoj1gvBgur2t1zrJD+csEkTitYnW14+La2Pv6SW1pNX5nIzFsgsS9Nex1KcH5S6Tw==",
+      "license": "MIT",
+      "dependencies": {
+        "tslib": "^2.3.0"
+      },
+      "engines": {
+        "node": "^18.19.1 || ^20.11.1 || >=22.0.0"
+      },
+      "peerDependencies": {
+        "@angular/common": "19.2.18",
+        "@angular/core": "19.2.18",
+        "@angular/platform-browser": "19.2.18",
+        "rxjs": "^6.5.3 || ^7.4.0"
+      }
+    },
+    "node_modules/@angular/material": {
+      "version": "19.2.19",
+      "resolved": "https://registry.npmmirror.com/@angular/material/-/material-19.2.19.tgz",
+      "integrity": "sha512-auIE6JUzTIA3LyYklh9J/T7u64crmphxUBgAa0zcOMDog6SYfwbNe9YeLQqua5ek4OUAOdK/BHHfVl5W5iaUoQ==",
+      "license": "MIT",
+      "dependencies": {
+        "tslib": "^2.3.0"
+      },
+      "peerDependencies": {
+        "@angular/cdk": "19.2.19",
+        "@angular/common": "^19.0.0 || ^20.0.0",
+        "@angular/core": "^19.0.0 || ^20.0.0",
+        "@angular/forms": "^19.0.0 || ^20.0.0",
+        "@angular/platform-browser": "^19.0.0 || ^20.0.0",
+        "rxjs": "^6.5.3 || ^7.4.0"
+      }
+    },
+    "node_modules/@angular/platform-browser": {
+      "version": "19.2.18",
+      "resolved": "https://registry.npmmirror.com/@angular/platform-browser/-/platform-browser-19.2.18.tgz",
+      "integrity": "sha512-eahtsHPyXTYLARs9YOlXhnXGgzw0wcyOcDkBvNWK/3lA0NHIgIHmQgXAmBo+cJ+g9skiEQTD2OmSrrwbFKWJkw==",
+      "license": "MIT",
+      "dependencies": {
+        "tslib": "^2.3.0"
+      },
+      "engines": {
+        "node": "^18.19.1 || ^20.11.1 || >=22.0.0"
+      },
+      "peerDependencies": {
+        "@angular/animations": "19.2.18",
+        "@angular/common": "19.2.18",
+        "@angular/core": "19.2.18"
+      },
+      "peerDependenciesMeta": {
+        "@angular/animations": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@angular/platform-browser-dynamic": {
+      "version": "19.2.18",
+      "resolved": "https://registry.npmmirror.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-19.2.18.tgz",
+      "integrity": "sha512-wqDtK2yVN5VDqVeOSOfqELdu40fyoIDknBGSxA27CEXzFVdMWJyIpuvUi+GMa+9eGjlS+1uVVBaRwxmnuvHj+A==",
+      "license": "MIT",
+      "dependencies": {
+        "tslib": "^2.3.0"
+      },
+      "engines": {
+        "node": "^18.19.1 || ^20.11.1 || >=22.0.0"
+      },
+      "peerDependencies": {
+        "@angular/common": "19.2.18",
+        "@angular/compiler": "19.2.18",
+        "@angular/core": "19.2.18",
+        "@angular/platform-browser": "19.2.18"
+      }
+    },
+    "node_modules/@angular/router": {
+      "version": "19.2.18",
+      "resolved": "https://registry.npmmirror.com/@angular/router/-/router-19.2.18.tgz",
+      "integrity": "sha512-7cimxtPODSwokFQ0TRYzX0ad8Yjrl0MJfzaDCJejd1n/q7RZ7KZmHd0DS/LkDNXVMEh4swr00fK+3YWG/Szsrg==",
+      "license": "MIT",
+      "dependencies": {
+        "tslib": "^2.3.0"
+      },
+      "engines": {
+        "node": "^18.19.1 || ^20.11.1 || >=22.0.0"
+      },
+      "peerDependencies": {
+        "@angular/common": "19.2.18",
+        "@angular/core": "19.2.18",
+        "@angular/platform-browser": "19.2.18",
+        "rxjs": "^6.5.3 || ^7.4.0"
+      }
+    },
+    "node_modules/@babel/code-frame": {
+      "version": "7.29.0",
+      "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.29.0.tgz",
+      "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-validator-identifier": "^7.28.5",
+        "js-tokens": "^4.0.0",
+        "picocolors": "^1.1.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/compat-data": {
+      "version": "7.29.0",
+      "resolved": "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.29.0.tgz",
+      "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/core": {
+      "version": "7.26.10",
+      "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.26.10.tgz",
+      "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@ampproject/remapping": "^2.2.0",
+        "@babel/code-frame": "^7.26.2",
+        "@babel/generator": "^7.26.10",
+        "@babel/helper-compilation-targets": "^7.26.5",
+        "@babel/helper-module-transforms": "^7.26.0",
+        "@babel/helpers": "^7.26.10",
+        "@babel/parser": "^7.26.10",
+        "@babel/template": "^7.26.9",
+        "@babel/traverse": "^7.26.10",
+        "@babel/types": "^7.26.10",
+        "convert-source-map": "^2.0.0",
+        "debug": "^4.1.0",
+        "gensync": "^1.0.0-beta.2",
+        "json5": "^2.2.3",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/babel"
+      }
+    },
+    "node_modules/@babel/core/node_modules/convert-source-map": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz",
+      "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@babel/core/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/@babel/generator": {
+      "version": "7.26.10",
+      "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.26.10.tgz",
+      "integrity": "sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/parser": "^7.26.10",
+        "@babel/types": "^7.26.10",
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.25",
+        "jsesc": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-annotate-as-pure": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz",
+      "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-compilation-targets": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz",
+      "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/compat-data": "^7.28.6",
+        "@babel/helper-validator-option": "^7.27.1",
+        "browserslist": "^4.24.0",
+        "lru-cache": "^5.1.1",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/@babel/helper-create-class-features-plugin": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz",
+      "integrity": "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-annotate-as-pure": "^7.27.3",
+        "@babel/helper-member-expression-to-functions": "^7.28.5",
+        "@babel/helper-optimise-call-expression": "^7.27.1",
+        "@babel/helper-replace-supers": "^7.28.6",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
+        "@babel/traverse": "^7.28.6",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/helper-annotate-as-pure": {
+      "version": "7.27.3",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz",
+      "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.27.3"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/@babel/helper-create-regexp-features-plugin": {
+      "version": "7.28.5",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz",
+      "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-annotate-as-pure": "^7.27.3",
+        "regexpu-core": "^6.3.1",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/@babel/helper-annotate-as-pure": {
+      "version": "7.27.3",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz",
+      "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.27.3"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/@babel/helper-define-polyfill-provider": {
+      "version": "0.6.6",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.6.tgz",
+      "integrity": "sha512-mOAsxeeKkUKayvZR3HeTYD/fICpCPLJrU5ZjelT/PA6WHtNDBOE436YiaEUvHN454bRM3CebhDsIpieCc4texA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-compilation-targets": "^7.28.6",
+        "@babel/helper-plugin-utils": "^7.28.6",
+        "debug": "^4.4.3",
+        "lodash.debounce": "^4.0.8",
+        "resolve": "^1.22.11"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+      }
+    },
+    "node_modules/@babel/helper-define-polyfill-provider/node_modules/resolve": {
+      "version": "1.22.11",
+      "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.11.tgz",
+      "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-core-module": "^2.16.1",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
+      },
+      "bin": {
+        "resolve": "bin/resolve"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/@babel/helper-globals": {
+      "version": "7.28.0",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
+      "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-member-expression-to-functions": {
+      "version": "7.28.5",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz",
+      "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/traverse": "^7.28.5",
+        "@babel/types": "^7.28.5"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-module-imports": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz",
+      "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/traverse": "^7.28.6",
+        "@babel/types": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-module-transforms": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz",
+      "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-module-imports": "^7.28.6",
+        "@babel/helper-validator-identifier": "^7.28.5",
+        "@babel/traverse": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/helper-optimise-call-expression": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz",
+      "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-plugin-utils": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz",
+      "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-remap-async-to-generator": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz",
+      "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-annotate-as-pure": "^7.27.1",
+        "@babel/helper-wrap-function": "^7.27.1",
+        "@babel/traverse": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/helper-remap-async-to-generator/node_modules/@babel/helper-annotate-as-pure": {
+      "version": "7.27.3",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz",
+      "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.27.3"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-replace-supers": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz",
+      "integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-member-expression-to-functions": "^7.28.5",
+        "@babel/helper-optimise-call-expression": "^7.27.1",
+        "@babel/traverse": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz",
+      "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/traverse": "^7.27.1",
+        "@babel/types": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-split-export-declaration": {
+      "version": "7.24.7",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz",
+      "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.24.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-string-parser": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+      "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-validator-identifier": {
+      "version": "7.28.5",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
+      "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-validator-option": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
+      "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-wrap-function": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-wrap-function/-/helper-wrap-function-7.28.6.tgz",
+      "integrity": "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/template": "^7.28.6",
+        "@babel/traverse": "^7.28.6",
+        "@babel/types": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helpers": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.28.6.tgz",
+      "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/template": "^7.28.6",
+        "@babel/types": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/parser": {
+      "version": "7.29.0",
+      "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.29.0.tgz",
+      "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.29.0"
+      },
+      "bin": {
+        "parser": "bin/babel-parser.js"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": {
+      "version": "7.28.5",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz",
+      "integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1",
+        "@babel/traverse": "^7.28.5"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz",
+      "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz",
+      "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz",
+      "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
+        "@babel/plugin-transform-optional-chaining": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.13.0"
+      }
+    },
+    "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.6.tgz",
+      "integrity": "sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.28.6",
+        "@babel/traverse": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-proposal-private-property-in-object": {
+      "version": "7.21.0-placeholder-for-preset-env.2",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
+      "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-syntax-import-assertions": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.28.6.tgz",
+      "integrity": "sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-syntax-import-attributes": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz",
+      "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-syntax-unicode-sets-regex": {
+      "version": "7.18.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz",
+      "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.18.6",
+        "@babel/helper-plugin-utils": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-arrow-functions": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz",
+      "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-async-generator-functions": {
+      "version": "7.26.8",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.26.8.tgz",
+      "integrity": "sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.26.5",
+        "@babel/helper-remap-async-to-generator": "^7.25.9",
+        "@babel/traverse": "^7.26.8"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-async-to-generator": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz",
+      "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-module-imports": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/helper-remap-async-to-generator": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-block-scoped-functions": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz",
+      "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-block-scoping": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.6.tgz",
+      "integrity": "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-class-properties": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.28.6.tgz",
+      "integrity": "sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-create-class-features-plugin": "^7.28.6",
+        "@babel/helper-plugin-utils": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-class-static-block": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.6.tgz",
+      "integrity": "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-create-class-features-plugin": "^7.28.6",
+        "@babel/helper-plugin-utils": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.12.0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-classes": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.6.tgz",
+      "integrity": "sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-annotate-as-pure": "^7.27.3",
+        "@babel/helper-compilation-targets": "^7.28.6",
+        "@babel/helper-globals": "^7.28.0",
+        "@babel/helper-plugin-utils": "^7.28.6",
+        "@babel/helper-replace-supers": "^7.28.6",
+        "@babel/traverse": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-annotate-as-pure": {
+      "version": "7.27.3",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz",
+      "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.27.3"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-computed-properties": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.28.6.tgz",
+      "integrity": "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.28.6",
+        "@babel/template": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-destructuring": {
+      "version": "7.28.5",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz",
+      "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1",
+        "@babel/traverse": "^7.28.5"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-dotall-regex": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.28.6.tgz",
+      "integrity": "sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.28.5",
+        "@babel/helper-plugin-utils": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-duplicate-keys": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz",
+      "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": {
+      "version": "7.29.0",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.29.0.tgz",
+      "integrity": "sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.28.5",
+        "@babel/helper-plugin-utils": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-dynamic-import": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz",
+      "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-exponentiation-operator": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.6.tgz",
+      "integrity": "sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-export-namespace-from": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz",
+      "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-for-of": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz",
+      "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-function-name": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz",
+      "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-compilation-targets": "^7.27.1",
+        "@babel/helper-plugin-utils": "^7.27.1",
+        "@babel/traverse": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-json-strings": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.28.6.tgz",
+      "integrity": "sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-literals": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz",
+      "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-logical-assignment-operators": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.6.tgz",
+      "integrity": "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-member-expression-literals": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz",
+      "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-modules-amd": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz",
+      "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-module-transforms": "^7.27.1",
+        "@babel/helper-plugin-utils": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-modules-commonjs": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.28.6.tgz",
+      "integrity": "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-module-transforms": "^7.28.6",
+        "@babel/helper-plugin-utils": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-modules-systemjs": {
+      "version": "7.29.0",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.0.tgz",
+      "integrity": "sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-module-transforms": "^7.28.6",
+        "@babel/helper-plugin-utils": "^7.28.6",
+        "@babel/helper-validator-identifier": "^7.28.5",
+        "@babel/traverse": "^7.29.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-modules-umd": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz",
+      "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-module-transforms": "^7.27.1",
+        "@babel/helper-plugin-utils": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
+      "version": "7.29.0",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.0.tgz",
+      "integrity": "sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.28.5",
+        "@babel/helper-plugin-utils": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-new-target": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz",
+      "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.28.6.tgz",
+      "integrity": "sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-numeric-separator": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.28.6.tgz",
+      "integrity": "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-object-rest-spread": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.6.tgz",
+      "integrity": "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-compilation-targets": "^7.28.6",
+        "@babel/helper-plugin-utils": "^7.28.6",
+        "@babel/plugin-transform-destructuring": "^7.28.5",
+        "@babel/plugin-transform-parameters": "^7.27.7",
+        "@babel/traverse": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-object-super": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz",
+      "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1",
+        "@babel/helper-replace-supers": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-optional-catch-binding": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.28.6.tgz",
+      "integrity": "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-optional-chaining": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.6.tgz",
+      "integrity": "sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.28.6",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-parameters": {
+      "version": "7.27.7",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz",
+      "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-private-methods": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.28.6.tgz",
+      "integrity": "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-create-class-features-plugin": "^7.28.6",
+        "@babel/helper-plugin-utils": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-private-property-in-object": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.28.6.tgz",
+      "integrity": "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-annotate-as-pure": "^7.27.3",
+        "@babel/helper-create-class-features-plugin": "^7.28.6",
+        "@babel/helper-plugin-utils": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-private-property-in-object/node_modules/@babel/helper-annotate-as-pure": {
+      "version": "7.27.3",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz",
+      "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.27.3"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-property-literals": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz",
+      "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-regenerator": {
+      "version": "7.29.0",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.0.tgz",
+      "integrity": "sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-regexp-modifiers": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.28.6.tgz",
+      "integrity": "sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.28.5",
+        "@babel/helper-plugin-utils": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-reserved-words": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz",
+      "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-runtime": {
+      "version": "7.26.10",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.26.10.tgz",
+      "integrity": "sha512-NWaL2qG6HRpONTnj4JvDU6th4jYeZOJgu3QhmFTCihib0ermtOJqktA5BduGm3suhhVe9EMP9c9+mfJ/I9slqw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-module-imports": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.26.5",
+        "babel-plugin-polyfill-corejs2": "^0.4.10",
+        "babel-plugin-polyfill-corejs3": "^0.11.0",
+        "babel-plugin-polyfill-regenerator": "^0.6.1",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-runtime/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/@babel/plugin-transform-shorthand-properties": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz",
+      "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-spread": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.28.6.tgz",
+      "integrity": "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.28.6",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-sticky-regex": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz",
+      "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-template-literals": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz",
+      "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-typeof-symbol": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz",
+      "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-unicode-escapes": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz",
+      "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-unicode-property-regex": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.28.6.tgz",
+      "integrity": "sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.28.5",
+        "@babel/helper-plugin-utils": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-unicode-regex": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz",
+      "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+        "@babel/helper-plugin-utils": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-unicode-sets-regex": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.28.6.tgz",
+      "integrity": "sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.28.5",
+        "@babel/helper-plugin-utils": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/preset-env": {
+      "version": "7.26.9",
+      "resolved": "https://registry.npmmirror.com/@babel/preset-env/-/preset-env-7.26.9.tgz",
+      "integrity": "sha512-vX3qPGE8sEKEAZCWk05k3cpTAE3/nOYca++JA+Rd0z2NCNzabmYvEiSShKzm10zdquOIAVXsy2Ei/DTW34KlKQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/compat-data": "^7.26.8",
+        "@babel/helper-compilation-targets": "^7.26.5",
+        "@babel/helper-plugin-utils": "^7.26.5",
+        "@babel/helper-validator-option": "^7.25.9",
+        "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9",
+        "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9",
+        "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9",
+        "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9",
+        "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9",
+        "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2",
+        "@babel/plugin-syntax-import-assertions": "^7.26.0",
+        "@babel/plugin-syntax-import-attributes": "^7.26.0",
+        "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
+        "@babel/plugin-transform-arrow-functions": "^7.25.9",
+        "@babel/plugin-transform-async-generator-functions": "^7.26.8",
+        "@babel/plugin-transform-async-to-generator": "^7.25.9",
+        "@babel/plugin-transform-block-scoped-functions": "^7.26.5",
+        "@babel/plugin-transform-block-scoping": "^7.25.9",
+        "@babel/plugin-transform-class-properties": "^7.25.9",
+        "@babel/plugin-transform-class-static-block": "^7.26.0",
+        "@babel/plugin-transform-classes": "^7.25.9",
+        "@babel/plugin-transform-computed-properties": "^7.25.9",
+        "@babel/plugin-transform-destructuring": "^7.25.9",
+        "@babel/plugin-transform-dotall-regex": "^7.25.9",
+        "@babel/plugin-transform-duplicate-keys": "^7.25.9",
+        "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9",
+        "@babel/plugin-transform-dynamic-import": "^7.25.9",
+        "@babel/plugin-transform-exponentiation-operator": "^7.26.3",
+        "@babel/plugin-transform-export-namespace-from": "^7.25.9",
+        "@babel/plugin-transform-for-of": "^7.26.9",
+        "@babel/plugin-transform-function-name": "^7.25.9",
+        "@babel/plugin-transform-json-strings": "^7.25.9",
+        "@babel/plugin-transform-literals": "^7.25.9",
+        "@babel/plugin-transform-logical-assignment-operators": "^7.25.9",
+        "@babel/plugin-transform-member-expression-literals": "^7.25.9",
+        "@babel/plugin-transform-modules-amd": "^7.25.9",
+        "@babel/plugin-transform-modules-commonjs": "^7.26.3",
+        "@babel/plugin-transform-modules-systemjs": "^7.25.9",
+        "@babel/plugin-transform-modules-umd": "^7.25.9",
+        "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9",
+        "@babel/plugin-transform-new-target": "^7.25.9",
+        "@babel/plugin-transform-nullish-coalescing-operator": "^7.26.6",
+        "@babel/plugin-transform-numeric-separator": "^7.25.9",
+        "@babel/plugin-transform-object-rest-spread": "^7.25.9",
+        "@babel/plugin-transform-object-super": "^7.25.9",
+        "@babel/plugin-transform-optional-catch-binding": "^7.25.9",
+        "@babel/plugin-transform-optional-chaining": "^7.25.9",
+        "@babel/plugin-transform-parameters": "^7.25.9",
+        "@babel/plugin-transform-private-methods": "^7.25.9",
+        "@babel/plugin-transform-private-property-in-object": "^7.25.9",
+        "@babel/plugin-transform-property-literals": "^7.25.9",
+        "@babel/plugin-transform-regenerator": "^7.25.9",
+        "@babel/plugin-transform-regexp-modifiers": "^7.26.0",
+        "@babel/plugin-transform-reserved-words": "^7.25.9",
+        "@babel/plugin-transform-shorthand-properties": "^7.25.9",
+        "@babel/plugin-transform-spread": "^7.25.9",
+        "@babel/plugin-transform-sticky-regex": "^7.25.9",
+        "@babel/plugin-transform-template-literals": "^7.26.8",
+        "@babel/plugin-transform-typeof-symbol": "^7.26.7",
+        "@babel/plugin-transform-unicode-escapes": "^7.25.9",
+        "@babel/plugin-transform-unicode-property-regex": "^7.25.9",
+        "@babel/plugin-transform-unicode-regex": "^7.25.9",
+        "@babel/plugin-transform-unicode-sets-regex": "^7.25.9",
+        "@babel/preset-modules": "0.1.6-no-external-plugins",
+        "babel-plugin-polyfill-corejs2": "^0.4.10",
+        "babel-plugin-polyfill-corejs3": "^0.11.0",
+        "babel-plugin-polyfill-regenerator": "^0.6.1",
+        "core-js-compat": "^3.40.0",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/preset-env/node_modules/@babel/plugin-syntax-import-attributes": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz",
+      "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/preset-env/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/@babel/preset-modules": {
+      "version": "0.1.6-no-external-plugins",
+      "resolved": "https://registry.npmmirror.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz",
+      "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "@babel/types": "^7.4.4",
+        "esutils": "^2.0.2"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0"
+      }
+    },
+    "node_modules/@babel/runtime": {
+      "version": "7.26.10",
+      "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.26.10.tgz",
+      "integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "regenerator-runtime": "^0.14.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/template": {
+      "version": "7.28.6",
+      "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.28.6.tgz",
+      "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/code-frame": "^7.28.6",
+        "@babel/parser": "^7.28.6",
+        "@babel/types": "^7.28.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/traverse": {
+      "version": "7.29.0",
+      "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.29.0.tgz",
+      "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/code-frame": "^7.29.0",
+        "@babel/generator": "^7.29.0",
+        "@babel/helper-globals": "^7.28.0",
+        "@babel/parser": "^7.29.0",
+        "@babel/template": "^7.28.6",
+        "@babel/types": "^7.29.0",
+        "debug": "^4.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/traverse/node_modules/@babel/generator": {
+      "version": "7.29.1",
+      "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.29.1.tgz",
+      "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/parser": "^7.29.0",
+        "@babel/types": "^7.29.0",
+        "@jridgewell/gen-mapping": "^0.3.12",
+        "@jridgewell/trace-mapping": "^0.3.28",
+        "jsesc": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/types": {
+      "version": "7.29.0",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.29.0.tgz",
+      "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.27.1",
+        "@babel/helper-validator-identifier": "^7.28.5"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@colors/colors": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmmirror.com/@colors/colors/-/colors-1.5.0.tgz",
+      "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.1.90"
+      }
+    },
+    "node_modules/@discoveryjs/json-ext": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmmirror.com/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz",
+      "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=14.17.0"
+      }
+    },
+    "node_modules/@esbuild/aix-ppc64": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz",
+      "integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "aix"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/android-arm": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.25.4.tgz",
+      "integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/android-arm64": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz",
+      "integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/android-x64": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.25.4.tgz",
+      "integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/darwin-arm64": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz",
+      "integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/darwin-x64": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz",
+      "integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/freebsd-arm64": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz",
+      "integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/freebsd-x64": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz",
+      "integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-arm": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz",
+      "integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-arm64": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz",
+      "integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-ia32": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz",
+      "integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-loong64": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz",
+      "integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==",
+      "cpu": [
+        "loong64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-mips64el": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz",
+      "integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==",
+      "cpu": [
+        "mips64el"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-ppc64": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz",
+      "integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-riscv64": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz",
+      "integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-s390x": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz",
+      "integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-x64": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz",
+      "integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/netbsd-arm64": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz",
+      "integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/netbsd-x64": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz",
+      "integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/openbsd-arm64": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz",
+      "integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/openbsd-x64": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz",
+      "integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/sunos-x64": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz",
+      "integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "sunos"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/win32-arm64": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz",
+      "integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/win32-ia32": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz",
+      "integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/win32-x64": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz",
+      "integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@inquirer/ansi": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/@inquirer/ansi/-/ansi-1.0.2.tgz",
+      "integrity": "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@inquirer/checkbox": {
+      "version": "4.3.2",
+      "resolved": "https://registry.npmmirror.com/@inquirer/checkbox/-/checkbox-4.3.2.tgz",
+      "integrity": "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@inquirer/ansi": "^1.0.2",
+        "@inquirer/core": "^10.3.2",
+        "@inquirer/figures": "^1.0.15",
+        "@inquirer/type": "^3.0.10",
+        "yoctocolors-cjs": "^2.1.3"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@types/node": ">=18"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@inquirer/confirm": {
+      "version": "5.1.6",
+      "resolved": "https://registry.npmmirror.com/@inquirer/confirm/-/confirm-5.1.6.tgz",
+      "integrity": "sha512-6ZXYK3M1XmaVBZX6FCfChgtponnL0R6I7k8Nu+kaoNkT828FVZTcca1MqmWQipaW2oNREQl5AaPCUOOCVNdRMw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@inquirer/core": "^10.1.7",
+        "@inquirer/type": "^3.0.4"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@types/node": ">=18"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@inquirer/core": {
+      "version": "10.3.2",
+      "resolved": "https://registry.npmmirror.com/@inquirer/core/-/core-10.3.2.tgz",
+      "integrity": "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@inquirer/ansi": "^1.0.2",
+        "@inquirer/figures": "^1.0.15",
+        "@inquirer/type": "^3.0.10",
+        "cli-width": "^4.1.0",
+        "mute-stream": "^2.0.0",
+        "signal-exit": "^4.1.0",
+        "wrap-ansi": "^6.2.0",
+        "yoctocolors-cjs": "^2.1.3"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@types/node": ">=18"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@inquirer/editor": {
+      "version": "4.2.23",
+      "resolved": "https://registry.npmmirror.com/@inquirer/editor/-/editor-4.2.23.tgz",
+      "integrity": "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@inquirer/core": "^10.3.2",
+        "@inquirer/external-editor": "^1.0.3",
+        "@inquirer/type": "^3.0.10"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@types/node": ">=18"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@inquirer/expand": {
+      "version": "4.0.23",
+      "resolved": "https://registry.npmmirror.com/@inquirer/expand/-/expand-4.0.23.tgz",
+      "integrity": "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@inquirer/core": "^10.3.2",
+        "@inquirer/type": "^3.0.10",
+        "yoctocolors-cjs": "^2.1.3"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@types/node": ">=18"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@inquirer/external-editor": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/@inquirer/external-editor/-/external-editor-1.0.3.tgz",
+      "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "chardet": "^2.1.1",
+        "iconv-lite": "^0.7.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@types/node": ">=18"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@inquirer/external-editor/node_modules/iconv-lite": {
+      "version": "0.7.2",
+      "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.7.2.tgz",
+      "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/express"
+      }
+    },
+    "node_modules/@inquirer/figures": {
+      "version": "1.0.15",
+      "resolved": "https://registry.npmmirror.com/@inquirer/figures/-/figures-1.0.15.tgz",
+      "integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@inquirer/input": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmmirror.com/@inquirer/input/-/input-4.3.1.tgz",
+      "integrity": "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@inquirer/core": "^10.3.2",
+        "@inquirer/type": "^3.0.10"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@types/node": ">=18"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@inquirer/number": {
+      "version": "3.0.23",
+      "resolved": "https://registry.npmmirror.com/@inquirer/number/-/number-3.0.23.tgz",
+      "integrity": "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@inquirer/core": "^10.3.2",
+        "@inquirer/type": "^3.0.10"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@types/node": ">=18"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@inquirer/password": {
+      "version": "4.0.23",
+      "resolved": "https://registry.npmmirror.com/@inquirer/password/-/password-4.0.23.tgz",
+      "integrity": "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@inquirer/ansi": "^1.0.2",
+        "@inquirer/core": "^10.3.2",
+        "@inquirer/type": "^3.0.10"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@types/node": ">=18"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@inquirer/prompts": {
+      "version": "7.3.2",
+      "resolved": "https://registry.npmmirror.com/@inquirer/prompts/-/prompts-7.3.2.tgz",
+      "integrity": "sha512-G1ytyOoHh5BphmEBxSwALin3n1KGNYB6yImbICcRQdzXfOGbuJ9Jske/Of5Sebk339NSGGNfUshnzK8YWkTPsQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@inquirer/checkbox": "^4.1.2",
+        "@inquirer/confirm": "^5.1.6",
+        "@inquirer/editor": "^4.2.7",
+        "@inquirer/expand": "^4.0.9",
+        "@inquirer/input": "^4.1.6",
+        "@inquirer/number": "^3.0.9",
+        "@inquirer/password": "^4.0.9",
+        "@inquirer/rawlist": "^4.0.9",
+        "@inquirer/search": "^3.0.9",
+        "@inquirer/select": "^4.0.9"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@types/node": ">=18"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@inquirer/rawlist": {
+      "version": "4.1.11",
+      "resolved": "https://registry.npmmirror.com/@inquirer/rawlist/-/rawlist-4.1.11.tgz",
+      "integrity": "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@inquirer/core": "^10.3.2",
+        "@inquirer/type": "^3.0.10",
+        "yoctocolors-cjs": "^2.1.3"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@types/node": ">=18"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@inquirer/search": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmmirror.com/@inquirer/search/-/search-3.2.2.tgz",
+      "integrity": "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@inquirer/core": "^10.3.2",
+        "@inquirer/figures": "^1.0.15",
+        "@inquirer/type": "^3.0.10",
+        "yoctocolors-cjs": "^2.1.3"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@types/node": ">=18"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@inquirer/select": {
+      "version": "4.4.2",
+      "resolved": "https://registry.npmmirror.com/@inquirer/select/-/select-4.4.2.tgz",
+      "integrity": "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@inquirer/ansi": "^1.0.2",
+        "@inquirer/core": "^10.3.2",
+        "@inquirer/figures": "^1.0.15",
+        "@inquirer/type": "^3.0.10",
+        "yoctocolors-cjs": "^2.1.3"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@types/node": ">=18"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@inquirer/type": {
+      "version": "3.0.10",
+      "resolved": "https://registry.npmmirror.com/@inquirer/type/-/type-3.0.10.tgz",
+      "integrity": "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@types/node": ">=18"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@isaacs/cliui": {
+      "version": "8.0.2",
+      "resolved": "https://registry.npmmirror.com/@isaacs/cliui/-/cliui-8.0.2.tgz",
+      "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "string-width": "^5.1.2",
+        "string-width-cjs": "npm:string-width@^4.2.0",
+        "strip-ansi": "^7.0.1",
+        "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+        "wrap-ansi": "^8.1.0",
+        "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@isaacs/cliui/node_modules/ansi-regex": {
+      "version": "6.2.2",
+      "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.2.2.tgz",
+      "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+      }
+    },
+    "node_modules/@isaacs/cliui/node_modules/ansi-styles": {
+      "version": "6.2.3",
+      "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.3.tgz",
+      "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/@isaacs/cliui/node_modules/emoji-regex": {
+      "version": "9.2.2",
+      "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-9.2.2.tgz",
+      "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@isaacs/cliui/node_modules/string-width": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmmirror.com/string-width/-/string-width-5.1.2.tgz",
+      "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "eastasianwidth": "^0.2.0",
+        "emoji-regex": "^9.2.2",
+        "strip-ansi": "^7.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@isaacs/cliui/node_modules/strip-ansi": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.2.tgz",
+      "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-regex": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+      }
+    },
+    "node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+      "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-styles": "^6.1.0",
+        "string-width": "^5.0.1",
+        "strip-ansi": "^7.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+      }
+    },
+    "node_modules/@isaacs/fs-minipass": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmmirror.com/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
+      "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "minipass": "^7.0.4"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      }
+    },
+    "node_modules/@istanbuljs/schema": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmmirror.com/@istanbuljs/schema/-/schema-0.1.3.tgz",
+      "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@jridgewell/gen-mapping": {
+      "version": "0.3.13",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+      "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@jridgewell/sourcemap-codec": "^1.5.0",
+        "@jridgewell/trace-mapping": "^0.3.24"
+      }
+    },
+    "node_modules/@jridgewell/resolve-uri": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+      "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/source-map": {
+      "version": "0.3.11",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/source-map/-/source-map-0.3.11.tgz",
+      "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.25"
+      }
+    },
+    "node_modules/@jridgewell/sourcemap-codec": {
+      "version": "1.5.5",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+      "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@jridgewell/trace-mapping": {
+      "version": "0.3.31",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+      "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@jridgewell/resolve-uri": "^3.1.0",
+        "@jridgewell/sourcemap-codec": "^1.4.14"
+      }
+    },
+    "node_modules/@jsonjoy.com/base64": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/@jsonjoy.com/base64/-/base64-1.1.2.tgz",
+      "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=10.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/@jsonjoy.com/buffers": {
+      "version": "17.67.0",
+      "resolved": "https://registry.npmmirror.com/@jsonjoy.com/buffers/-/buffers-17.67.0.tgz",
+      "integrity": "sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=10.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/@jsonjoy.com/codegen": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/@jsonjoy.com/codegen/-/codegen-1.0.0.tgz",
+      "integrity": "sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=10.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/@jsonjoy.com/fs-core": {
+      "version": "4.56.10",
+      "resolved": "https://registry.npmmirror.com/@jsonjoy.com/fs-core/-/fs-core-4.56.10.tgz",
+      "integrity": "sha512-PyAEA/3cnHhsGcdY+AmIU+ZPqTuZkDhCXQ2wkXypdLitSpd6d5Ivxhnq4wa2ETRWFVJGabYynBWxIijOswSmOw==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@jsonjoy.com/fs-node-builtins": "4.56.10",
+        "@jsonjoy.com/fs-node-utils": "4.56.10",
+        "thingies": "^2.5.0"
+      },
+      "engines": {
+        "node": ">=10.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/@jsonjoy.com/fs-fsa": {
+      "version": "4.56.10",
+      "resolved": "https://registry.npmmirror.com/@jsonjoy.com/fs-fsa/-/fs-fsa-4.56.10.tgz",
+      "integrity": "sha512-/FVK63ysNzTPOnCCcPoPHt77TOmachdMS422txM4KhxddLdbW1fIbFMYH0AM0ow/YchCyS5gqEjKLNyv71j/5Q==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@jsonjoy.com/fs-core": "4.56.10",
+        "@jsonjoy.com/fs-node-builtins": "4.56.10",
+        "@jsonjoy.com/fs-node-utils": "4.56.10",
+        "thingies": "^2.5.0"
+      },
+      "engines": {
+        "node": ">=10.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/@jsonjoy.com/fs-node": {
+      "version": "4.56.10",
+      "resolved": "https://registry.npmmirror.com/@jsonjoy.com/fs-node/-/fs-node-4.56.10.tgz",
+      "integrity": "sha512-7R4Gv3tkUdW3dXfXiOkqxkElxKNVdd8BDOWC0/dbERd0pXpPY+s2s1Mino+aTvkGrFPiY+mmVxA7zhskm4Ue4Q==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@jsonjoy.com/fs-core": "4.56.10",
+        "@jsonjoy.com/fs-node-builtins": "4.56.10",
+        "@jsonjoy.com/fs-node-utils": "4.56.10",
+        "@jsonjoy.com/fs-print": "4.56.10",
+        "@jsonjoy.com/fs-snapshot": "4.56.10",
+        "glob-to-regex.js": "^1.0.0",
+        "thingies": "^2.5.0"
+      },
+      "engines": {
+        "node": ">=10.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/@jsonjoy.com/fs-node-builtins": {
+      "version": "4.56.10",
+      "resolved": "https://registry.npmmirror.com/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.56.10.tgz",
+      "integrity": "sha512-uUnKz8R0YJyKq5jXpZtkGV9U0pJDt8hmYcLRrPjROheIfjMXsz82kXMgAA/qNg0wrZ1Kv+hrg7azqEZx6XZCVw==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=10.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/@jsonjoy.com/fs-node-to-fsa": {
+      "version": "4.56.10",
+      "resolved": "https://registry.npmmirror.com/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.56.10.tgz",
+      "integrity": "sha512-oH+O6Y4lhn9NyG6aEoFwIBNKZeYy66toP5LJcDOMBgL99BKQMUf/zWJspdRhMdn/3hbzQsZ8EHHsuekbFLGUWw==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@jsonjoy.com/fs-fsa": "4.56.10",
+        "@jsonjoy.com/fs-node-builtins": "4.56.10",
+        "@jsonjoy.com/fs-node-utils": "4.56.10"
+      },
+      "engines": {
+        "node": ">=10.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/@jsonjoy.com/fs-node-utils": {
+      "version": "4.56.10",
+      "resolved": "https://registry.npmmirror.com/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.56.10.tgz",
+      "integrity": "sha512-8EuPBgVI2aDPwFdaNQeNpHsyqPi3rr+85tMNG/lHvQLiVjzoZsvxA//Xd8aB567LUhy4QS03ptT+unkD/DIsNg==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@jsonjoy.com/fs-node-builtins": "4.56.10"
+      },
+      "engines": {
+        "node": ">=10.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/@jsonjoy.com/fs-print": {
+      "version": "4.56.10",
+      "resolved": "https://registry.npmmirror.com/@jsonjoy.com/fs-print/-/fs-print-4.56.10.tgz",
+      "integrity": "sha512-JW4fp5mAYepzFsSGrQ48ep8FXxpg4niFWHdF78wDrFGof7F3tKDJln72QFDEn/27M1yHd4v7sKHHVPh78aWcEw==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@jsonjoy.com/fs-node-utils": "4.56.10",
+        "tree-dump": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=10.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/@jsonjoy.com/fs-snapshot": {
+      "version": "4.56.10",
+      "resolved": "https://registry.npmmirror.com/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.56.10.tgz",
+      "integrity": "sha512-DkR6l5fj7+qj0+fVKm/OOXMGfDFCGXLfyHkORH3DF8hxkpDgIHbhf/DwncBMs2igu/ST7OEkexn1gIqoU6Y+9g==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@jsonjoy.com/buffers": "^17.65.0",
+        "@jsonjoy.com/fs-node-utils": "4.56.10",
+        "@jsonjoy.com/json-pack": "^17.65.0",
+        "@jsonjoy.com/util": "^17.65.0"
+      },
+      "engines": {
+        "node": ">=10.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/base64": {
+      "version": "17.67.0",
+      "resolved": "https://registry.npmmirror.com/@jsonjoy.com/base64/-/base64-17.67.0.tgz",
+      "integrity": "sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=10.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/codegen": {
+      "version": "17.67.0",
+      "resolved": "https://registry.npmmirror.com/@jsonjoy.com/codegen/-/codegen-17.67.0.tgz",
+      "integrity": "sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=10.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pack": {
+      "version": "17.67.0",
+      "resolved": "https://registry.npmmirror.com/@jsonjoy.com/json-pack/-/json-pack-17.67.0.tgz",
+      "integrity": "sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@jsonjoy.com/base64": "17.67.0",
+        "@jsonjoy.com/buffers": "17.67.0",
+        "@jsonjoy.com/codegen": "17.67.0",
+        "@jsonjoy.com/json-pointer": "17.67.0",
+        "@jsonjoy.com/util": "17.67.0",
+        "hyperdyperid": "^1.2.0",
+        "thingies": "^2.5.0",
+        "tree-dump": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=10.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pointer": {
+      "version": "17.67.0",
+      "resolved": "https://registry.npmmirror.com/@jsonjoy.com/json-pointer/-/json-pointer-17.67.0.tgz",
+      "integrity": "sha512-+iqOFInH+QZGmSuaybBUNdh7yvNrXvqR+h3wjXm0N/3JK1EyyFAeGJvqnmQL61d1ARLlk/wJdFKSL+LHJ1eaUA==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@jsonjoy.com/util": "17.67.0"
+      },
+      "engines": {
+        "node": ">=10.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/util": {
+      "version": "17.67.0",
+      "resolved": "https://registry.npmmirror.com/@jsonjoy.com/util/-/util-17.67.0.tgz",
+      "integrity": "sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@jsonjoy.com/buffers": "17.67.0",
+        "@jsonjoy.com/codegen": "17.67.0"
+      },
+      "engines": {
+        "node": ">=10.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/@jsonjoy.com/json-pack": {
+      "version": "1.21.0",
+      "resolved": "https://registry.npmmirror.com/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz",
+      "integrity": "sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@jsonjoy.com/base64": "^1.1.2",
+        "@jsonjoy.com/buffers": "^1.2.0",
+        "@jsonjoy.com/codegen": "^1.0.0",
+        "@jsonjoy.com/json-pointer": "^1.0.2",
+        "@jsonjoy.com/util": "^1.9.0",
+        "hyperdyperid": "^1.2.0",
+        "thingies": "^2.5.0",
+        "tree-dump": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=10.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/@jsonjoy.com/json-pack/node_modules/@jsonjoy.com/buffers": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz",
+      "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=10.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/@jsonjoy.com/json-pointer": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz",
+      "integrity": "sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@jsonjoy.com/codegen": "^1.0.0",
+        "@jsonjoy.com/util": "^1.9.0"
+      },
+      "engines": {
+        "node": ">=10.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/@jsonjoy.com/util": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmmirror.com/@jsonjoy.com/util/-/util-1.9.0.tgz",
+      "integrity": "sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@jsonjoy.com/buffers": "^1.0.0",
+        "@jsonjoy.com/codegen": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=10.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/@jsonjoy.com/util/node_modules/@jsonjoy.com/buffers": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz",
+      "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=10.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/@leichtgewicht/ip-codec": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmmirror.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz",
+      "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@listr2/prompt-adapter-inquirer": {
+      "version": "2.0.18",
+      "resolved": "https://registry.npmmirror.com/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-2.0.18.tgz",
+      "integrity": "sha512-0hz44rAcrphyXcA8IS7EJ2SCoaBZD2u5goE8S/e+q/DL+dOGpqpcLidVOFeLG3VgML62SXmfRLAhWt0zL1oW4Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@inquirer/type": "^1.5.5"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      },
+      "peerDependencies": {
+        "@inquirer/prompts": ">= 3 < 8"
+      }
+    },
+    "node_modules/@listr2/prompt-adapter-inquirer/node_modules/@inquirer/type": {
+      "version": "1.5.5",
+      "resolved": "https://registry.npmmirror.com/@inquirer/type/-/type-1.5.5.tgz",
+      "integrity": "sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "mute-stream": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@listr2/prompt-adapter-inquirer/node_modules/mute-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/mute-stream/-/mute-stream-1.0.0.tgz",
+      "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+      }
+    },
+    "node_modules/@lmdb/lmdb-darwin-arm64": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmmirror.com/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.2.6.tgz",
+      "integrity": "sha512-yF/ih9EJJZc72psFQbwnn8mExIWfTnzWJg+N02hnpXtDPETYLmQswIMBn7+V88lfCaFrMozJsUvcEQIkEPU0Gg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@lmdb/lmdb-darwin-x64": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmmirror.com/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.2.6.tgz",
+      "integrity": "sha512-5BbCumsFLbCi586Bb1lTWQFkekdQUw8/t8cy++Uq251cl3hbDIGEwD9HAwh8H6IS2F6QA9KdKmO136LmipRNkg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@lmdb/lmdb-linux-arm": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmmirror.com/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.2.6.tgz",
+      "integrity": "sha512-+6XgLpMb7HBoWxXj+bLbiiB4s0mRRcDPElnRS3LpWRzdYSe+gFk5MT/4RrVNqd2MESUDmb53NUXw1+BP69bjiQ==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@lmdb/lmdb-linux-arm64": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmmirror.com/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.2.6.tgz",
+      "integrity": "sha512-l5VmJamJ3nyMmeD1ANBQCQqy7do1ESaJQfKPSm2IG9/ADZryptTyCj8N6QaYgIWewqNUrcbdMkJajRQAt5Qjfg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@lmdb/lmdb-linux-x64": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmmirror.com/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.2.6.tgz",
+      "integrity": "sha512-nDYT8qN9si5+onHYYaI4DiauDMx24OAiuZAUsEqrDy+ja/3EbpXPX/VAkMV8AEaQhy3xc4dRC+KcYIvOFefJ4Q==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@lmdb/lmdb-win32-x64": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmmirror.com/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.2.6.tgz",
+      "integrity": "sha512-XlqVtILonQnG+9fH2N3Aytria7P/1fwDgDhl29rde96uH2sLB8CHORIf2PfuLVzFQJ7Uqp8py9AYwr3ZUCFfWg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz",
+      "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz",
+      "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz",
+      "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz",
+      "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz",
+      "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz",
+      "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@napi-rs/nice": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/@napi-rs/nice/-/nice-1.1.1.tgz",
+      "integrity": "sha512-xJIPs+bYuc9ASBl+cvGsKbGrJmS6fAKaSZCnT0lhahT5rhA2VVy9/EcIgd2JhtEuFOJNx7UHNn/qiTPTY4nrQw==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">= 10"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/Brooooooklyn"
+      },
+      "optionalDependencies": {
+        "@napi-rs/nice-android-arm-eabi": "1.1.1",
+        "@napi-rs/nice-android-arm64": "1.1.1",
+        "@napi-rs/nice-darwin-arm64": "1.1.1",
+        "@napi-rs/nice-darwin-x64": "1.1.1",
+        "@napi-rs/nice-freebsd-x64": "1.1.1",
+        "@napi-rs/nice-linux-arm-gnueabihf": "1.1.1",
+        "@napi-rs/nice-linux-arm64-gnu": "1.1.1",
+        "@napi-rs/nice-linux-arm64-musl": "1.1.1",
+        "@napi-rs/nice-linux-ppc64-gnu": "1.1.1",
+        "@napi-rs/nice-linux-riscv64-gnu": "1.1.1",
+        "@napi-rs/nice-linux-s390x-gnu": "1.1.1",
+        "@napi-rs/nice-linux-x64-gnu": "1.1.1",
+        "@napi-rs/nice-linux-x64-musl": "1.1.1",
+        "@napi-rs/nice-openharmony-arm64": "1.1.1",
+        "@napi-rs/nice-win32-arm64-msvc": "1.1.1",
+        "@napi-rs/nice-win32-ia32-msvc": "1.1.1",
+        "@napi-rs/nice-win32-x64-msvc": "1.1.1"
+      }
+    },
+    "node_modules/@napi-rs/nice-android-arm-eabi": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.1.1.tgz",
+      "integrity": "sha512-kjirL3N6TnRPv5iuHw36wnucNqXAO46dzK9oPb0wj076R5Xm8PfUVA9nAFB5ZNMmfJQJVKACAPd/Z2KYMppthw==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@napi-rs/nice-android-arm64": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.1.1.tgz",
+      "integrity": "sha512-blG0i7dXgbInN5urONoUCNf+DUEAavRffrO7fZSeoRMJc5qD+BJeNcpr54msPF6qfDD6kzs9AQJogZvT2KD5nw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@napi-rs/nice-darwin-arm64": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.1.1.tgz",
+      "integrity": "sha512-s/E7w45NaLqTGuOjC2p96pct4jRfo61xb9bU1unM/MJ/RFkKlJyJDx7OJI/O0ll/hrfpqKopuAFDV8yo0hfT7A==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@napi-rs/nice-darwin-x64": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.1.1.tgz",
+      "integrity": "sha512-dGoEBnVpsdcC+oHHmW1LRK5eiyzLwdgNQq3BmZIav+9/5WTZwBYX7r5ZkQC07Nxd3KHOCkgbHSh4wPkH1N1LiQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@napi-rs/nice-freebsd-x64": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.1.1.tgz",
+      "integrity": "sha512-kHv4kEHAylMYmlNwcQcDtXjklYp4FCf0b05E+0h6nDHsZ+F0bDe04U/tXNOqrx5CmIAth4vwfkjjUmp4c4JktQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@napi-rs/nice-linux-arm-gnueabihf": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.1.1.tgz",
+      "integrity": "sha512-E1t7K0efyKXZDoZg1LzCOLxgolxV58HCkaEkEvIYQx12ht2pa8hoBo+4OB3qh7e+QiBlp1SRf+voWUZFxyhyqg==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@napi-rs/nice-linux-arm64-gnu": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.1.1.tgz",
+      "integrity": "sha512-CIKLA12DTIZlmTaaKhQP88R3Xao+gyJxNWEn04wZwC2wmRapNnxCUZkVwggInMJvtVElA+D4ZzOU5sX4jV+SmQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@napi-rs/nice-linux-arm64-musl": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.1.1.tgz",
+      "integrity": "sha512-+2Rzdb3nTIYZ0YJF43qf2twhqOCkiSrHx2Pg6DJaCPYhhaxbLcdlV8hCRMHghQ+EtZQWGNcS2xF4KxBhSGeutg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@napi-rs/nice-linux-ppc64-gnu": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.1.1.tgz",
+      "integrity": "sha512-4FS8oc0GeHpwvv4tKciKkw3Y4jKsL7FRhaOeiPei0X9T4Jd619wHNe4xCLmN2EMgZoeGg+Q7GY7BsvwKpL22Tg==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@napi-rs/nice-linux-riscv64-gnu": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.1.1.tgz",
+      "integrity": "sha512-HU0nw9uD4FO/oGCCk409tCi5IzIZpH2agE6nN4fqpwVlCn5BOq0MS1dXGjXaG17JaAvrlpV5ZeyZwSon10XOXw==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@napi-rs/nice-linux-s390x-gnu": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.1.1.tgz",
+      "integrity": "sha512-2YqKJWWl24EwrX0DzCQgPLKQBxYDdBxOHot1KWEq7aY2uYeX+Uvtv4I8xFVVygJDgf6/92h9N3Y43WPx8+PAgQ==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@napi-rs/nice-linux-x64-gnu": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.1.1.tgz",
+      "integrity": "sha512-/gaNz3R92t+dcrfCw/96pDopcmec7oCcAQ3l/M+Zxr82KT4DljD37CpgrnXV+pJC263JkW572pdbP3hP+KjcIg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@napi-rs/nice-linux-x64-musl": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.1.1.tgz",
+      "integrity": "sha512-xScCGnyj/oppsNPMnevsBe3pvNaoK7FGvMjT35riz9YdhB2WtTG47ZlbxtOLpjeO9SqqQ2J2igCmz6IJOD5JYw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@napi-rs/nice-openharmony-arm64": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/@napi-rs/nice-openharmony-arm64/-/nice-openharmony-arm64-1.1.1.tgz",
+      "integrity": "sha512-6uJPRVwVCLDeoOaNyeiW0gp2kFIM4r7PL2MczdZQHkFi9gVlgm+Vn+V6nTWRcu856mJ2WjYJiumEajfSm7arPQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "openharmony"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@napi-rs/nice-win32-arm64-msvc": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.1.1.tgz",
+      "integrity": "sha512-uoTb4eAvM5B2aj/z8j+Nv8OttPf2m+HVx3UjA5jcFxASvNhQriyCQF1OB1lHL43ZhW+VwZlgvjmP5qF3+59atA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@napi-rs/nice-win32-ia32-msvc": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.1.1.tgz",
+      "integrity": "sha512-CNQqlQT9MwuCsg1Vd/oKXiuH+TcsSPJmlAFc5frFyX/KkOh0UpBLEj7aoY656d5UKZQMQFP7vJNa1DNUNORvug==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@napi-rs/nice-win32-x64-msvc": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.1.1.tgz",
+      "integrity": "sha512-vB+4G/jBQCAh0jelMTY3+kgFy00Hlx2f2/1zjMoH821IbplbWZOkLiTYXQkygNTzQJTq5cvwBDgn2ppHD+bglQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@ngtools/webpack": {
+      "version": "19.2.19",
+      "resolved": "https://registry.npmmirror.com/@ngtools/webpack/-/webpack-19.2.19.tgz",
+      "integrity": "sha512-R9aeTrOBiRVl8I698JWPniUAAEpSvzc8SUGWSM5UXWMcHnWqd92cOnJJ1aXDGJZKXrbhMhCBx9Dglmcks5IDpg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "^18.19.1 || ^20.11.1 || >=22.0.0",
+        "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+        "yarn": ">= 1.13.0"
+      },
+      "peerDependencies": {
+        "@angular/compiler-cli": "^19.0.0 || ^19.2.0-next.0",
+        "typescript": ">=5.5 <5.9",
+        "webpack": "^5.54.0"
+      }
+    },
+    "node_modules/@nodelib/fs.scandir": {
+      "version": "2.1.5",
+      "resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+      "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@nodelib/fs.stat": "2.0.5",
+        "run-parallel": "^1.1.9"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/@nodelib/fs.stat": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+      "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/@nodelib/fs.walk": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@nodelib/fs.scandir": "2.1.5",
+        "fastq": "^1.6.0"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/@npmcli/agent": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/@npmcli/agent/-/agent-3.0.0.tgz",
+      "integrity": "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "agent-base": "^7.1.0",
+        "http-proxy-agent": "^7.0.0",
+        "https-proxy-agent": "^7.0.1",
+        "lru-cache": "^10.0.1",
+        "socks-proxy-agent": "^8.0.3"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/@npmcli/agent/node_modules/lru-cache": {
+      "version": "10.4.3",
+      "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.4.3.tgz",
+      "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/@npmcli/fs": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/@npmcli/fs/-/fs-4.0.0.tgz",
+      "integrity": "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "semver": "^7.3.5"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/@npmcli/git": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmmirror.com/@npmcli/git/-/git-6.0.3.tgz",
+      "integrity": "sha512-GUYESQlxZRAdhs3UhbB6pVRNUELQOHXwK9ruDkwmCv2aZ5y0SApQzUJCg02p3A7Ue2J5hxvlk1YI53c00NmRyQ==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "@npmcli/promise-spawn": "^8.0.0",
+        "ini": "^5.0.0",
+        "lru-cache": "^10.0.1",
+        "npm-pick-manifest": "^10.0.0",
+        "proc-log": "^5.0.0",
+        "promise-retry": "^2.0.1",
+        "semver": "^7.3.5",
+        "which": "^5.0.0"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/@npmcli/git/node_modules/isexe": {
+      "version": "3.1.5",
+      "resolved": "https://registry.npmmirror.com/isexe/-/isexe-3.1.5.tgz",
+      "integrity": "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@npmcli/git/node_modules/lru-cache": {
+      "version": "10.4.3",
+      "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.4.3.tgz",
+      "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/@npmcli/git/node_modules/which": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/which/-/which-5.0.0.tgz",
+      "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "isexe": "^3.1.1"
+      },
+      "bin": {
+        "node-which": "bin/which.js"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/@npmcli/installed-package-contents": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/@npmcli/installed-package-contents/-/installed-package-contents-3.0.0.tgz",
+      "integrity": "sha512-fkxoPuFGvxyrH+OQzyTkX2LUEamrF4jZSmxjAtPPHHGO0dqsQ8tTKjnIS8SAnPHdk2I03BDtSMR5K/4loKg79Q==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "npm-bundled": "^4.0.0",
+        "npm-normalize-package-bin": "^4.0.0"
+      },
+      "bin": {
+        "installed-package-contents": "bin/index.js"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/@npmcli/node-gyp": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/@npmcli/node-gyp/-/node-gyp-4.0.0.tgz",
+      "integrity": "sha512-+t5DZ6mO/QFh78PByMq1fGSAub/agLJZDRfJRMeOSNCt8s9YVlTjmGpIPwPhvXTGUIJk+WszlT0rQa1W33yzNA==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/@npmcli/package-json": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmmirror.com/@npmcli/package-json/-/package-json-6.2.0.tgz",
+      "integrity": "sha512-rCNLSB/JzNvot0SEyXqWZ7tX2B5dD2a1br2Dp0vSYVo5jh8Z0EZ7lS9TsZ1UtziddB1UfNUaMCc538/HztnJGA==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "@npmcli/git": "^6.0.0",
+        "glob": "^10.2.2",
+        "hosted-git-info": "^8.0.0",
+        "json-parse-even-better-errors": "^4.0.0",
+        "proc-log": "^5.0.0",
+        "semver": "^7.5.3",
+        "validate-npm-package-license": "^3.0.4"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/@npmcli/package-json/node_modules/brace-expansion": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.2.tgz",
+      "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
+    "node_modules/@npmcli/package-json/node_modules/glob": {
+      "version": "10.4.5",
+      "resolved": "https://registry.npmmirror.com/glob/-/glob-10.4.5.tgz",
+      "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "foreground-child": "^3.1.0",
+        "jackspeak": "^3.1.2",
+        "minimatch": "^9.0.4",
+        "minipass": "^7.1.2",
+        "package-json-from-dist": "^1.0.0",
+        "path-scurry": "^1.11.1"
+      },
+      "bin": {
+        "glob": "dist/esm/bin.mjs"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/@npmcli/package-json/node_modules/minimatch": {
+      "version": "9.0.5",
+      "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz",
+      "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/@npmcli/promise-spawn": {
+      "version": "8.0.3",
+      "resolved": "https://registry.npmmirror.com/@npmcli/promise-spawn/-/promise-spawn-8.0.3.tgz",
+      "integrity": "sha512-Yb00SWaL4F8w+K8YGhQ55+xE4RUNdMHV43WZGsiTM92gS+lC0mGsn7I4hLug7pbao035S6bj3Y3w0cUNGLfmkg==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "which": "^5.0.0"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/@npmcli/promise-spawn/node_modules/isexe": {
+      "version": "3.1.5",
+      "resolved": "https://registry.npmmirror.com/isexe/-/isexe-3.1.5.tgz",
+      "integrity": "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@npmcli/promise-spawn/node_modules/which": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/which/-/which-5.0.0.tgz",
+      "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "isexe": "^3.1.1"
+      },
+      "bin": {
+        "node-which": "bin/which.js"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/@npmcli/redact": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmmirror.com/@npmcli/redact/-/redact-3.2.2.tgz",
+      "integrity": "sha512-7VmYAmk4csGv08QzrDKScdzn11jHPFGyqJW39FyPgPuAp3zIaUmuCo1yxw9aGs+NEJuTGQ9Gwqpt93vtJubucg==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/@npmcli/run-script": {
+      "version": "9.1.0",
+      "resolved": "https://registry.npmmirror.com/@npmcli/run-script/-/run-script-9.1.0.tgz",
+      "integrity": "sha512-aoNSbxtkePXUlbZB+anS1LqsJdctG5n3UVhfU47+CDdwMi6uNTBMF9gPcQRnqghQd2FGzcwwIFBruFMxjhBewg==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "@npmcli/node-gyp": "^4.0.0",
+        "@npmcli/package-json": "^6.0.0",
+        "@npmcli/promise-spawn": "^8.0.0",
+        "node-gyp": "^11.0.0",
+        "proc-log": "^5.0.0",
+        "which": "^5.0.0"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/@npmcli/run-script/node_modules/isexe": {
+      "version": "3.1.5",
+      "resolved": "https://registry.npmmirror.com/isexe/-/isexe-3.1.5.tgz",
+      "integrity": "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@npmcli/run-script/node_modules/which": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/which/-/which-5.0.0.tgz",
+      "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "isexe": "^3.1.1"
+      },
+      "bin": {
+        "node-which": "bin/which.js"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/@parcel/watcher": {
+      "version": "2.5.6",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher/-/watcher-2.5.6.tgz",
+      "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==",
+      "dev": true,
+      "hasInstallScript": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "detect-libc": "^2.0.3",
+        "is-glob": "^4.0.3",
+        "node-addon-api": "^7.0.0",
+        "picomatch": "^4.0.3"
+      },
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      },
+      "optionalDependencies": {
+        "@parcel/watcher-android-arm64": "2.5.6",
+        "@parcel/watcher-darwin-arm64": "2.5.6",
+        "@parcel/watcher-darwin-x64": "2.5.6",
+        "@parcel/watcher-freebsd-x64": "2.5.6",
+        "@parcel/watcher-linux-arm-glibc": "2.5.6",
+        "@parcel/watcher-linux-arm-musl": "2.5.6",
+        "@parcel/watcher-linux-arm64-glibc": "2.5.6",
+        "@parcel/watcher-linux-arm64-musl": "2.5.6",
+        "@parcel/watcher-linux-x64-glibc": "2.5.6",
+        "@parcel/watcher-linux-x64-musl": "2.5.6",
+        "@parcel/watcher-win32-arm64": "2.5.6",
+        "@parcel/watcher-win32-ia32": "2.5.6",
+        "@parcel/watcher-win32-x64": "2.5.6"
+      }
+    },
+    "node_modules/@parcel/watcher-android-arm64": {
+      "version": "2.5.6",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz",
+      "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-darwin-arm64": {
+      "version": "2.5.6",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz",
+      "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-darwin-x64": {
+      "version": "2.5.6",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz",
+      "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-freebsd-x64": {
+      "version": "2.5.6",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz",
+      "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-linux-arm-glibc": {
+      "version": "2.5.6",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz",
+      "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-linux-arm-musl": {
+      "version": "2.5.6",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz",
+      "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-linux-arm64-glibc": {
+      "version": "2.5.6",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz",
+      "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-linux-arm64-musl": {
+      "version": "2.5.6",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz",
+      "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-linux-x64-glibc": {
+      "version": "2.5.6",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz",
+      "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-linux-x64-musl": {
+      "version": "2.5.6",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz",
+      "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-win32-arm64": {
+      "version": "2.5.6",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz",
+      "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-win32-ia32": {
+      "version": "2.5.6",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz",
+      "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-win32-x64": {
+      "version": "2.5.6",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz",
+      "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher/node_modules/node-addon-api": {
+      "version": "7.1.1",
+      "resolved": "https://registry.npmmirror.com/node-addon-api/-/node-addon-api-7.1.1.tgz",
+      "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/@parcel/watcher/node_modules/picomatch": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz",
+      "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/@pkgjs/parseargs": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmmirror.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+      "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=14"
+      }
+    },
+    "node_modules/@rollup/rollup-android-arm-eabi": {
+      "version": "4.34.8",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz",
+      "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ]
+    },
+    "node_modules/@rollup/rollup-android-arm64": {
+      "version": "4.34.8",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz",
+      "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ]
+    },
+    "node_modules/@rollup/rollup-darwin-arm64": {
+      "version": "4.34.8",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz",
+      "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@rollup/rollup-darwin-x64": {
+      "version": "4.34.8",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz",
+      "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@rollup/rollup-freebsd-arm64": {
+      "version": "4.34.8",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz",
+      "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ]
+    },
+    "node_modules/@rollup/rollup-freebsd-x64": {
+      "version": "4.34.8",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz",
+      "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+      "version": "4.34.8",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz",
+      "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+      "version": "4.34.8",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz",
+      "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm64-gnu": {
+      "version": "4.34.8",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz",
+      "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm64-musl": {
+      "version": "4.34.8",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz",
+      "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-loong64-gnu": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.57.1.tgz",
+      "integrity": "sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==",
+      "cpu": [
+        "loong64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-loong64-musl": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.57.1.tgz",
+      "integrity": "sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==",
+      "cpu": [
+        "loong64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
+      "version": "4.34.8",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz",
+      "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==",
+      "cpu": [
+        "loong64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+      "version": "4.34.8",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz",
+      "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.57.1.tgz",
+      "integrity": "sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-ppc64-musl": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.57.1.tgz",
+      "integrity": "sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+      "version": "4.34.8",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz",
+      "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-riscv64-musl": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.57.1.tgz",
+      "integrity": "sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-s390x-gnu": {
+      "version": "4.34.8",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz",
+      "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-x64-gnu": {
+      "version": "4.34.8",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz",
+      "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-x64-musl": {
+      "version": "4.34.8",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz",
+      "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-openbsd-x64": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.57.1.tgz",
+      "integrity": "sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "openbsd"
+      ]
+    },
+    "node_modules/@rollup/rollup-openharmony-arm64": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.57.1.tgz",
+      "integrity": "sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "openharmony"
+      ]
+    },
+    "node_modules/@rollup/rollup-win32-arm64-msvc": {
+      "version": "4.34.8",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz",
+      "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@rollup/rollup-win32-ia32-msvc": {
+      "version": "4.34.8",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz",
+      "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@rollup/rollup-win32-x64-gnu": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.57.1.tgz",
+      "integrity": "sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@rollup/rollup-win32-x64-msvc": {
+      "version": "4.34.8",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz",
+      "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@schematics/angular": {
+      "version": "19.2.19",
+      "resolved": "https://registry.npmmirror.com/@schematics/angular/-/angular-19.2.19.tgz",
+      "integrity": "sha512-6/0pvbPCY4UHeB4lnM/5r250QX5gcLgOYbR5FdhFu+22mOPHfWpRc5tNuY9kCephDHzAHjo6fTW1vefOOmA4jw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@angular-devkit/core": "19.2.19",
+        "@angular-devkit/schematics": "19.2.19",
+        "jsonc-parser": "3.3.1"
+      },
+      "engines": {
+        "node": "^18.19.1 || ^20.11.1 || >=22.0.0",
+        "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+        "yarn": ">= 1.13.0"
+      }
+    },
+    "node_modules/@schematics/angular/node_modules/@angular-devkit/core": {
+      "version": "19.2.19",
+      "resolved": "https://registry.npmmirror.com/@angular-devkit/core/-/core-19.2.19.tgz",
+      "integrity": "sha512-JbLL+4IMLMBgjLZlnPG4lYDfz4zGrJ/s6Aoon321NJKuw1Kb1k5KpFu9dUY0BqLIe8xPQ2UJBpI+xXdK5MXMHQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ajv": "8.17.1",
+        "ajv-formats": "3.0.1",
+        "jsonc-parser": "3.3.1",
+        "picomatch": "4.0.2",
+        "rxjs": "7.8.1",
+        "source-map": "0.7.4"
+      },
+      "engines": {
+        "node": "^18.19.1 || ^20.11.1 || >=22.0.0",
+        "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+        "yarn": ">= 1.13.0"
+      },
+      "peerDependencies": {
+        "chokidar": "^4.0.0"
+      },
+      "peerDependenciesMeta": {
+        "chokidar": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@schematics/angular/node_modules/chokidar": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-4.0.3.tgz",
+      "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "readdirp": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 14.16.0"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/@schematics/angular/node_modules/readdirp": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-4.1.2.tgz",
+      "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "peer": true,
+      "engines": {
+        "node": ">= 14.18.0"
+      },
+      "funding": {
+        "type": "individual",
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/@schematics/angular/node_modules/rxjs": {
+      "version": "7.8.1",
+      "resolved": "https://registry.npmmirror.com/rxjs/-/rxjs-7.8.1.tgz",
+      "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "tslib": "^2.1.0"
+      }
+    },
+    "node_modules/@sigstore/bundle": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/@sigstore/bundle/-/bundle-3.1.0.tgz",
+      "integrity": "sha512-Mm1E3/CmDDCz3nDhFKTuYdB47EdRFRQMOE/EAbiG1MJW77/w1b3P7Qx7JSrVJs8PfwOLOVcKQCHErIwCTyPbag==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@sigstore/protobuf-specs": "^0.4.0"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/@sigstore/core": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/@sigstore/core/-/core-2.0.0.tgz",
+      "integrity": "sha512-nYxaSb/MtlSI+JWcwTHQxyNmWeWrUXJJ/G4liLrGG7+tS4vAz6LF3xRXqLH6wPIVUoZQel2Fs4ddLx4NCpiIYg==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/@sigstore/protobuf-specs": {
+      "version": "0.4.3",
+      "resolved": "https://registry.npmmirror.com/@sigstore/protobuf-specs/-/protobuf-specs-0.4.3.tgz",
+      "integrity": "sha512-fk2zjD9117RL9BjqEwF7fwv7Q/P9yGsMV4MUJZ/DocaQJ6+3pKr+syBq1owU5Q5qGw5CUbXzm+4yJ2JVRDQeSA==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/@sigstore/sign": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/@sigstore/sign/-/sign-3.1.0.tgz",
+      "integrity": "sha512-knzjmaOHOov1Ur7N/z4B1oPqZ0QX5geUfhrVaqVlu+hl0EAoL4o+l0MSULINcD5GCWe3Z0+YJO8ues6vFlW0Yw==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@sigstore/bundle": "^3.1.0",
+        "@sigstore/core": "^2.0.0",
+        "@sigstore/protobuf-specs": "^0.4.0",
+        "make-fetch-happen": "^14.0.2",
+        "proc-log": "^5.0.0",
+        "promise-retry": "^2.0.1"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/@sigstore/tuf": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmmirror.com/@sigstore/tuf/-/tuf-3.1.1.tgz",
+      "integrity": "sha512-eFFvlcBIoGwVkkwmTi/vEQFSva3xs5Ot3WmBcjgjVdiaoelBLQaQ/ZBfhlG0MnG0cmTYScPpk7eDdGDWUcFUmg==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@sigstore/protobuf-specs": "^0.4.1",
+        "tuf-js": "^3.0.1"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/@sigstore/verify": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/@sigstore/verify/-/verify-2.1.1.tgz",
+      "integrity": "sha512-hVJD77oT67aowHxwT4+M6PGOp+E2LtLdTK3+FC0lBO9T7sYwItDMXZ7Z07IDCvR1M717a4axbIWckrW67KMP/w==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@sigstore/bundle": "^3.1.0",
+        "@sigstore/core": "^2.0.0",
+        "@sigstore/protobuf-specs": "^0.4.1"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/@sindresorhus/merge-streams": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz",
+      "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@socket.io/component-emitter": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmmirror.com/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
+      "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@tufjs/canonical-json": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz",
+      "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "^16.14.0 || >=18.0.0"
+      }
+    },
+    "node_modules/@tufjs/models": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/@tufjs/models/-/models-3.0.1.tgz",
+      "integrity": "sha512-UUYHISyhCU3ZgN8yaear3cGATHb3SMuKHsQ/nVbHXcmnBf+LzQ/cQfhNG+rfaSHgqGKNEm2cOCLVLELStUQ1JA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@tufjs/canonical-json": "2.0.0",
+        "minimatch": "^9.0.5"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/@tufjs/models/node_modules/brace-expansion": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.2.tgz",
+      "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
+    "node_modules/@tufjs/models/node_modules/minimatch": {
+      "version": "9.0.5",
+      "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz",
+      "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/@types/body-parser": {
+      "version": "1.19.6",
+      "resolved": "https://registry.npmmirror.com/@types/body-parser/-/body-parser-1.19.6.tgz",
+      "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/connect": "*",
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/bonjour": {
+      "version": "3.5.13",
+      "resolved": "https://registry.npmmirror.com/@types/bonjour/-/bonjour-3.5.13.tgz",
+      "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/connect": {
+      "version": "3.4.38",
+      "resolved": "https://registry.npmmirror.com/@types/connect/-/connect-3.4.38.tgz",
+      "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/connect-history-api-fallback": {
+      "version": "1.5.4",
+      "resolved": "https://registry.npmmirror.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz",
+      "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/express-serve-static-core": "*",
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/cors": {
+      "version": "2.8.19",
+      "resolved": "https://registry.npmmirror.com/@types/cors/-/cors-2.8.19.tgz",
+      "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/eslint": {
+      "version": "9.6.1",
+      "resolved": "https://registry.npmmirror.com/@types/eslint/-/eslint-9.6.1.tgz",
+      "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/estree": "*",
+        "@types/json-schema": "*"
+      }
+    },
+    "node_modules/@types/eslint-scope": {
+      "version": "3.7.7",
+      "resolved": "https://registry.npmmirror.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
+      "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/eslint": "*",
+        "@types/estree": "*"
+      }
+    },
+    "node_modules/@types/estree": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.6.tgz",
+      "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@types/express": {
+      "version": "4.17.25",
+      "resolved": "https://registry.npmmirror.com/@types/express/-/express-4.17.25.tgz",
+      "integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/body-parser": "*",
+        "@types/express-serve-static-core": "^4.17.33",
+        "@types/qs": "*",
+        "@types/serve-static": "^1"
+      }
+    },
+    "node_modules/@types/express-serve-static-core": {
+      "version": "4.19.8",
+      "resolved": "https://registry.npmmirror.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.8.tgz",
+      "integrity": "sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/node": "*",
+        "@types/qs": "*",
+        "@types/range-parser": "*",
+        "@types/send": "*"
+      }
+    },
+    "node_modules/@types/http-errors": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmmirror.com/@types/http-errors/-/http-errors-2.0.5.tgz",
+      "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@types/http-proxy": {
+      "version": "1.17.17",
+      "resolved": "https://registry.npmmirror.com/@types/http-proxy/-/http-proxy-1.17.17.tgz",
+      "integrity": "sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/jasmine": {
+      "version": "5.1.15",
+      "resolved": "https://registry.npmmirror.com/@types/jasmine/-/jasmine-5.1.15.tgz",
+      "integrity": "sha512-ZAC8KjmV2MJxbNTrwXFN+HKeajpXQZp6KpPiR6Aa4XvaEnjP6qh23lL/Rqb7AYzlp3h/rcwDrQ7Gg7q28cQTQg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@types/json-schema": {
+      "version": "7.0.15",
+      "resolved": "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.15.tgz",
+      "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@types/mime": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmmirror.com/@types/mime/-/mime-1.3.5.tgz",
+      "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@types/node": {
+      "version": "22.19.11",
+      "resolved": "https://registry.npmmirror.com/@types/node/-/node-22.19.11.tgz",
+      "integrity": "sha512-BH7YwL6rA93ReqeQS1c4bsPpcfOmJasG+Fkr6Y59q83f9M1WcBRHR2vM+P9eOisYRcN3ujQoiZY8uk5W+1WL8w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "undici-types": "~6.21.0"
+      }
+    },
+    "node_modules/@types/node-forge": {
+      "version": "1.3.14",
+      "resolved": "https://registry.npmmirror.com/@types/node-forge/-/node-forge-1.3.14.tgz",
+      "integrity": "sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/qs": {
+      "version": "6.14.0",
+      "resolved": "https://registry.npmmirror.com/@types/qs/-/qs-6.14.0.tgz",
+      "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@types/range-parser": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npmmirror.com/@types/range-parser/-/range-parser-1.2.7.tgz",
+      "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@types/retry": {
+      "version": "0.12.2",
+      "resolved": "https://registry.npmmirror.com/@types/retry/-/retry-0.12.2.tgz",
+      "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@types/send": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/@types/send/-/send-1.2.1.tgz",
+      "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/serve-index": {
+      "version": "1.9.4",
+      "resolved": "https://registry.npmmirror.com/@types/serve-index/-/serve-index-1.9.4.tgz",
+      "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/express": "*"
+      }
+    },
+    "node_modules/@types/serve-static": {
+      "version": "1.15.10",
+      "resolved": "https://registry.npmmirror.com/@types/serve-static/-/serve-static-1.15.10.tgz",
+      "integrity": "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/http-errors": "*",
+        "@types/node": "*",
+        "@types/send": "<1"
+      }
+    },
+    "node_modules/@types/serve-static/node_modules/@types/send": {
+      "version": "0.17.6",
+      "resolved": "https://registry.npmmirror.com/@types/send/-/send-0.17.6.tgz",
+      "integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/mime": "^1",
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/sockjs": {
+      "version": "0.3.36",
+      "resolved": "https://registry.npmmirror.com/@types/sockjs/-/sockjs-0.3.36.tgz",
+      "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/ws": {
+      "version": "8.18.1",
+      "resolved": "https://registry.npmmirror.com/@types/ws/-/ws-8.18.1.tgz",
+      "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@vitejs/plugin-basic-ssl": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.2.0.tgz",
+      "integrity": "sha512-mkQnxTkcldAzIsomk1UuLfAu9n+kpQ3JbHcpCp7d2Oo6ITtji8pHS3QToOWjhPFvNQSnhlkAjmGbhv2QvwO/7Q==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=14.21.3"
+      },
+      "peerDependencies": {
+        "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0"
+      }
+    },
+    "node_modules/@webassemblyjs/ast": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/ast/-/ast-1.14.1.tgz",
+      "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@webassemblyjs/helper-numbers": "1.13.2",
+        "@webassemblyjs/helper-wasm-bytecode": "1.13.2"
+      }
+    },
+    "node_modules/@webassemblyjs/floating-point-hex-parser": {
+      "version": "1.13.2",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz",
+      "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@webassemblyjs/helper-api-error": {
+      "version": "1.13.2",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz",
+      "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@webassemblyjs/helper-buffer": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz",
+      "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@webassemblyjs/helper-numbers": {
+      "version": "1.13.2",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz",
+      "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@webassemblyjs/floating-point-hex-parser": "1.13.2",
+        "@webassemblyjs/helper-api-error": "1.13.2",
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "node_modules/@webassemblyjs/helper-wasm-bytecode": {
+      "version": "1.13.2",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz",
+      "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@webassemblyjs/helper-wasm-section": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz",
+      "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@webassemblyjs/ast": "1.14.1",
+        "@webassemblyjs/helper-buffer": "1.14.1",
+        "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+        "@webassemblyjs/wasm-gen": "1.14.1"
+      }
+    },
+    "node_modules/@webassemblyjs/ieee754": {
+      "version": "1.13.2",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz",
+      "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@xtuc/ieee754": "^1.2.0"
+      }
+    },
+    "node_modules/@webassemblyjs/leb128": {
+      "version": "1.13.2",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/leb128/-/leb128-1.13.2.tgz",
+      "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "node_modules/@webassemblyjs/utf8": {
+      "version": "1.13.2",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/utf8/-/utf8-1.13.2.tgz",
+      "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@webassemblyjs/wasm-edit": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz",
+      "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@webassemblyjs/ast": "1.14.1",
+        "@webassemblyjs/helper-buffer": "1.14.1",
+        "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+        "@webassemblyjs/helper-wasm-section": "1.14.1",
+        "@webassemblyjs/wasm-gen": "1.14.1",
+        "@webassemblyjs/wasm-opt": "1.14.1",
+        "@webassemblyjs/wasm-parser": "1.14.1",
+        "@webassemblyjs/wast-printer": "1.14.1"
+      }
+    },
+    "node_modules/@webassemblyjs/wasm-gen": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz",
+      "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@webassemblyjs/ast": "1.14.1",
+        "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+        "@webassemblyjs/ieee754": "1.13.2",
+        "@webassemblyjs/leb128": "1.13.2",
+        "@webassemblyjs/utf8": "1.13.2"
+      }
+    },
+    "node_modules/@webassemblyjs/wasm-opt": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz",
+      "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@webassemblyjs/ast": "1.14.1",
+        "@webassemblyjs/helper-buffer": "1.14.1",
+        "@webassemblyjs/wasm-gen": "1.14.1",
+        "@webassemblyjs/wasm-parser": "1.14.1"
+      }
+    },
+    "node_modules/@webassemblyjs/wasm-parser": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz",
+      "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@webassemblyjs/ast": "1.14.1",
+        "@webassemblyjs/helper-api-error": "1.13.2",
+        "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+        "@webassemblyjs/ieee754": "1.13.2",
+        "@webassemblyjs/leb128": "1.13.2",
+        "@webassemblyjs/utf8": "1.13.2"
+      }
+    },
+    "node_modules/@webassemblyjs/wast-printer": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz",
+      "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@webassemblyjs/ast": "1.14.1",
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "node_modules/@xtuc/ieee754": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+      "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+      "dev": true,
+      "license": "BSD-3-Clause"
+    },
+    "node_modules/@xtuc/long": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmmirror.com/@xtuc/long/-/long-4.2.2.tgz",
+      "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+      "dev": true,
+      "license": "Apache-2.0"
+    },
+    "node_modules/@yarnpkg/lockfile": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz",
+      "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==",
+      "dev": true,
+      "license": "BSD-2-Clause"
+    },
+    "node_modules/abbrev": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/abbrev/-/abbrev-3.0.1.tgz",
+      "integrity": "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/accepts": {
+      "version": "1.3.8",
+      "resolved": "https://registry.npmmirror.com/accepts/-/accepts-1.3.8.tgz",
+      "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "mime-types": "~2.1.34",
+        "negotiator": "0.6.3"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/accepts/node_modules/negotiator": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.3.tgz",
+      "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/acorn": {
+      "version": "8.15.0",
+      "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.15.0.tgz",
+      "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "acorn": "bin/acorn"
+      },
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/adjust-sourcemap-loader": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz",
+      "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "loader-utils": "^2.0.0",
+        "regex-parser": "^2.2.11"
+      },
+      "engines": {
+        "node": ">=8.9"
+      }
+    },
+    "node_modules/adjust-sourcemap-loader/node_modules/loader-utils": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz",
+      "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "big.js": "^5.2.2",
+        "emojis-list": "^3.0.0",
+        "json5": "^2.1.2"
+      },
+      "engines": {
+        "node": ">=8.9.0"
+      }
+    },
+    "node_modules/agent-base": {
+      "version": "7.1.4",
+      "resolved": "https://registry.npmmirror.com/agent-base/-/agent-base-7.1.4.tgz",
+      "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 14"
+      }
+    },
+    "node_modules/ajv": {
+      "version": "8.17.1",
+      "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.17.1.tgz",
+      "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "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/ajv-formats": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/ajv-formats/-/ajv-formats-3.0.1.tgz",
+      "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ajv": "^8.0.0"
+      },
+      "peerDependencies": {
+        "ajv": "^8.0.0"
+      },
+      "peerDependenciesMeta": {
+        "ajv": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/ajv-keywords": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+      "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "fast-deep-equal": "^3.1.3"
+      },
+      "peerDependencies": {
+        "ajv": "^8.8.2"
+      }
+    },
+    "node_modules/ansi-colors": {
+      "version": "4.1.3",
+      "resolved": "https://registry.npmmirror.com/ansi-colors/-/ansi-colors-4.1.3.tgz",
+      "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/ansi-escapes": {
+      "version": "7.3.0",
+      "resolved": "https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-7.3.0.tgz",
+      "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "environment": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/ansi-html-community": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmmirror.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz",
+      "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==",
+      "dev": true,
+      "engines": [
+        "node >= 0.8.0"
+      ],
+      "license": "Apache-2.0",
+      "bin": {
+        "ansi-html": "bin/ansi-html"
+      }
+    },
+    "node_modules/ansi-regex": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz",
+      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/anymatch": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz",
+      "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "normalize-path": "^3.0.0",
+        "picomatch": "^2.0.4"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/anymatch/node_modules/picomatch": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz",
+      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/argparse": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz",
+      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+      "dev": true,
+      "license": "Python-2.0"
+    },
+    "node_modules/array-flatten": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/array-flatten/-/array-flatten-1.1.1.tgz",
+      "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/autoprefixer": {
+      "version": "10.4.20",
+      "resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.20.tgz",
+      "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/autoprefixer"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "browserslist": "^4.23.3",
+        "caniuse-lite": "^1.0.30001646",
+        "fraction.js": "^4.3.7",
+        "normalize-range": "^0.1.2",
+        "picocolors": "^1.0.1",
+        "postcss-value-parser": "^4.2.0"
+      },
+      "bin": {
+        "autoprefixer": "bin/autoprefixer"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      },
+      "peerDependencies": {
+        "postcss": "^8.1.0"
+      }
+    },
+    "node_modules/babel-loader": {
+      "version": "9.2.1",
+      "resolved": "https://registry.npmmirror.com/babel-loader/-/babel-loader-9.2.1.tgz",
+      "integrity": "sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "find-cache-dir": "^4.0.0",
+        "schema-utils": "^4.0.0"
+      },
+      "engines": {
+        "node": ">= 14.15.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.12.0",
+        "webpack": ">=5"
+      }
+    },
+    "node_modules/babel-plugin-polyfill-corejs2": {
+      "version": "0.4.15",
+      "resolved": "https://registry.npmmirror.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.15.tgz",
+      "integrity": "sha512-hR3GwrRwHUfYwGfrisXPIDP3JcYfBrW7wKE7+Au6wDYl7fm/ka1NEII6kORzxNU556JjfidZeBsO10kYvtV1aw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/compat-data": "^7.28.6",
+        "@babel/helper-define-polyfill-provider": "^0.6.6",
+        "semver": "^6.3.1"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+      }
+    },
+    "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/babel-plugin-polyfill-corejs3": {
+      "version": "0.11.1",
+      "resolved": "https://registry.npmmirror.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz",
+      "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-define-polyfill-provider": "^0.6.3",
+        "core-js-compat": "^3.40.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+      }
+    },
+    "node_modules/babel-plugin-polyfill-regenerator": {
+      "version": "0.6.6",
+      "resolved": "https://registry.npmmirror.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.6.tgz",
+      "integrity": "sha512-hYm+XLYRMvupxiQzrvXUj7YyvFFVfv5gI0R71AJzudg1g2AI2vyCPPIFEBjk162/wFzti3inBHo7isWFuEVS/A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-define-polyfill-provider": "^0.6.6"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+      }
+    },
+    "node_modules/balanced-match": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
+      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/base64-js": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz",
+      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+      "dev": true,
+      "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/base64id": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/base64id/-/base64id-2.0.0.tgz",
+      "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "^4.5.0 || >= 5.9"
+      }
+    },
+    "node_modules/baseline-browser-mapping": {
+      "version": "2.9.19",
+      "resolved": "https://registry.npmmirror.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz",
+      "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "bin": {
+        "baseline-browser-mapping": "dist/cli.js"
+      }
+    },
+    "node_modules/batch": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmmirror.com/batch/-/batch-0.6.1.tgz",
+      "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/beasties": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmmirror.com/beasties/-/beasties-0.3.2.tgz",
+      "integrity": "sha512-p4AF8uYzm9Fwu8m/hSVTCPXrRBPmB34hQpHsec2KOaR9CZmgoU8IOv4Cvwq4hgz2p4hLMNbsdNl5XeA6XbAQwA==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "css-select": "^5.1.0",
+        "css-what": "^6.1.0",
+        "dom-serializer": "^2.0.0",
+        "domhandler": "^5.0.3",
+        "htmlparser2": "^10.0.0",
+        "picocolors": "^1.1.1",
+        "postcss": "^8.4.49",
+        "postcss-media-query-parser": "^0.2.3"
+      },
+      "engines": {
+        "node": ">=14.0.0"
+      }
+    },
+    "node_modules/big.js": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npmmirror.com/big.js/-/big.js-5.2.2.tgz",
+      "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/binary-extensions": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz",
+      "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/bl": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz",
+      "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "buffer": "^5.5.0",
+        "inherits": "^2.0.4",
+        "readable-stream": "^3.4.0"
+      }
+    },
+    "node_modules/body-parser": {
+      "version": "1.20.4",
+      "resolved": "https://registry.npmmirror.com/body-parser/-/body-parser-1.20.4.tgz",
+      "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "bytes": "~3.1.2",
+        "content-type": "~1.0.5",
+        "debug": "2.6.9",
+        "depd": "2.0.0",
+        "destroy": "~1.2.0",
+        "http-errors": "~2.0.1",
+        "iconv-lite": "~0.4.24",
+        "on-finished": "~2.4.1",
+        "qs": "~6.14.0",
+        "raw-body": "~2.5.3",
+        "type-is": "~1.6.18",
+        "unpipe": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8",
+        "npm": "1.2.8000 || >= 1.4.16"
+      }
+    },
+    "node_modules/body-parser/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/body-parser/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/bonjour-service": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/bonjour-service/-/bonjour-service-1.3.0.tgz",
+      "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "fast-deep-equal": "^3.1.3",
+        "multicast-dns": "^7.2.5"
+      }
+    },
+    "node_modules/boolbase": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/boolbase/-/boolbase-1.0.0.tgz",
+      "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/brace-expansion": {
+      "version": "1.1.12",
+      "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.12.tgz",
+      "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "node_modules/braces": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.3.tgz",
+      "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "fill-range": "^7.1.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/browserslist": {
+      "version": "4.28.1",
+      "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.28.1.tgz",
+      "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "baseline-browser-mapping": "^2.9.0",
+        "caniuse-lite": "^1.0.30001759",
+        "electron-to-chromium": "^1.5.263",
+        "node-releases": "^2.0.27",
+        "update-browserslist-db": "^1.2.0"
+      },
+      "bin": {
+        "browserslist": "cli.js"
+      },
+      "engines": {
+        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+      }
+    },
+    "node_modules/buffer": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmmirror.com/buffer/-/buffer-5.7.1.tgz",
+      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+      "dev": true,
+      "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",
+      "dependencies": {
+        "base64-js": "^1.3.1",
+        "ieee754": "^1.1.13"
+      }
+    },
+    "node_modules/buffer-from": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz",
+      "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/bundle-name": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/bundle-name/-/bundle-name-4.1.0.tgz",
+      "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "run-applescript": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/bytes": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmmirror.com/bytes/-/bytes-3.1.2.tgz",
+      "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/cacache": {
+      "version": "19.0.1",
+      "resolved": "https://registry.npmmirror.com/cacache/-/cacache-19.0.1.tgz",
+      "integrity": "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "@npmcli/fs": "^4.0.0",
+        "fs-minipass": "^3.0.0",
+        "glob": "^10.2.2",
+        "lru-cache": "^10.0.1",
+        "minipass": "^7.0.3",
+        "minipass-collect": "^2.0.1",
+        "minipass-flush": "^1.0.5",
+        "minipass-pipeline": "^1.2.4",
+        "p-map": "^7.0.2",
+        "ssri": "^12.0.0",
+        "tar": "^7.4.3",
+        "unique-filename": "^4.0.0"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/cacache/node_modules/brace-expansion": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.2.tgz",
+      "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
+    "node_modules/cacache/node_modules/chownr": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/chownr/-/chownr-3.0.0.tgz",
+      "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/cacache/node_modules/glob": {
+      "version": "10.4.5",
+      "resolved": "https://registry.npmmirror.com/glob/-/glob-10.4.5.tgz",
+      "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "foreground-child": "^3.1.0",
+        "jackspeak": "^3.1.2",
+        "minimatch": "^9.0.4",
+        "minipass": "^7.1.2",
+        "package-json-from-dist": "^1.0.0",
+        "path-scurry": "^1.11.1"
+      },
+      "bin": {
+        "glob": "dist/esm/bin.mjs"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/cacache/node_modules/lru-cache": {
+      "version": "10.4.3",
+      "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.4.3.tgz",
+      "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/cacache/node_modules/minimatch": {
+      "version": "9.0.5",
+      "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz",
+      "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/cacache/node_modules/tar": {
+      "version": "7.5.7",
+      "resolved": "https://registry.npmmirror.com/tar/-/tar-7.5.7.tgz",
+      "integrity": "sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "dependencies": {
+        "@isaacs/fs-minipass": "^4.0.0",
+        "chownr": "^3.0.0",
+        "minipass": "^7.1.2",
+        "minizlib": "^3.1.0",
+        "yallist": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/cacache/node_modules/yallist": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/yallist/-/yallist-5.0.0.tgz",
+      "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/call-bind-apply-helpers": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+      "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "function-bind": "^1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/call-bound": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmmirror.com/call-bound/-/call-bound-1.0.4.tgz",
+      "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind-apply-helpers": "^1.0.2",
+        "get-intrinsic": "^1.3.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/callsites": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz",
+      "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/caniuse-lite": {
+      "version": "1.0.30001769",
+      "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz",
+      "integrity": "sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "CC-BY-4.0"
+    },
+    "node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/chardet": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/chardet/-/chardet-2.1.1.tgz",
+      "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/chokidar": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz",
+      "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "anymatch": "~3.1.2",
+        "braces": "~3.0.2",
+        "glob-parent": "~5.1.2",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.6.0"
+      },
+      "engines": {
+        "node": ">= 8.10.0"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/chokidar/node_modules/glob-parent": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz",
+      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "is-glob": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/chownr": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/chownr/-/chownr-2.0.0.tgz",
+      "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/chrome-trace-event": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmmirror.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz",
+      "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.0"
+      }
+    },
+    "node_modules/cli-cursor": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/cli-cursor/-/cli-cursor-5.0.0.tgz",
+      "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "restore-cursor": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/cli-spinners": {
+      "version": "2.9.2",
+      "resolved": "https://registry.npmmirror.com/cli-spinners/-/cli-spinners-2.9.2.tgz",
+      "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/cli-truncate": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/cli-truncate/-/cli-truncate-4.0.0.tgz",
+      "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "slice-ansi": "^5.0.0",
+        "string-width": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/cli-width": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/cli-width/-/cli-width-4.1.0.tgz",
+      "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": ">= 12"
+      }
+    },
+    "node_modules/cliui": {
+      "version": "8.0.1",
+      "resolved": "https://registry.npmmirror.com/cliui/-/cliui-8.0.1.tgz",
+      "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.1",
+        "wrap-ansi": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/cliui/node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/cliui/node_modules/is-fullwidth-code-point": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/cliui/node_modules/string-width": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+      "dev": true,
+      "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/cliui/node_modules/wrap-ansi": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+      "dev": true,
+      "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/clone": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmmirror.com/clone/-/clone-1.0.4.tgz",
+      "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/clone-deep": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmmirror.com/clone-deep/-/clone-deep-4.0.1.tgz",
+      "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-plain-object": "^2.0.4",
+        "kind-of": "^6.0.2",
+        "shallow-clone": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/clone-deep/node_modules/is-plain-object": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmmirror.com/is-plain-object/-/is-plain-object-2.0.4.tgz",
+      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "isobject": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/colorette": {
+      "version": "2.0.20",
+      "resolved": "https://registry.npmmirror.com/colorette/-/colorette-2.0.20.tgz",
+      "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/commander": {
+      "version": "2.20.3",
+      "resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz",
+      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/common-path-prefix": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz",
+      "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/compressible": {
+      "version": "2.0.18",
+      "resolved": "https://registry.npmmirror.com/compressible/-/compressible-2.0.18.tgz",
+      "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "mime-db": ">= 1.43.0 < 2"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/compression": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmmirror.com/compression/-/compression-1.8.1.tgz",
+      "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "bytes": "3.1.2",
+        "compressible": "~2.0.18",
+        "debug": "2.6.9",
+        "negotiator": "~0.6.4",
+        "on-headers": "~1.1.0",
+        "safe-buffer": "5.2.1",
+        "vary": "~1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/compression/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/compression/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/compression/node_modules/negotiator": {
+      "version": "0.6.4",
+      "resolved": "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.4.tgz",
+      "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/connect": {
+      "version": "3.7.0",
+      "resolved": "https://registry.npmmirror.com/connect/-/connect-3.7.0.tgz",
+      "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "debug": "2.6.9",
+        "finalhandler": "1.1.2",
+        "parseurl": "~1.3.3",
+        "utils-merge": "1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.10.0"
+      }
+    },
+    "node_modules/connect-history-api-fallback": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz",
+      "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/connect/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/connect/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/content-disposition": {
+      "version": "0.5.4",
+      "resolved": "https://registry.npmmirror.com/content-disposition/-/content-disposition-0.5.4.tgz",
+      "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "safe-buffer": "5.2.1"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/content-type": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmmirror.com/content-type/-/content-type-1.0.5.tgz",
+      "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/convert-source-map": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-1.9.0.tgz",
+      "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/cookie": {
+      "version": "0.7.2",
+      "resolved": "https://registry.npmmirror.com/cookie/-/cookie-0.7.2.tgz",
+      "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/cookie-signature": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmmirror.com/cookie-signature/-/cookie-signature-1.0.7.tgz",
+      "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/copy-anything": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmmirror.com/copy-anything/-/copy-anything-2.0.6.tgz",
+      "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-what": "^3.14.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/mesqueeb"
+      }
+    },
+    "node_modules/copy-webpack-plugin": {
+      "version": "12.0.2",
+      "resolved": "https://registry.npmmirror.com/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz",
+      "integrity": "sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "fast-glob": "^3.3.2",
+        "glob-parent": "^6.0.1",
+        "globby": "^14.0.0",
+        "normalize-path": "^3.0.0",
+        "schema-utils": "^4.2.0",
+        "serialize-javascript": "^6.0.2"
+      },
+      "engines": {
+        "node": ">= 18.12.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "webpack": "^5.1.0"
+      }
+    },
+    "node_modules/core-js-compat": {
+      "version": "3.48.0",
+      "resolved": "https://registry.npmmirror.com/core-js-compat/-/core-js-compat-3.48.0.tgz",
+      "integrity": "sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "browserslist": "^4.28.1"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/core-js"
+      }
+    },
+    "node_modules/core-util-is": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz",
+      "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/cors": {
+      "version": "2.8.6",
+      "resolved": "https://registry.npmmirror.com/cors/-/cors-2.8.6.tgz",
+      "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "object-assign": "^4",
+        "vary": "^1"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/express"
+      }
+    },
+    "node_modules/cosmiconfig": {
+      "version": "9.0.0",
+      "resolved": "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-9.0.0.tgz",
+      "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "env-paths": "^2.2.1",
+        "import-fresh": "^3.3.0",
+        "js-yaml": "^4.1.0",
+        "parse-json": "^5.2.0"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/d-fischer"
+      },
+      "peerDependencies": {
+        "typescript": ">=4.9.5"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/cross-spawn": {
+      "version": "7.0.6",
+      "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz",
+      "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "path-key": "^3.1.0",
+        "shebang-command": "^2.0.0",
+        "which": "^2.0.1"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/cross-spawn/node_modules/which": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz",
+      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "node-which": "bin/node-which"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/css-loader": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmmirror.com/css-loader/-/css-loader-7.1.2.tgz",
+      "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "icss-utils": "^5.1.0",
+        "postcss": "^8.4.33",
+        "postcss-modules-extract-imports": "^3.1.0",
+        "postcss-modules-local-by-default": "^4.0.5",
+        "postcss-modules-scope": "^3.2.0",
+        "postcss-modules-values": "^4.0.0",
+        "postcss-value-parser": "^4.2.0",
+        "semver": "^7.5.4"
+      },
+      "engines": {
+        "node": ">= 18.12.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "@rspack/core": "0.x || 1.x",
+        "webpack": "^5.27.0"
+      },
+      "peerDependenciesMeta": {
+        "@rspack/core": {
+          "optional": true
+        },
+        "webpack": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/css-select": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npmmirror.com/css-select/-/css-select-5.2.2.tgz",
+      "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "boolbase": "^1.0.0",
+        "css-what": "^6.1.0",
+        "domhandler": "^5.0.2",
+        "domutils": "^3.0.1",
+        "nth-check": "^2.0.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/fb55"
+      }
+    },
+    "node_modules/css-what": {
+      "version": "6.2.2",
+      "resolved": "https://registry.npmmirror.com/css-what/-/css-what-6.2.2.tgz",
+      "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">= 6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/fb55"
+      }
+    },
+    "node_modules/cssesc": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz",
+      "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "cssesc": "bin/cssesc"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/custom-event": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/custom-event/-/custom-event-1.0.1.tgz",
+      "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/date-format": {
+      "version": "4.0.14",
+      "resolved": "https://registry.npmmirror.com/date-format/-/date-format-4.0.14.tgz",
+      "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/debug": {
+      "version": "4.4.3",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz",
+      "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ms": "^2.1.3"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/default-browser": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmmirror.com/default-browser/-/default-browser-5.5.0.tgz",
+      "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "bundle-name": "^4.1.0",
+        "default-browser-id": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/default-browser-id": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmmirror.com/default-browser-id/-/default-browser-id-5.0.1.tgz",
+      "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/defaults": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmmirror.com/defaults/-/defaults-1.0.4.tgz",
+      "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "clone": "^1.0.2"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/define-lazy-prop": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
+      "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/depd": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz",
+      "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/destroy": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/destroy/-/destroy-1.2.0.tgz",
+      "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8",
+        "npm": "1.2.8000 || >= 1.4.16"
+      }
+    },
+    "node_modules/detect-libc": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.1.2.tgz",
+      "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "optional": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/detect-node": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/detect-node/-/detect-node-2.1.0.tgz",
+      "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/di": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmmirror.com/di/-/di-0.0.1.tgz",
+      "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/dns-packet": {
+      "version": "5.6.1",
+      "resolved": "https://registry.npmmirror.com/dns-packet/-/dns-packet-5.6.1.tgz",
+      "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@leichtgewicht/ip-codec": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/dom-serialize": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmmirror.com/dom-serialize/-/dom-serialize-2.2.1.tgz",
+      "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "custom-event": "~1.0.0",
+        "ent": "~2.2.0",
+        "extend": "^3.0.0",
+        "void-elements": "^2.0.0"
+      }
+    },
+    "node_modules/dom-serializer": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/dom-serializer/-/dom-serializer-2.0.0.tgz",
+      "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.2",
+        "entities": "^4.2.0"
+      },
+      "funding": {
+        "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+      }
+    },
+    "node_modules/domelementtype": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/domelementtype/-/domelementtype-2.3.0.tgz",
+      "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fb55"
+        }
+      ],
+      "license": "BSD-2-Clause"
+    },
+    "node_modules/domhandler": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmmirror.com/domhandler/-/domhandler-5.0.3.tgz",
+      "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "domelementtype": "^2.3.0"
+      },
+      "engines": {
+        "node": ">= 4"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/domhandler?sponsor=1"
+      }
+    },
+    "node_modules/domutils": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmmirror.com/domutils/-/domutils-3.2.2.tgz",
+      "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "dom-serializer": "^2.0.0",
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.3"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/domutils?sponsor=1"
+      }
+    },
+    "node_modules/dunder-proto": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",
+      "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind-apply-helpers": "^1.0.1",
+        "es-errors": "^1.3.0",
+        "gopd": "^1.2.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/eastasianwidth": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmmirror.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+      "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/ee-first": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz",
+      "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/electron-to-chromium": {
+      "version": "1.5.286",
+      "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz",
+      "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/emoji-regex": {
+      "version": "10.6.0",
+      "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-10.6.0.tgz",
+      "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/emojis-list": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/emojis-list/-/emojis-list-3.0.0.tgz",
+      "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/encodeurl": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-1.0.2.tgz",
+      "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/encoding": {
+      "version": "0.1.13",
+      "resolved": "https://registry.npmmirror.com/encoding/-/encoding-0.1.13.tgz",
+      "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "iconv-lite": "^0.6.2"
+      }
+    },
+    "node_modules/encoding/node_modules/iconv-lite": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz",
+      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/engine.io": {
+      "version": "6.6.5",
+      "resolved": "https://registry.npmmirror.com/engine.io/-/engine.io-6.6.5.tgz",
+      "integrity": "sha512-2RZdgEbXmp5+dVbRm0P7HQUImZpICccJy7rN7Tv+SFa55pH+lxnuw6/K1ZxxBfHoYpSkHLAO92oa8O4SwFXA2A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/cors": "^2.8.12",
+        "@types/node": ">=10.0.0",
+        "accepts": "~1.3.4",
+        "base64id": "2.0.0",
+        "cookie": "~0.7.2",
+        "cors": "~2.8.5",
+        "debug": "~4.4.1",
+        "engine.io-parser": "~5.2.1",
+        "ws": "~8.18.3"
+      },
+      "engines": {
+        "node": ">=10.2.0"
+      }
+    },
+    "node_modules/engine.io-parser": {
+      "version": "5.2.3",
+      "resolved": "https://registry.npmmirror.com/engine.io-parser/-/engine.io-parser-5.2.3.tgz",
+      "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/enhanced-resolve": {
+      "version": "5.19.0",
+      "resolved": "https://registry.npmmirror.com/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz",
+      "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "graceful-fs": "^4.2.4",
+        "tapable": "^2.3.0"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/ent": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmmirror.com/ent/-/ent-2.2.2.tgz",
+      "integrity": "sha512-kKvD1tO6BM+oK9HzCPpUdRb4vKFQY/FPTFmurMvh6LlN68VMrdj77w8yp51/kDbpkFOS9J8w5W6zIzgM2H8/hw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.3",
+        "es-errors": "^1.3.0",
+        "punycode": "^1.4.1",
+        "safe-regex-test": "^1.1.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/entities": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz",
+      "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=0.12"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
+      }
+    },
+    "node_modules/env-paths": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmmirror.com/env-paths/-/env-paths-2.2.1.tgz",
+      "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/environment": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/environment/-/environment-1.1.0.tgz",
+      "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/err-code": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmmirror.com/err-code/-/err-code-2.0.3.tgz",
+      "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/errno": {
+      "version": "0.1.8",
+      "resolved": "https://registry.npmmirror.com/errno/-/errno-0.1.8.tgz",
+      "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "prr": "~1.0.1"
+      },
+      "bin": {
+        "errno": "cli.js"
+      }
+    },
+    "node_modules/error-ex": {
+      "version": "1.3.4",
+      "resolved": "https://registry.npmmirror.com/error-ex/-/error-ex-1.3.4.tgz",
+      "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-arrayish": "^0.2.1"
+      }
+    },
+    "node_modules/es-define-property": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
+      "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-errors": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
+      "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-module-lexer": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmmirror.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
+      "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/es-object-atoms": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+      "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/esbuild": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.25.4.tgz",
+      "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==",
+      "dev": true,
+      "hasInstallScript": true,
+      "license": "MIT",
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "optionalDependencies": {
+        "@esbuild/aix-ppc64": "0.25.4",
+        "@esbuild/android-arm": "0.25.4",
+        "@esbuild/android-arm64": "0.25.4",
+        "@esbuild/android-x64": "0.25.4",
+        "@esbuild/darwin-arm64": "0.25.4",
+        "@esbuild/darwin-x64": "0.25.4",
+        "@esbuild/freebsd-arm64": "0.25.4",
+        "@esbuild/freebsd-x64": "0.25.4",
+        "@esbuild/linux-arm": "0.25.4",
+        "@esbuild/linux-arm64": "0.25.4",
+        "@esbuild/linux-ia32": "0.25.4",
+        "@esbuild/linux-loong64": "0.25.4",
+        "@esbuild/linux-mips64el": "0.25.4",
+        "@esbuild/linux-ppc64": "0.25.4",
+        "@esbuild/linux-riscv64": "0.25.4",
+        "@esbuild/linux-s390x": "0.25.4",
+        "@esbuild/linux-x64": "0.25.4",
+        "@esbuild/netbsd-arm64": "0.25.4",
+        "@esbuild/netbsd-x64": "0.25.4",
+        "@esbuild/openbsd-arm64": "0.25.4",
+        "@esbuild/openbsd-x64": "0.25.4",
+        "@esbuild/sunos-x64": "0.25.4",
+        "@esbuild/win32-arm64": "0.25.4",
+        "@esbuild/win32-ia32": "0.25.4",
+        "@esbuild/win32-x64": "0.25.4"
+      }
+    },
+    "node_modules/esbuild-wasm": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmmirror.com/esbuild-wasm/-/esbuild-wasm-0.25.4.tgz",
+      "integrity": "sha512-2HlCS6rNvKWaSKhWaG/YIyRsTsL3gUrMP2ToZMBIjw9LM7vVcIs+rz8kE2vExvTJgvM8OKPqNpcHawY/BQc/qQ==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/escalade": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz",
+      "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/eslint-scope": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-5.1.1.tgz",
+      "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "esrecurse": "^4.3.0",
+        "estraverse": "^4.1.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/esrecurse": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmmirror.com/esrecurse/-/esrecurse-4.3.0.tgz",
+      "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "estraverse": "^5.2.0"
+      },
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/esrecurse/node_modules/estraverse": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz",
+      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/estraverse": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-4.3.0.tgz",
+      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/esutils": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz",
+      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/etag": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmmirror.com/etag/-/etag-1.8.1.tgz",
+      "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/eventemitter3": {
+      "version": "4.0.7",
+      "resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-4.0.7.tgz",
+      "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/events": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmmirror.com/events/-/events-3.3.0.tgz",
+      "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.8.x"
+      }
+    },
+    "node_modules/exponential-backoff": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmmirror.com/exponential-backoff/-/exponential-backoff-3.1.3.tgz",
+      "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==",
+      "dev": true,
+      "license": "Apache-2.0"
+    },
+    "node_modules/express": {
+      "version": "4.22.1",
+      "resolved": "https://registry.npmmirror.com/express/-/express-4.22.1.tgz",
+      "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==",
+      "dev": true,
+      "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.14.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"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/express"
+      }
+    },
+    "node_modules/express/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/express/node_modules/encodeurl": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-2.0.0.tgz",
+      "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/express/node_modules/finalhandler": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmmirror.com/finalhandler/-/finalhandler-1.3.2.tgz",
+      "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==",
+      "dev": true,
+      "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.2",
+        "unpipe": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/express/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/express/node_modules/statuses": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.2.tgz",
+      "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmmirror.com/extend/-/extend-3.0.2.tgz",
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/fast-deep-equal": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/fast-glob": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.3.tgz",
+      "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@nodelib/fs.stat": "^2.0.2",
+        "@nodelib/fs.walk": "^1.2.3",
+        "glob-parent": "^5.1.2",
+        "merge2": "^1.3.0",
+        "micromatch": "^4.0.8"
+      },
+      "engines": {
+        "node": ">=8.6.0"
+      }
+    },
+    "node_modules/fast-glob/node_modules/glob-parent": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz",
+      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "is-glob": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/fast-uri": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/fast-uri/-/fast-uri-3.1.0.tgz",
+      "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fastify"
+        },
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/fastify"
+        }
+      ],
+      "license": "BSD-3-Clause"
+    },
+    "node_modules/fastq": {
+      "version": "1.20.1",
+      "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.20.1.tgz",
+      "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "reusify": "^1.0.4"
+      }
+    },
+    "node_modules/faye-websocket": {
+      "version": "0.11.4",
+      "resolved": "https://registry.npmmirror.com/faye-websocket/-/faye-websocket-0.11.4.tgz",
+      "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "websocket-driver": ">=0.5.1"
+      },
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/fdir": {
+      "version": "6.5.0",
+      "resolved": "https://registry.npmmirror.com/fdir/-/fdir-6.5.0.tgz",
+      "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12.0.0"
+      },
+      "peerDependencies": {
+        "picomatch": "^3 || ^4"
+      },
+      "peerDependenciesMeta": {
+        "picomatch": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/fill-range": {
+      "version": "7.1.1",
+      "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz",
+      "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "to-regex-range": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/finalhandler": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/finalhandler/-/finalhandler-1.1.2.tgz",
+      "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "debug": "2.6.9",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.3",
+        "statuses": "~1.5.0",
+        "unpipe": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/finalhandler/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/finalhandler/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/finalhandler/node_modules/on-finished": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/on-finished/-/on-finished-2.3.0.tgz",
+      "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ee-first": "1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/find-cache-dir": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/find-cache-dir/-/find-cache-dir-4.0.0.tgz",
+      "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "common-path-prefix": "^3.0.0",
+        "pkg-dir": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=14.16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/find-up": {
+      "version": "6.3.0",
+      "resolved": "https://registry.npmmirror.com/find-up/-/find-up-6.3.0.tgz",
+      "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "locate-path": "^7.1.0",
+        "path-exists": "^5.0.0"
+      },
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/flat": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmmirror.com/flat/-/flat-5.0.2.tgz",
+      "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "bin": {
+        "flat": "cli.js"
+      }
+    },
+    "node_modules/flatted": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmmirror.com/flatted/-/flatted-3.3.3.tgz",
+      "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/follow-redirects": {
+      "version": "1.15.11",
+      "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.11.tgz",
+      "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://github.com/sponsors/RubenVerborgh"
+        }
+      ],
+      "license": "MIT",
+      "engines": {
+        "node": ">=4.0"
+      },
+      "peerDependenciesMeta": {
+        "debug": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/foreground-child": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmmirror.com/foreground-child/-/foreground-child-3.3.1.tgz",
+      "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "cross-spawn": "^7.0.6",
+        "signal-exit": "^4.0.1"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/forwarded": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz",
+      "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/fraction.js": {
+      "version": "4.3.7",
+      "resolved": "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.3.7.tgz",
+      "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "type": "patreon",
+        "url": "https://github.com/sponsors/rawify"
+      }
+    },
+    "node_modules/fresh": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmmirror.com/fresh/-/fresh-0.5.2.tgz",
+      "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/fs-extra": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-8.1.0.tgz",
+      "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "graceful-fs": "^4.2.0",
+        "jsonfile": "^4.0.0",
+        "universalify": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=6 <7 || >=8"
+      }
+    },
+    "node_modules/fs-minipass": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/fs-minipass/-/fs-minipass-3.0.3.tgz",
+      "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "minipass": "^7.0.3"
+      },
+      "engines": {
+        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+      }
+    },
+    "node_modules/fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/fsevents": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz",
+      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+      "dev": true,
+      "hasInstallScript": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
+    "node_modules/function-bind": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
+      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+      "dev": true,
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/gensync": {
+      "version": "1.0.0-beta.2",
+      "resolved": "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz",
+      "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/get-caller-file": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz",
+      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": "6.* || 8.* || >= 10.*"
+      }
+    },
+    "node_modules/get-east-asian-width": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmmirror.com/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz",
+      "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/get-intrinsic": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+      "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bind-apply-helpers": "^1.0.2",
+        "es-define-property": "^1.0.1",
+        "es-errors": "^1.3.0",
+        "es-object-atoms": "^1.1.1",
+        "function-bind": "^1.1.2",
+        "get-proto": "^1.0.1",
+        "gopd": "^1.2.0",
+        "has-symbols": "^1.1.0",
+        "hasown": "^2.0.2",
+        "math-intrinsics": "^1.1.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/get-proto": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz",
+      "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "dunder-proto": "^1.0.1",
+        "es-object-atoms": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/glob": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+      "deprecated": "Glob versions prior to v9 are no longer supported",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.1.1",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/glob-parent": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz",
+      "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "is-glob": "^4.0.3"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/glob-to-regex.js": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/glob-to-regex.js/-/glob-to-regex.js-1.2.0.tgz",
+      "integrity": "sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=10.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/glob-to-regexp": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmmirror.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+      "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+      "dev": true,
+      "license": "BSD-2-Clause"
+    },
+    "node_modules/globby": {
+      "version": "14.1.0",
+      "resolved": "https://registry.npmmirror.com/globby/-/globby-14.1.0.tgz",
+      "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@sindresorhus/merge-streams": "^2.1.0",
+        "fast-glob": "^3.3.3",
+        "ignore": "^7.0.3",
+        "path-type": "^6.0.0",
+        "slash": "^5.1.0",
+        "unicorn-magic": "^0.3.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/gopd": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
+      "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/graceful-fs": {
+      "version": "4.2.11",
+      "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz",
+      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/handle-thing": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/handle-thing/-/handle-thing-2.0.1.tgz",
+      "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/has-flag": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/has-symbols": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
+      "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/has-tostringtag": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+      "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+      "dev": true,
+      "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.npmmirror.com/hasown/-/hasown-2.0.2.tgz",
+      "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "function-bind": "^1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/hosted-git-info": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-8.1.0.tgz",
+      "integrity": "sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "lru-cache": "^10.0.1"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/hosted-git-info/node_modules/lru-cache": {
+      "version": "10.4.3",
+      "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.4.3.tgz",
+      "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/hpack.js": {
+      "version": "2.1.6",
+      "resolved": "https://registry.npmmirror.com/hpack.js/-/hpack.js-2.1.6.tgz",
+      "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "obuf": "^1.0.0",
+        "readable-stream": "^2.0.1",
+        "wbuf": "^1.1.0"
+      }
+    },
+    "node_modules/hpack.js/node_modules/readable-stream": {
+      "version": "2.3.8",
+      "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz",
+      "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.3",
+        "isarray": "~1.0.0",
+        "process-nextick-args": "~2.0.0",
+        "safe-buffer": "~5.1.1",
+        "string_decoder": "~1.1.1",
+        "util-deprecate": "~1.0.1"
+      }
+    },
+    "node_modules/hpack.js/node_modules/safe-buffer": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
+      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/hpack.js/node_modules/string_decoder": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz",
+      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/html-escaper": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/html-escaper/-/html-escaper-2.0.2.tgz",
+      "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/htmlparser2": {
+      "version": "10.1.0",
+      "resolved": "https://registry.npmmirror.com/htmlparser2/-/htmlparser2-10.1.0.tgz",
+      "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==",
+      "dev": true,
+      "funding": [
+        "https://github.com/fb55/htmlparser2?sponsor=1",
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fb55"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.3",
+        "domutils": "^3.2.2",
+        "entities": "^7.0.1"
+      }
+    },
+    "node_modules/htmlparser2/node_modules/entities": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmmirror.com/entities/-/entities-7.0.1.tgz",
+      "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=0.12"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
+      }
+    },
+    "node_modules/http-cache-semantics": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmmirror.com/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz",
+      "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==",
+      "dev": true,
+      "license": "BSD-2-Clause"
+    },
+    "node_modules/http-deceiver": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npmmirror.com/http-deceiver/-/http-deceiver-1.2.7.tgz",
+      "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/http-errors": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.1.tgz",
+      "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
+      "dev": true,
+      "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-errors/node_modules/statuses": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.2.tgz",
+      "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/http-parser-js": {
+      "version": "0.5.10",
+      "resolved": "https://registry.npmmirror.com/http-parser-js/-/http-parser-js-0.5.10.tgz",
+      "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/http-proxy": {
+      "version": "1.18.1",
+      "resolved": "https://registry.npmmirror.com/http-proxy/-/http-proxy-1.18.1.tgz",
+      "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "eventemitter3": "^4.0.0",
+        "follow-redirects": "^1.0.0",
+        "requires-port": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/http-proxy-agent": {
+      "version": "7.0.2",
+      "resolved": "https://registry.npmmirror.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+      "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "agent-base": "^7.1.0",
+        "debug": "^4.3.4"
+      },
+      "engines": {
+        "node": ">= 14"
+      }
+    },
+    "node_modules/http-proxy-middleware": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmmirror.com/http-proxy-middleware/-/http-proxy-middleware-3.0.5.tgz",
+      "integrity": "sha512-GLZZm1X38BPY4lkXA01jhwxvDoOkkXqjgVyUzVxiEK4iuRu03PZoYHhHRwxnfhQMDuaxi3vVri0YgSro/1oWqg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/http-proxy": "^1.17.15",
+        "debug": "^4.3.6",
+        "http-proxy": "^1.18.1",
+        "is-glob": "^4.0.3",
+        "is-plain-object": "^5.0.0",
+        "micromatch": "^4.0.8"
+      },
+      "engines": {
+        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+      }
+    },
+    "node_modules/https-proxy-agent": {
+      "version": "7.0.6",
+      "resolved": "https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+      "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "agent-base": "^7.1.2",
+        "debug": "4"
+      },
+      "engines": {
+        "node": ">= 14"
+      }
+    },
+    "node_modules/hyperdyperid": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/hyperdyperid/-/hyperdyperid-1.2.0.tgz",
+      "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=10.18"
+      }
+    },
+    "node_modules/iconv-lite": {
+      "version": "0.4.24",
+      "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz",
+      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/icss-utils": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/icss-utils/-/icss-utils-5.1.0.tgz",
+      "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": "^10 || ^12 || >= 14"
+      },
+      "peerDependencies": {
+        "postcss": "^8.1.0"
+      }
+    },
+    "node_modules/ieee754": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz",
+      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+      "dev": true,
+      "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": "BSD-3-Clause"
+    },
+    "node_modules/ignore": {
+      "version": "7.0.5",
+      "resolved": "https://registry.npmmirror.com/ignore/-/ignore-7.0.5.tgz",
+      "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/ignore-walk": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmmirror.com/ignore-walk/-/ignore-walk-7.0.0.tgz",
+      "integrity": "sha512-T4gbf83A4NH95zvhVYZc+qWocBBGlpzUXLPGurJggw/WIOwicfXJChLDP/iBZnN5WqROSu5Bm3hhle4z8a8YGQ==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "minimatch": "^9.0.0"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/ignore-walk/node_modules/brace-expansion": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.2.tgz",
+      "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
+    "node_modules/ignore-walk/node_modules/minimatch": {
+      "version": "9.0.5",
+      "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz",
+      "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/image-size": {
+      "version": "0.5.5",
+      "resolved": "https://registry.npmmirror.com/image-size/-/image-size-0.5.5.tgz",
+      "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "bin": {
+        "image-size": "bin/image-size.js"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/immutable": {
+      "version": "5.1.4",
+      "resolved": "https://registry.npmmirror.com/immutable/-/immutable-5.1.4.tgz",
+      "integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/import-fresh": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.1.tgz",
+      "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "parent-module": "^1.0.0",
+        "resolve-from": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/imurmurhash": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz",
+      "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.8.19"
+      }
+    },
+    "node_modules/inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+      "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "once": "^1.3.0",
+        "wrappy": "1"
+      }
+    },
+    "node_modules/inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/ini": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/ini/-/ini-5.0.0.tgz",
+      "integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/ip-address": {
+      "version": "10.1.0",
+      "resolved": "https://registry.npmmirror.com/ip-address/-/ip-address-10.1.0.tgz",
+      "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 12"
+      }
+    },
+    "node_modules/ipaddr.js": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-2.3.0.tgz",
+      "integrity": "sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/is-arrayish": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.2.1.tgz",
+      "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/is-binary-path": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz",
+      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "binary-extensions": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/is-core-module": {
+      "version": "2.16.1",
+      "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.16.1.tgz",
+      "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "hasown": "^2.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-docker": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/is-docker/-/is-docker-3.0.0.tgz",
+      "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "is-docker": "cli.js"
+      },
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-fullwidth-code-point": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz",
+      "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/is-glob": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz",
+      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-extglob": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-inside-container": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/is-inside-container/-/is-inside-container-1.0.0.tgz",
+      "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-docker": "^3.0.0"
+      },
+      "bin": {
+        "is-inside-container": "cli.js"
+      },
+      "engines": {
+        "node": ">=14.16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/is-interactive": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/is-interactive/-/is-interactive-1.0.0.tgz",
+      "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/is-network-error": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/is-network-error/-/is-network-error-1.3.0.tgz",
+      "integrity": "sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/is-number": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz",
+      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.12.0"
+      }
+    },
+    "node_modules/is-plain-obj": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz",
+      "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/is-plain-object": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/is-plain-object/-/is-plain-object-5.0.0.tgz",
+      "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-regex": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/is-regex/-/is-regex-1.2.1.tgz",
+      "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "gopd": "^1.2.0",
+        "has-tostringtag": "^1.0.2",
+        "hasown": "^2.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-unicode-supported": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmmirror.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
+      "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/is-what": {
+      "version": "3.14.1",
+      "resolved": "https://registry.npmmirror.com/is-what/-/is-what-3.14.1.tgz",
+      "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/is-wsl": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/is-wsl/-/is-wsl-3.1.0.tgz",
+      "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-inside-container": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/isbinaryfile": {
+      "version": "4.0.10",
+      "resolved": "https://registry.npmmirror.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz",
+      "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 8.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/gjtorikian/"
+      }
+    },
+    "node_modules/isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/isobject": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/isobject/-/isobject-3.0.1.tgz",
+      "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/istanbul-lib-coverage": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmmirror.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
+      "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/istanbul-lib-instrument": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmmirror.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz",
+      "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "@babel/core": "^7.23.9",
+        "@babel/parser": "^7.23.9",
+        "@istanbuljs/schema": "^0.1.3",
+        "istanbul-lib-coverage": "^3.2.0",
+        "semver": "^7.5.4"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/istanbul-lib-report": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+      "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "istanbul-lib-coverage": "^3.0.0",
+        "make-dir": "^4.0.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/istanbul-lib-source-maps": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmmirror.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
+      "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "debug": "^4.1.1",
+        "istanbul-lib-coverage": "^3.0.0",
+        "source-map": "^0.6.1"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/istanbul-lib-source-maps/node_modules/source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/istanbul-reports": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmmirror.com/istanbul-reports/-/istanbul-reports-3.2.0.tgz",
+      "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "html-escaper": "^2.0.0",
+        "istanbul-lib-report": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/jackspeak": {
+      "version": "3.4.3",
+      "resolved": "https://registry.npmmirror.com/jackspeak/-/jackspeak-3.4.3.tgz",
+      "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "dependencies": {
+        "@isaacs/cliui": "^8.0.2"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      },
+      "optionalDependencies": {
+        "@pkgjs/parseargs": "^0.11.0"
+      }
+    },
+    "node_modules/jasmine-core": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmmirror.com/jasmine-core/-/jasmine-core-5.2.0.tgz",
+      "integrity": "sha512-tSAtdrvWybZkQmmaIoDgnvHG8ORUNw5kEVlO5CvrXj02Jjr9TZrmjFq7FUiOUzJiOP2wLGYT6PgrQgQF4R1xiw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/jest-worker": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmmirror.com/jest-worker/-/jest-worker-27.5.1.tgz",
+      "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/node": "*",
+        "merge-stream": "^2.0.0",
+        "supports-color": "^8.0.0"
+      },
+      "engines": {
+        "node": ">= 10.13.0"
+      }
+    },
+    "node_modules/jest-worker/node_modules/supports-color": {
+      "version": "8.1.1",
+      "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz",
+      "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/supports-color?sponsor=1"
+      }
+    },
+    "node_modules/jiti": {
+      "version": "1.21.7",
+      "resolved": "https://registry.npmmirror.com/jiti/-/jiti-1.21.7.tgz",
+      "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "jiti": "bin/jiti.js"
+      }
+    },
+    "node_modules/js-tokens": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/js-yaml": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.1.tgz",
+      "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "argparse": "^2.0.1"
+      },
+      "bin": {
+        "js-yaml": "bin/js-yaml.js"
+      }
+    },
+    "node_modules/jsesc": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-3.1.0.tgz",
+      "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "jsesc": "bin/jsesc"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/json-parse-even-better-errors": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/json-parse-even-better-errors/-/json-parse-even-better-errors-4.0.0.tgz",
+      "integrity": "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/json-schema-traverse": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/json5": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz",
+      "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "json5": "lib/cli.js"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/jsonc-parser": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmmirror.com/jsonc-parser/-/jsonc-parser-3.3.1.tgz",
+      "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/jsonfile": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-4.0.0.tgz",
+      "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
+      "dev": true,
+      "license": "MIT",
+      "optionalDependencies": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
+    "node_modules/jsonparse": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmmirror.com/jsonparse/-/jsonparse-1.3.1.tgz",
+      "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==",
+      "dev": true,
+      "engines": [
+        "node >= 0.2.0"
+      ],
+      "license": "MIT"
+    },
+    "node_modules/karma": {
+      "version": "6.4.4",
+      "resolved": "https://registry.npmmirror.com/karma/-/karma-6.4.4.tgz",
+      "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@colors/colors": "1.5.0",
+        "body-parser": "^1.19.0",
+        "braces": "^3.0.2",
+        "chokidar": "^3.5.1",
+        "connect": "^3.7.0",
+        "di": "^0.0.1",
+        "dom-serialize": "^2.2.1",
+        "glob": "^7.1.7",
+        "graceful-fs": "^4.2.6",
+        "http-proxy": "^1.18.1",
+        "isbinaryfile": "^4.0.8",
+        "lodash": "^4.17.21",
+        "log4js": "^6.4.1",
+        "mime": "^2.5.2",
+        "minimatch": "^3.0.4",
+        "mkdirp": "^0.5.5",
+        "qjobs": "^1.2.0",
+        "range-parser": "^1.2.1",
+        "rimraf": "^3.0.2",
+        "socket.io": "^4.7.2",
+        "source-map": "^0.6.1",
+        "tmp": "^0.2.1",
+        "ua-parser-js": "^0.7.30",
+        "yargs": "^16.1.1"
+      },
+      "bin": {
+        "karma": "bin/karma"
+      },
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/karma-chrome-launcher": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmmirror.com/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz",
+      "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "which": "^1.2.1"
+      }
+    },
+    "node_modules/karma-coverage": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmmirror.com/karma-coverage/-/karma-coverage-2.2.1.tgz",
+      "integrity": "sha512-yj7hbequkQP2qOSb20GuNSIyE//PgJWHwC2IydLE6XRtsnaflv+/OSGNssPjobYUlhVVagy99TQpqUt3vAUG7A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "istanbul-lib-coverage": "^3.2.0",
+        "istanbul-lib-instrument": "^5.1.0",
+        "istanbul-lib-report": "^3.0.0",
+        "istanbul-lib-source-maps": "^4.0.1",
+        "istanbul-reports": "^3.0.5",
+        "minimatch": "^3.0.4"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/karma-coverage/node_modules/istanbul-lib-instrument": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmmirror.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz",
+      "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "@babel/core": "^7.12.3",
+        "@babel/parser": "^7.14.7",
+        "@istanbuljs/schema": "^0.1.2",
+        "istanbul-lib-coverage": "^3.2.0",
+        "semver": "^6.3.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/karma-coverage/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/karma-jasmine": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/karma-jasmine/-/karma-jasmine-5.1.0.tgz",
+      "integrity": "sha512-i/zQLFrfEpRyQoJF9fsCdTMOF5c2dK7C7OmsuKg2D0YSsuZSfQDiLuaiktbuio6F2wiCsZSnSnieIQ0ant/uzQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "jasmine-core": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "peerDependencies": {
+        "karma": "^6.0.0"
+      }
+    },
+    "node_modules/karma-jasmine-html-reporter": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-2.1.0.tgz",
+      "integrity": "sha512-sPQE1+nlsn6Hwb5t+HHwyy0A1FNCVKuL1192b+XNauMYWThz2kweiBVW1DqloRpVvZIJkIoHVB7XRpK78n1xbQ==",
+      "dev": true,
+      "license": "MIT",
+      "peerDependencies": {
+        "jasmine-core": "^4.0.0 || ^5.0.0",
+        "karma": "^6.0.0",
+        "karma-jasmine": "^5.0.0"
+      }
+    },
+    "node_modules/karma-jasmine/node_modules/jasmine-core": {
+      "version": "4.6.1",
+      "resolved": "https://registry.npmmirror.com/jasmine-core/-/jasmine-core-4.6.1.tgz",
+      "integrity": "sha512-VYz/BjjmC3klLJlLwA4Kw8ytk0zDSmbbDLNs794VnWmkcCB7I9aAL/D48VNQtmITyPvea2C3jdUMfc3kAoy0PQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/karma-source-map-support": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmmirror.com/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz",
+      "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "source-map-support": "^0.5.5"
+      }
+    },
+    "node_modules/karma/node_modules/cliui": {
+      "version": "7.0.4",
+      "resolved": "https://registry.npmmirror.com/cliui/-/cliui-7.0.4.tgz",
+      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.0",
+        "wrap-ansi": "^7.0.0"
+      }
+    },
+    "node_modules/karma/node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/karma/node_modules/is-fullwidth-code-point": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/karma/node_modules/source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/karma/node_modules/string-width": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+      "dev": true,
+      "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/karma/node_modules/tmp": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmmirror.com/tmp/-/tmp-0.2.5.tgz",
+      "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=14.14"
+      }
+    },
+    "node_modules/karma/node_modules/wrap-ansi": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+      "dev": true,
+      "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/karma/node_modules/yargs": {
+      "version": "16.2.0",
+      "resolved": "https://registry.npmmirror.com/yargs/-/yargs-16.2.0.tgz",
+      "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "cliui": "^7.0.2",
+        "escalade": "^3.1.1",
+        "get-caller-file": "^2.0.5",
+        "require-directory": "^2.1.1",
+        "string-width": "^4.2.0",
+        "y18n": "^5.0.5",
+        "yargs-parser": "^20.2.2"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/karma/node_modules/yargs-parser": {
+      "version": "20.2.9",
+      "resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-20.2.9.tgz",
+      "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/kind-of": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-6.0.3.tgz",
+      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/launch-editor": {
+      "version": "2.12.0",
+      "resolved": "https://registry.npmmirror.com/launch-editor/-/launch-editor-2.12.0.tgz",
+      "integrity": "sha512-giOHXoOtifjdHqUamwKq6c49GzBdLjvxrd2D+Q4V6uOHopJv7p9VJxikDsQ/CBXZbEITgUqSVHXLTG3VhPP1Dg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "picocolors": "^1.1.1",
+        "shell-quote": "^1.8.3"
+      }
+    },
+    "node_modules/less": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmmirror.com/less/-/less-4.2.2.tgz",
+      "integrity": "sha512-tkuLHQlvWUTeQ3doAqnHbNn8T6WX1KA8yvbKG9x4VtKtIjHsVKQZCH11zRgAfbDAXC2UNIg/K9BYAAcEzUIrNg==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "copy-anything": "^2.0.1",
+        "parse-node-version": "^1.0.1",
+        "tslib": "^2.3.0"
+      },
+      "bin": {
+        "lessc": "bin/lessc"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "optionalDependencies": {
+        "errno": "^0.1.1",
+        "graceful-fs": "^4.1.2",
+        "image-size": "~0.5.0",
+        "make-dir": "^2.1.0",
+        "mime": "^1.4.1",
+        "needle": "^3.1.0",
+        "source-map": "~0.6.0"
+      }
+    },
+    "node_modules/less-loader": {
+      "version": "12.2.0",
+      "resolved": "https://registry.npmmirror.com/less-loader/-/less-loader-12.2.0.tgz",
+      "integrity": "sha512-MYUxjSQSBUQmowc0l5nPieOYwMzGPUaTzB6inNW/bdPEG9zOL3eAAD1Qw5ZxSPk7we5dMojHwNODYMV1hq4EVg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 18.12.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "@rspack/core": "0.x || 1.x",
+        "less": "^3.5.0 || ^4.0.0",
+        "webpack": "^5.0.0"
+      },
+      "peerDependenciesMeta": {
+        "@rspack/core": {
+          "optional": true
+        },
+        "webpack": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/less/node_modules/make-dir": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/make-dir/-/make-dir-2.1.0.tgz",
+      "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "pify": "^4.0.1",
+        "semver": "^5.6.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/less/node_modules/mime": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz",
+      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "bin": {
+        "mime": "cli.js"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/less/node_modules/semver": {
+      "version": "5.7.2",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-5.7.2.tgz",
+      "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+      "dev": true,
+      "license": "ISC",
+      "optional": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/less/node_modules/source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "optional": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/license-webpack-plugin": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz",
+      "integrity": "sha512-771TFWFD70G1wLTC4oU2Cw4qvtmNrIw+wRvBtn+okgHl7slJVi7zfNcdmqDL72BojM30VNJ2UHylr1o77U37Jw==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "webpack-sources": "^3.0.0"
+      },
+      "peerDependenciesMeta": {
+        "webpack": {
+          "optional": true
+        },
+        "webpack-sources": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/lines-and-columns": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+      "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/listr2": {
+      "version": "8.2.5",
+      "resolved": "https://registry.npmmirror.com/listr2/-/listr2-8.2.5.tgz",
+      "integrity": "sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "cli-truncate": "^4.0.0",
+        "colorette": "^2.0.20",
+        "eventemitter3": "^5.0.1",
+        "log-update": "^6.1.0",
+        "rfdc": "^1.4.1",
+        "wrap-ansi": "^9.0.0"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      }
+    },
+    "node_modules/listr2/node_modules/ansi-regex": {
+      "version": "6.2.2",
+      "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.2.2.tgz",
+      "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+      }
+    },
+    "node_modules/listr2/node_modules/ansi-styles": {
+      "version": "6.2.3",
+      "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.3.tgz",
+      "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/listr2/node_modules/eventemitter3": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-5.0.4.tgz",
+      "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/listr2/node_modules/strip-ansi": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.2.tgz",
+      "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-regex": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+      }
+    },
+    "node_modules/listr2/node_modules/wrap-ansi": {
+      "version": "9.0.2",
+      "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
+      "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-styles": "^6.2.1",
+        "string-width": "^7.0.0",
+        "strip-ansi": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+      }
+    },
+    "node_modules/lmdb": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmmirror.com/lmdb/-/lmdb-3.2.6.tgz",
+      "integrity": "sha512-SuHqzPl7mYStna8WRotY8XX/EUZBjjv3QyKIByeCLFfC9uXT/OIHByEcA07PzbMfQAM0KYJtLgtpMRlIe5dErQ==",
+      "dev": true,
+      "hasInstallScript": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "msgpackr": "^1.11.2",
+        "node-addon-api": "^6.1.0",
+        "node-gyp-build-optional-packages": "5.2.2",
+        "ordered-binary": "^1.5.3",
+        "weak-lru-cache": "^1.2.2"
+      },
+      "bin": {
+        "download-lmdb-prebuilds": "bin/download-prebuilds.js"
+      },
+      "optionalDependencies": {
+        "@lmdb/lmdb-darwin-arm64": "3.2.6",
+        "@lmdb/lmdb-darwin-x64": "3.2.6",
+        "@lmdb/lmdb-linux-arm": "3.2.6",
+        "@lmdb/lmdb-linux-arm64": "3.2.6",
+        "@lmdb/lmdb-linux-x64": "3.2.6",
+        "@lmdb/lmdb-win32-x64": "3.2.6"
+      }
+    },
+    "node_modules/loader-runner": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmmirror.com/loader-runner/-/loader-runner-4.3.1.tgz",
+      "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.11.5"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      }
+    },
+    "node_modules/loader-utils": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-3.3.1.tgz",
+      "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 12.13.0"
+      }
+    },
+    "node_modules/locate-path": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-7.2.0.tgz",
+      "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "p-locate": "^6.0.0"
+      },
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/lodash": {
+      "version": "4.17.23",
+      "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.23.tgz",
+      "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/lodash.debounce": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmmirror.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+      "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/log-symbols": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/log-symbols/-/log-symbols-4.1.0.tgz",
+      "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "chalk": "^4.1.0",
+        "is-unicode-supported": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/log-update": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmmirror.com/log-update/-/log-update-6.1.0.tgz",
+      "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-escapes": "^7.0.0",
+        "cli-cursor": "^5.0.0",
+        "slice-ansi": "^7.1.0",
+        "strip-ansi": "^7.1.0",
+        "wrap-ansi": "^9.0.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/log-update/node_modules/ansi-regex": {
+      "version": "6.2.2",
+      "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.2.2.tgz",
+      "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+      }
+    },
+    "node_modules/log-update/node_modules/ansi-styles": {
+      "version": "6.2.3",
+      "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.3.tgz",
+      "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/log-update/node_modules/is-fullwidth-code-point": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz",
+      "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "get-east-asian-width": "^1.3.1"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/log-update/node_modules/slice-ansi": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmmirror.com/slice-ansi/-/slice-ansi-7.1.2.tgz",
+      "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-styles": "^6.2.1",
+        "is-fullwidth-code-point": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+      }
+    },
+    "node_modules/log-update/node_modules/strip-ansi": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.2.tgz",
+      "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-regex": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+      }
+    },
+    "node_modules/log-update/node_modules/wrap-ansi": {
+      "version": "9.0.2",
+      "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
+      "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-styles": "^6.2.1",
+        "string-width": "^7.0.0",
+        "strip-ansi": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+      }
+    },
+    "node_modules/log4js": {
+      "version": "6.9.1",
+      "resolved": "https://registry.npmmirror.com/log4js/-/log4js-6.9.1.tgz",
+      "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "date-format": "^4.0.14",
+        "debug": "^4.3.4",
+        "flatted": "^3.2.7",
+        "rfdc": "^1.3.0",
+        "streamroller": "^3.1.5"
+      },
+      "engines": {
+        "node": ">=8.0"
+      }
+    },
+    "node_modules/lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz",
+      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "yallist": "^3.0.2"
+      }
+    },
+    "node_modules/magic-string": {
+      "version": "0.30.17",
+      "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.17.tgz",
+      "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@jridgewell/sourcemap-codec": "^1.5.0"
+      }
+    },
+    "node_modules/make-dir": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/make-dir/-/make-dir-4.0.0.tgz",
+      "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "semver": "^7.5.3"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/make-fetch-happen": {
+      "version": "14.0.3",
+      "resolved": "https://registry.npmmirror.com/make-fetch-happen/-/make-fetch-happen-14.0.3.tgz",
+      "integrity": "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "@npmcli/agent": "^3.0.0",
+        "cacache": "^19.0.1",
+        "http-cache-semantics": "^4.1.1",
+        "minipass": "^7.0.2",
+        "minipass-fetch": "^4.0.0",
+        "minipass-flush": "^1.0.5",
+        "minipass-pipeline": "^1.2.4",
+        "negotiator": "^1.0.0",
+        "proc-log": "^5.0.0",
+        "promise-retry": "^2.0.1",
+        "ssri": "^12.0.0"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/math-intrinsics": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+      "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/media-typer": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmmirror.com/media-typer/-/media-typer-0.3.0.tgz",
+      "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/memfs": {
+      "version": "4.56.10",
+      "resolved": "https://registry.npmmirror.com/memfs/-/memfs-4.56.10.tgz",
+      "integrity": "sha512-eLvzyrwqLHnLYalJP7YZ3wBe79MXktMdfQbvMrVD80K+NhrIukCVBvgP30zTJYEEDh9hZ/ep9z0KOdD7FSHo7w==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@jsonjoy.com/fs-core": "4.56.10",
+        "@jsonjoy.com/fs-fsa": "4.56.10",
+        "@jsonjoy.com/fs-node": "4.56.10",
+        "@jsonjoy.com/fs-node-builtins": "4.56.10",
+        "@jsonjoy.com/fs-node-to-fsa": "4.56.10",
+        "@jsonjoy.com/fs-node-utils": "4.56.10",
+        "@jsonjoy.com/fs-print": "4.56.10",
+        "@jsonjoy.com/fs-snapshot": "4.56.10",
+        "@jsonjoy.com/json-pack": "^1.11.0",
+        "@jsonjoy.com/util": "^1.9.0",
+        "glob-to-regex.js": "^1.0.1",
+        "thingies": "^2.5.0",
+        "tree-dump": "^1.0.3",
+        "tslib": "^2.0.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/merge-descriptors": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
+      "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
+      "dev": true,
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/merge-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz",
+      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/merge2": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz",
+      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/methods": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/methods/-/methods-1.1.2.tgz",
+      "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/micromatch": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.8.tgz",
+      "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "braces": "^3.0.3",
+        "picomatch": "^2.3.1"
+      },
+      "engines": {
+        "node": ">=8.6"
+      }
+    },
+    "node_modules/micromatch/node_modules/picomatch": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz",
+      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/mime": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmmirror.com/mime/-/mime-2.6.0.tgz",
+      "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "mime": "cli.js"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mimic-fn": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz",
+      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/mimic-function": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmmirror.com/mimic-function/-/mimic-function-5.0.1.tgz",
+      "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/mini-css-extract-plugin": {
+      "version": "2.9.2",
+      "resolved": "https://registry.npmmirror.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz",
+      "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "schema-utils": "^4.0.0",
+        "tapable": "^2.2.1"
+      },
+      "engines": {
+        "node": ">= 12.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "webpack": "^5.0.0"
+      }
+    },
+    "node_modules/minimalistic-assert": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+      "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/minimist": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz",
+      "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+      "dev": true,
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/minipass": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmmirror.com/minipass/-/minipass-7.1.2.tgz",
+      "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      }
+    },
+    "node_modules/minipass-collect": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/minipass-collect/-/minipass-collect-2.0.1.tgz",
+      "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "minipass": "^7.0.3"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      }
+    },
+    "node_modules/minipass-fetch": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmmirror.com/minipass-fetch/-/minipass-fetch-4.0.1.tgz",
+      "integrity": "sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "minipass": "^7.0.3",
+        "minipass-sized": "^1.0.3",
+        "minizlib": "^3.0.1"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      },
+      "optionalDependencies": {
+        "encoding": "^0.1.13"
+      }
+    },
+    "node_modules/minipass-flush": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmmirror.com/minipass-flush/-/minipass-flush-1.0.5.tgz",
+      "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "minipass": "^3.0.0"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/minipass-flush/node_modules/minipass": {
+      "version": "3.3.6",
+      "resolved": "https://registry.npmmirror.com/minipass/-/minipass-3.3.6.tgz",
+      "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/minipass-flush/node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/minipass-pipeline": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmmirror.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
+      "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "minipass": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/minipass-pipeline/node_modules/minipass": {
+      "version": "3.3.6",
+      "resolved": "https://registry.npmmirror.com/minipass/-/minipass-3.3.6.tgz",
+      "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/minipass-pipeline/node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/minipass-sized": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/minipass-sized/-/minipass-sized-1.0.3.tgz",
+      "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "minipass": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/minipass-sized/node_modules/minipass": {
+      "version": "3.3.6",
+      "resolved": "https://registry.npmmirror.com/minipass/-/minipass-3.3.6.tgz",
+      "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/minipass-sized/node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/minizlib": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/minizlib/-/minizlib-3.1.0.tgz",
+      "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "minipass": "^7.1.2"
+      },
+      "engines": {
+        "node": ">= 18"
+      }
+    },
+    "node_modules/mkdirp": {
+      "version": "0.5.6",
+      "resolved": "https://registry.npmmirror.com/mkdirp/-/mkdirp-0.5.6.tgz",
+      "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "minimist": "^1.2.6"
+      },
+      "bin": {
+        "mkdirp": "bin/cmd.js"
+      }
+    },
+    "node_modules/mrmime": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/mrmime/-/mrmime-2.0.1.tgz",
+      "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/ms": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/msgpackr": {
+      "version": "1.11.8",
+      "resolved": "https://registry.npmmirror.com/msgpackr/-/msgpackr-1.11.8.tgz",
+      "integrity": "sha512-bC4UGzHhVvgDNS7kn9tV8fAucIYUBuGojcaLiz7v+P63Lmtm0Xeji8B/8tYKddALXxJLpwIeBmUN3u64C4YkRA==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "optionalDependencies": {
+        "msgpackr-extract": "^3.0.2"
+      }
+    },
+    "node_modules/msgpackr-extract": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz",
+      "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==",
+      "dev": true,
+      "hasInstallScript": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "node-gyp-build-optional-packages": "5.2.2"
+      },
+      "bin": {
+        "download-msgpackr-prebuilds": "bin/download-prebuilds.js"
+      },
+      "optionalDependencies": {
+        "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3",
+        "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3",
+        "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3",
+        "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3",
+        "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3",
+        "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3"
+      }
+    },
+    "node_modules/multicast-dns": {
+      "version": "7.2.5",
+      "resolved": "https://registry.npmmirror.com/multicast-dns/-/multicast-dns-7.2.5.tgz",
+      "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "dns-packet": "^5.2.2",
+        "thunky": "^1.0.2"
+      },
+      "bin": {
+        "multicast-dns": "cli.js"
+      }
+    },
+    "node_modules/mute-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/mute-stream/-/mute-stream-2.0.0.tgz",
+      "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/nanoid": {
+      "version": "3.3.11",
+      "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz",
+      "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "bin": {
+        "nanoid": "bin/nanoid.cjs"
+      },
+      "engines": {
+        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+      }
+    },
+    "node_modules/needle": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmmirror.com/needle/-/needle-3.3.1.tgz",
+      "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "iconv-lite": "^0.6.3",
+        "sax": "^1.2.4"
+      },
+      "bin": {
+        "needle": "bin/needle"
+      },
+      "engines": {
+        "node": ">= 4.4.x"
+      }
+    },
+    "node_modules/needle/node_modules/iconv-lite": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz",
+      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/negotiator": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/negotiator/-/negotiator-1.0.0.tgz",
+      "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/neo-async": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmmirror.com/neo-async/-/neo-async-2.6.2.tgz",
+      "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/node-addon-api": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmmirror.com/node-addon-api/-/node-addon-api-6.1.0.tgz",
+      "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/node-forge": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmmirror.com/node-forge/-/node-forge-1.3.3.tgz",
+      "integrity": "sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==",
+      "dev": true,
+      "license": "(BSD-3-Clause OR GPL-2.0)",
+      "engines": {
+        "node": ">= 6.13.0"
+      }
+    },
+    "node_modules/node-gyp": {
+      "version": "11.5.0",
+      "resolved": "https://registry.npmmirror.com/node-gyp/-/node-gyp-11.5.0.tgz",
+      "integrity": "sha512-ra7Kvlhxn5V9Slyus0ygMa2h+UqExPqUIkfk7Pc8QTLT956JLSy51uWFwHtIYy0vI8cB4BDhc/S03+880My/LQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "env-paths": "^2.2.0",
+        "exponential-backoff": "^3.1.1",
+        "graceful-fs": "^4.2.6",
+        "make-fetch-happen": "^14.0.3",
+        "nopt": "^8.0.0",
+        "proc-log": "^5.0.0",
+        "semver": "^7.3.5",
+        "tar": "^7.4.3",
+        "tinyglobby": "^0.2.12",
+        "which": "^5.0.0"
+      },
+      "bin": {
+        "node-gyp": "bin/node-gyp.js"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/node-gyp-build-optional-packages": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npmmirror.com/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz",
+      "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "detect-libc": "^2.0.1"
+      },
+      "bin": {
+        "node-gyp-build-optional-packages": "bin.js",
+        "node-gyp-build-optional-packages-optional": "optional.js",
+        "node-gyp-build-optional-packages-test": "build-test.js"
+      }
+    },
+    "node_modules/node-gyp/node_modules/chownr": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/chownr/-/chownr-3.0.0.tgz",
+      "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/node-gyp/node_modules/isexe": {
+      "version": "3.1.5",
+      "resolved": "https://registry.npmmirror.com/isexe/-/isexe-3.1.5.tgz",
+      "integrity": "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/node-gyp/node_modules/tar": {
+      "version": "7.5.7",
+      "resolved": "https://registry.npmmirror.com/tar/-/tar-7.5.7.tgz",
+      "integrity": "sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "dependencies": {
+        "@isaacs/fs-minipass": "^4.0.0",
+        "chownr": "^3.0.0",
+        "minipass": "^7.1.2",
+        "minizlib": "^3.1.0",
+        "yallist": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/node-gyp/node_modules/which": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/which/-/which-5.0.0.tgz",
+      "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "isexe": "^3.1.1"
+      },
+      "bin": {
+        "node-which": "bin/which.js"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/node-gyp/node_modules/yallist": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/yallist/-/yallist-5.0.0.tgz",
+      "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/node-releases": {
+      "version": "2.0.27",
+      "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.27.tgz",
+      "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/nopt": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmmirror.com/nopt/-/nopt-8.1.0.tgz",
+      "integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "abbrev": "^3.0.0"
+      },
+      "bin": {
+        "nopt": "bin/nopt.js"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/normalize-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz",
+      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/normalize-range": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmmirror.com/normalize-range/-/normalize-range-0.1.2.tgz",
+      "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/npm-bundled": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/npm-bundled/-/npm-bundled-4.0.0.tgz",
+      "integrity": "sha512-IxaQZDMsqfQ2Lz37VvyyEtKLe8FsRZuysmedy/N06TU1RyVppYKXrO4xIhR0F+7ubIBox6Q7nir6fQI3ej39iA==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "npm-normalize-package-bin": "^4.0.0"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/npm-install-checks": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmmirror.com/npm-install-checks/-/npm-install-checks-7.1.2.tgz",
+      "integrity": "sha512-z9HJBCYw9Zr8BqXcllKIs5nI+QggAImbBdHphOzVYrz2CB4iQ6FzWyKmlqDZua+51nAu7FcemlbTc9VgQN5XDQ==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "semver": "^7.1.1"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/npm-normalize-package-bin": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz",
+      "integrity": "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/npm-package-arg": {
+      "version": "12.0.2",
+      "resolved": "https://registry.npmmirror.com/npm-package-arg/-/npm-package-arg-12.0.2.tgz",
+      "integrity": "sha512-f1NpFjNI9O4VbKMOlA5QoBq/vSQPORHcTZ2feJpFkTHJ9eQkdlmZEKSjcAhxTGInC7RlEyScT9ui67NaOsjFWA==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "hosted-git-info": "^8.0.0",
+        "proc-log": "^5.0.0",
+        "semver": "^7.3.5",
+        "validate-npm-package-name": "^6.0.0"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/npm-packlist": {
+      "version": "9.0.0",
+      "resolved": "https://registry.npmmirror.com/npm-packlist/-/npm-packlist-9.0.0.tgz",
+      "integrity": "sha512-8qSayfmHJQTx3nJWYbbUmflpyarbLMBc6LCAjYsiGtXxDB68HaZpb8re6zeaLGxZzDuMdhsg70jryJe+RrItVQ==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "ignore-walk": "^7.0.0"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/npm-pick-manifest": {
+      "version": "10.0.0",
+      "resolved": "https://registry.npmmirror.com/npm-pick-manifest/-/npm-pick-manifest-10.0.0.tgz",
+      "integrity": "sha512-r4fFa4FqYY8xaM7fHecQ9Z2nE9hgNfJR+EmoKv0+chvzWkBcORX3r0FpTByP+CbOVJDladMXnPQGVN8PBLGuTQ==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "npm-install-checks": "^7.1.0",
+        "npm-normalize-package-bin": "^4.0.0",
+        "npm-package-arg": "^12.0.0",
+        "semver": "^7.3.5"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/npm-registry-fetch": {
+      "version": "18.0.2",
+      "resolved": "https://registry.npmmirror.com/npm-registry-fetch/-/npm-registry-fetch-18.0.2.tgz",
+      "integrity": "sha512-LeVMZBBVy+oQb5R6FDV9OlJCcWDU+al10oKpe+nsvcHnG24Z3uM3SvJYKfGJlfGjVU8v9liejCrUR/M5HO5NEQ==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "@npmcli/redact": "^3.0.0",
+        "jsonparse": "^1.3.1",
+        "make-fetch-happen": "^14.0.0",
+        "minipass": "^7.0.2",
+        "minipass-fetch": "^4.0.0",
+        "minizlib": "^3.0.1",
+        "npm-package-arg": "^12.0.0",
+        "proc-log": "^5.0.0"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/nth-check": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/nth-check/-/nth-check-2.1.1.tgz",
+      "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "boolbase": "^1.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/nth-check?sponsor=1"
+      }
+    },
+    "node_modules/object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/object-inspect": {
+      "version": "1.13.4",
+      "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.13.4.tgz",
+      "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/obuf": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/obuf/-/obuf-1.1.2.tgz",
+      "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/on-finished": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz",
+      "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ee-first": "1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/on-headers": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/on-headers/-/on-headers-1.1.0.tgz",
+      "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz",
+      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "wrappy": "1"
+      }
+    },
+    "node_modules/onetime": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmmirror.com/onetime/-/onetime-7.0.0.tgz",
+      "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "mimic-function": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/open": {
+      "version": "10.1.0",
+      "resolved": "https://registry.npmmirror.com/open/-/open-10.1.0.tgz",
+      "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "default-browser": "^5.2.1",
+        "define-lazy-prop": "^3.0.0",
+        "is-inside-container": "^1.0.0",
+        "is-wsl": "^3.1.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/ora": {
+      "version": "5.4.1",
+      "resolved": "https://registry.npmmirror.com/ora/-/ora-5.4.1.tgz",
+      "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "bl": "^4.1.0",
+        "chalk": "^4.1.0",
+        "cli-cursor": "^3.1.0",
+        "cli-spinners": "^2.5.0",
+        "is-interactive": "^1.0.0",
+        "is-unicode-supported": "^0.1.0",
+        "log-symbols": "^4.1.0",
+        "strip-ansi": "^6.0.0",
+        "wcwidth": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/ora/node_modules/cli-cursor": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/cli-cursor/-/cli-cursor-3.1.0.tgz",
+      "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "restore-cursor": "^3.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/ora/node_modules/onetime": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz",
+      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "mimic-fn": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/ora/node_modules/restore-cursor": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/restore-cursor/-/restore-cursor-3.1.0.tgz",
+      "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "onetime": "^5.1.0",
+        "signal-exit": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/ora/node_modules/signal-exit": {
+      "version": "3.0.7",
+      "resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz",
+      "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/ordered-binary": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmmirror.com/ordered-binary/-/ordered-binary-1.6.1.tgz",
+      "integrity": "sha512-QkCdPooczexPLiXIrbVOPYkR3VO3T6v2OyKRkR1Xbhpy7/LAVXwahnRCgRp78Oe/Ehf0C/HATAxfSr6eA1oX+w==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/p-limit": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-4.0.0.tgz",
+      "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "yocto-queue": "^1.0.0"
+      },
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/p-locate": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-6.0.0.tgz",
+      "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "p-limit": "^4.0.0"
+      },
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/p-map": {
+      "version": "7.0.4",
+      "resolved": "https://registry.npmmirror.com/p-map/-/p-map-7.0.4.tgz",
+      "integrity": "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/p-retry": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmmirror.com/p-retry/-/p-retry-6.2.1.tgz",
+      "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/retry": "0.12.2",
+        "is-network-error": "^1.0.0",
+        "retry": "^0.13.1"
+      },
+      "engines": {
+        "node": ">=16.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/p-retry/node_modules/retry": {
+      "version": "0.13.1",
+      "resolved": "https://registry.npmmirror.com/retry/-/retry-0.13.1.tgz",
+      "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/package-json-from-dist": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+      "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
+      "dev": true,
+      "license": "BlueOak-1.0.0"
+    },
+    "node_modules/pacote": {
+      "version": "20.0.0",
+      "resolved": "https://registry.npmmirror.com/pacote/-/pacote-20.0.0.tgz",
+      "integrity": "sha512-pRjC5UFwZCgx9kUFDVM9YEahv4guZ1nSLqwmWiLUnDbGsjs+U5w7z6Uc8HNR1a6x8qnu5y9xtGE6D1uAuYz+0A==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "@npmcli/git": "^6.0.0",
+        "@npmcli/installed-package-contents": "^3.0.0",
+        "@npmcli/package-json": "^6.0.0",
+        "@npmcli/promise-spawn": "^8.0.0",
+        "@npmcli/run-script": "^9.0.0",
+        "cacache": "^19.0.0",
+        "fs-minipass": "^3.0.0",
+        "minipass": "^7.0.2",
+        "npm-package-arg": "^12.0.0",
+        "npm-packlist": "^9.0.0",
+        "npm-pick-manifest": "^10.0.0",
+        "npm-registry-fetch": "^18.0.0",
+        "proc-log": "^5.0.0",
+        "promise-retry": "^2.0.1",
+        "sigstore": "^3.0.0",
+        "ssri": "^12.0.0",
+        "tar": "^6.1.11"
+      },
+      "bin": {
+        "pacote": "bin/index.js"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/parent-module": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz",
+      "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "callsites": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/parse-json": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmmirror.com/parse-json/-/parse-json-5.2.0.tgz",
+      "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/code-frame": "^7.0.0",
+        "error-ex": "^1.3.1",
+        "json-parse-even-better-errors": "^2.3.0",
+        "lines-and-columns": "^1.1.6"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/parse-json/node_modules/json-parse-even-better-errors": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmmirror.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/parse-node-version": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/parse-node-version/-/parse-node-version-1.0.1.tgz",
+      "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/parse5": {
+      "version": "7.3.0",
+      "resolved": "https://registry.npmmirror.com/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/parse5-html-rewriting-stream": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmmirror.com/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-7.0.0.tgz",
+      "integrity": "sha512-mazCyGWkmCRWDI15Zp+UiCqMp/0dgEmkZRvhlsqqKYr4SsVm/TvnSpD9fCvqCA2zoWJcfRym846ejWBBHRiYEg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "entities": "^4.3.0",
+        "parse5": "^7.0.0",
+        "parse5-sax-parser": "^7.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/inikulin/parse5?sponsor=1"
+      }
+    },
+    "node_modules/parse5-sax-parser": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmmirror.com/parse5-sax-parser/-/parse5-sax-parser-7.0.0.tgz",
+      "integrity": "sha512-5A+v2SNsq8T6/mG3ahcz8ZtQ0OUFTatxPbeidoMB7tkJSGDY3tdfl4MHovtLQHkEn5CGxijNWRQHhRQ6IRpXKg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "parse5": "^7.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/inikulin/parse5?sponsor=1"
+      }
+    },
+    "node_modules/parse5/node_modules/entities": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmmirror.com/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/parseurl": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz",
+      "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/path-exists": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-5.0.0.tgz",
+      "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      }
+    },
+    "node_modules/path-is-absolute": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/path-key": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz",
+      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/path-parse": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz",
+      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/path-scurry": {
+      "version": "1.11.1",
+      "resolved": "https://registry.npmmirror.com/path-scurry/-/path-scurry-1.11.1.tgz",
+      "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "dependencies": {
+        "lru-cache": "^10.2.0",
+        "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/path-scurry/node_modules/lru-cache": {
+      "version": "10.4.3",
+      "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.4.3.tgz",
+      "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/path-to-regexp": {
+      "version": "0.1.12",
+      "resolved": "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
+      "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/path-type": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmmirror.com/path-type/-/path-type-6.0.0.tgz",
+      "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/picocolors": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
+      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/picomatch": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.2.tgz",
+      "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/pify": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmmirror.com/pify/-/pify-4.0.1.tgz",
+      "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/piscina": {
+      "version": "4.8.0",
+      "resolved": "https://registry.npmmirror.com/piscina/-/piscina-4.8.0.tgz",
+      "integrity": "sha512-EZJb+ZxDrQf3dihsUL7p42pjNyrNIFJCrRHPMgxu/svsj+P3xS3fuEWp7k2+rfsavfl1N0G29b1HGs7J0m8rZA==",
+      "dev": true,
+      "license": "MIT",
+      "optionalDependencies": {
+        "@napi-rs/nice": "^1.0.1"
+      }
+    },
+    "node_modules/pkg-dir": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmmirror.com/pkg-dir/-/pkg-dir-7.0.0.tgz",
+      "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "find-up": "^6.3.0"
+      },
+      "engines": {
+        "node": ">=14.16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/postcss": {
+      "version": "8.5.6",
+      "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.6.tgz",
+      "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/postcss"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "nanoid": "^3.3.11",
+        "picocolors": "^1.1.1",
+        "source-map-js": "^1.2.1"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      }
+    },
+    "node_modules/postcss-loader": {
+      "version": "8.1.1",
+      "resolved": "https://registry.npmmirror.com/postcss-loader/-/postcss-loader-8.1.1.tgz",
+      "integrity": "sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "cosmiconfig": "^9.0.0",
+        "jiti": "^1.20.0",
+        "semver": "^7.5.4"
+      },
+      "engines": {
+        "node": ">= 18.12.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "@rspack/core": "0.x || 1.x",
+        "postcss": "^7.0.0 || ^8.0.1",
+        "webpack": "^5.0.0"
+      },
+      "peerDependenciesMeta": {
+        "@rspack/core": {
+          "optional": true
+        },
+        "webpack": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/postcss-media-query-parser": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmmirror.com/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz",
+      "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/postcss-modules-extract-imports": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz",
+      "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": "^10 || ^12 || >= 14"
+      },
+      "peerDependencies": {
+        "postcss": "^8.1.0"
+      }
+    },
+    "node_modules/postcss-modules-local-by-default": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmmirror.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz",
+      "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "icss-utils": "^5.0.0",
+        "postcss-selector-parser": "^7.0.0",
+        "postcss-value-parser": "^4.1.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >= 14"
+      },
+      "peerDependencies": {
+        "postcss": "^8.1.0"
+      }
+    },
+    "node_modules/postcss-modules-scope": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmmirror.com/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz",
+      "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "postcss-selector-parser": "^7.0.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >= 14"
+      },
+      "peerDependencies": {
+        "postcss": "^8.1.0"
+      }
+    },
+    "node_modules/postcss-modules-values": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz",
+      "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "icss-utils": "^5.0.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >= 14"
+      },
+      "peerDependencies": {
+        "postcss": "^8.1.0"
+      }
+    },
+    "node_modules/postcss-selector-parser": {
+      "version": "7.1.1",
+      "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
+      "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "cssesc": "^3.0.0",
+        "util-deprecate": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/postcss-value-parser": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+      "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/proc-log": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/proc-log/-/proc-log-5.0.0.tgz",
+      "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/process-nextick-args": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/promise-retry": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/promise-retry/-/promise-retry-2.0.1.tgz",
+      "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "err-code": "^2.0.2",
+        "retry": "^0.12.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/proxy-addr": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmmirror.com/proxy-addr/-/proxy-addr-2.0.7.tgz",
+      "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "forwarded": "0.2.0",
+        "ipaddr.js": "1.9.1"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/proxy-addr/node_modules/ipaddr.js": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+      "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/prr": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/prr/-/prr-1.0.1.tgz",
+      "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/punycode": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/punycode/-/punycode-1.4.1.tgz",
+      "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/qjobs": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/qjobs/-/qjobs-1.2.0.tgz",
+      "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.9"
+      }
+    },
+    "node_modules/qs": {
+      "version": "6.14.1",
+      "resolved": "https://registry.npmmirror.com/qs/-/qs-6.14.1.tgz",
+      "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "side-channel": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=0.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/queue-microtask": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz",
+      "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+      "dev": true,
+      "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/randombytes": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/randombytes/-/randombytes-2.1.0.tgz",
+      "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "node_modules/range-parser": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/range-parser/-/range-parser-1.2.1.tgz",
+      "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/raw-body": {
+      "version": "2.5.3",
+      "resolved": "https://registry.npmmirror.com/raw-body/-/raw-body-2.5.3.tgz",
+      "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "bytes": "~3.1.2",
+        "http-errors": "~2.0.1",
+        "iconv-lite": "~0.4.24",
+        "unpipe": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/readable-stream": {
+      "version": "3.6.2",
+      "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz",
+      "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/readdirp": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz",
+      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "picomatch": "^2.2.1"
+      },
+      "engines": {
+        "node": ">=8.10.0"
+      }
+    },
+    "node_modules/readdirp/node_modules/picomatch": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz",
+      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/reflect-metadata": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmmirror.com/reflect-metadata/-/reflect-metadata-0.2.2.tgz",
+      "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==",
+      "dev": true,
+      "license": "Apache-2.0"
+    },
+    "node_modules/regenerate": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmmirror.com/regenerate/-/regenerate-1.4.2.tgz",
+      "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/regenerate-unicode-properties": {
+      "version": "10.2.2",
+      "resolved": "https://registry.npmmirror.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz",
+      "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "regenerate": "^1.4.2"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/regenerator-runtime": {
+      "version": "0.14.1",
+      "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+      "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/regex-parser": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmmirror.com/regex-parser/-/regex-parser-2.3.1.tgz",
+      "integrity": "sha512-yXLRqatcCuKtVHsWrNg0JL3l1zGfdXeEvDa0bdu4tCDQw0RpMDZsqbkyRTUnKMR0tXF627V2oEWjBEaEdqTwtQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/regexpu-core": {
+      "version": "6.4.0",
+      "resolved": "https://registry.npmmirror.com/regexpu-core/-/regexpu-core-6.4.0.tgz",
+      "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "regenerate": "^1.4.2",
+        "regenerate-unicode-properties": "^10.2.2",
+        "regjsgen": "^0.8.0",
+        "regjsparser": "^0.13.0",
+        "unicode-match-property-ecmascript": "^2.0.0",
+        "unicode-match-property-value-ecmascript": "^2.2.1"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/regjsgen": {
+      "version": "0.8.0",
+      "resolved": "https://registry.npmmirror.com/regjsgen/-/regjsgen-0.8.0.tgz",
+      "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/regjsparser": {
+      "version": "0.13.0",
+      "resolved": "https://registry.npmmirror.com/regjsparser/-/regjsparser-0.13.0.tgz",
+      "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "jsesc": "~3.1.0"
+      },
+      "bin": {
+        "regjsparser": "bin/parser"
+      }
+    },
+    "node_modules/require-directory": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz",
+      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/require-from-string": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/require-from-string/-/require-from-string-2.0.2.tgz",
+      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/requires-port": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/requires-port/-/requires-port-1.0.0.tgz",
+      "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/resolve": {
+      "version": "1.22.10",
+      "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.10.tgz",
+      "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-core-module": "^2.16.0",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
+      },
+      "bin": {
+        "resolve": "bin/resolve"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/resolve-from": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz",
+      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/resolve-url-loader": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz",
+      "integrity": "sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "adjust-sourcemap-loader": "^4.0.0",
+        "convert-source-map": "^1.7.0",
+        "loader-utils": "^2.0.0",
+        "postcss": "^8.2.14",
+        "source-map": "0.6.1"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/resolve-url-loader/node_modules/loader-utils": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz",
+      "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "big.js": "^5.2.2",
+        "emojis-list": "^3.0.0",
+        "json5": "^2.1.2"
+      },
+      "engines": {
+        "node": ">=8.9.0"
+      }
+    },
+    "node_modules/resolve-url-loader/node_modules/source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/restore-cursor": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/restore-cursor/-/restore-cursor-5.1.0.tgz",
+      "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "onetime": "^7.0.0",
+        "signal-exit": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/retry": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmmirror.com/retry/-/retry-0.12.0.tgz",
+      "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/reusify": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.1.0.tgz",
+      "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "iojs": ">=1.0.0",
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/rfdc": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.4.1.tgz",
+      "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/rimraf": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz",
+      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+      "deprecated": "Rimraf versions prior to v4 are no longer supported",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "glob": "^7.1.3"
+      },
+      "bin": {
+        "rimraf": "bin.js"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/rollup": {
+      "version": "4.34.8",
+      "resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.34.8.tgz",
+      "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/estree": "1.0.6"
+      },
+      "bin": {
+        "rollup": "dist/bin/rollup"
+      },
+      "engines": {
+        "node": ">=18.0.0",
+        "npm": ">=8.0.0"
+      },
+      "optionalDependencies": {
+        "@rollup/rollup-android-arm-eabi": "4.34.8",
+        "@rollup/rollup-android-arm64": "4.34.8",
+        "@rollup/rollup-darwin-arm64": "4.34.8",
+        "@rollup/rollup-darwin-x64": "4.34.8",
+        "@rollup/rollup-freebsd-arm64": "4.34.8",
+        "@rollup/rollup-freebsd-x64": "4.34.8",
+        "@rollup/rollup-linux-arm-gnueabihf": "4.34.8",
+        "@rollup/rollup-linux-arm-musleabihf": "4.34.8",
+        "@rollup/rollup-linux-arm64-gnu": "4.34.8",
+        "@rollup/rollup-linux-arm64-musl": "4.34.8",
+        "@rollup/rollup-linux-loongarch64-gnu": "4.34.8",
+        "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8",
+        "@rollup/rollup-linux-riscv64-gnu": "4.34.8",
+        "@rollup/rollup-linux-s390x-gnu": "4.34.8",
+        "@rollup/rollup-linux-x64-gnu": "4.34.8",
+        "@rollup/rollup-linux-x64-musl": "4.34.8",
+        "@rollup/rollup-win32-arm64-msvc": "4.34.8",
+        "@rollup/rollup-win32-ia32-msvc": "4.34.8",
+        "@rollup/rollup-win32-x64-msvc": "4.34.8",
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/run-applescript": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmmirror.com/run-applescript/-/run-applescript-7.1.0.tgz",
+      "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/run-parallel": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz",
+      "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+      "dev": true,
+      "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",
+      "dependencies": {
+        "queue-microtask": "^1.2.2"
+      }
+    },
+    "node_modules/rxjs": {
+      "version": "7.8.2",
+      "resolved": "https://registry.npmmirror.com/rxjs/-/rxjs-7.8.2.tgz",
+      "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "tslib": "^2.1.0"
+      }
+    },
+    "node_modules/safe-buffer": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
+      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+      "dev": true,
+      "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/safe-regex-test": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+      "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "es-errors": "^1.3.0",
+        "is-regex": "^1.2.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/sass": {
+      "version": "1.85.0",
+      "resolved": "https://registry.npmmirror.com/sass/-/sass-1.85.0.tgz",
+      "integrity": "sha512-3ToiC1xZ1Y8aU7+CkgCI/tqyuPXEmYGJXO7H4uqp0xkLXUqp88rQQ4j1HmP37xSJLbCJPaIiv+cT1y+grssrww==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "chokidar": "^4.0.0",
+        "immutable": "^5.0.2",
+        "source-map-js": ">=0.6.2 <2.0.0"
+      },
+      "bin": {
+        "sass": "sass.js"
+      },
+      "engines": {
+        "node": ">=14.0.0"
+      },
+      "optionalDependencies": {
+        "@parcel/watcher": "^2.4.1"
+      }
+    },
+    "node_modules/sass-loader": {
+      "version": "16.0.5",
+      "resolved": "https://registry.npmmirror.com/sass-loader/-/sass-loader-16.0.5.tgz",
+      "integrity": "sha512-oL+CMBXrj6BZ/zOq4os+UECPL+bWqt6OAC6DWS8Ln8GZRcMDjlJ4JC3FBDuHJdYaFWIdKNIBYmtZtK2MaMkNIw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "neo-async": "^2.6.2"
+      },
+      "engines": {
+        "node": ">= 18.12.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "@rspack/core": "0.x || 1.x",
+        "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0",
+        "sass": "^1.3.0",
+        "sass-embedded": "*",
+        "webpack": "^5.0.0"
+      },
+      "peerDependenciesMeta": {
+        "@rspack/core": {
+          "optional": true
+        },
+        "node-sass": {
+          "optional": true
+        },
+        "sass": {
+          "optional": true
+        },
+        "sass-embedded": {
+          "optional": true
+        },
+        "webpack": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/sass/node_modules/chokidar": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-4.0.3.tgz",
+      "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "readdirp": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 14.16.0"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/sass/node_modules/readdirp": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-4.1.2.tgz",
+      "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 14.18.0"
+      },
+      "funding": {
+        "type": "individual",
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/sax": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmmirror.com/sax/-/sax-1.4.4.tgz",
+      "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "optional": true,
+      "engines": {
+        "node": ">=11.0.0"
+      }
+    },
+    "node_modules/schema-utils": {
+      "version": "4.3.3",
+      "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-4.3.3.tgz",
+      "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/json-schema": "^7.0.9",
+        "ajv": "^8.9.0",
+        "ajv-formats": "^2.1.1",
+        "ajv-keywords": "^5.1.0"
+      },
+      "engines": {
+        "node": ">= 10.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      }
+    },
+    "node_modules/schema-utils/node_modules/ajv-formats": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/ajv-formats/-/ajv-formats-2.1.1.tgz",
+      "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ajv": "^8.0.0"
+      },
+      "peerDependencies": {
+        "ajv": "^8.0.0"
+      },
+      "peerDependenciesMeta": {
+        "ajv": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/select-hose": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/select-hose/-/select-hose-2.0.0.tgz",
+      "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/selfsigned": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmmirror.com/selfsigned/-/selfsigned-2.4.1.tgz",
+      "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/node-forge": "^1.3.0",
+        "node-forge": "^1"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/semver": {
+      "version": "7.7.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.1.tgz",
+      "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+      "dev": true,
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/send": {
+      "version": "0.19.2",
+      "resolved": "https://registry.npmmirror.com/send/-/send-0.19.2.tgz",
+      "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "debug": "2.6.9",
+        "depd": "2.0.0",
+        "destroy": "1.2.0",
+        "encodeurl": "~2.0.0",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "fresh": "~0.5.2",
+        "http-errors": "~2.0.1",
+        "mime": "1.6.0",
+        "ms": "2.1.3",
+        "on-finished": "~2.4.1",
+        "range-parser": "~1.2.1",
+        "statuses": "~2.0.2"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/send/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/send/node_modules/debug/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/send/node_modules/encodeurl": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-2.0.0.tgz",
+      "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/send/node_modules/mime": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz",
+      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "mime": "cli.js"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/send/node_modules/statuses": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.2.tgz",
+      "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/serialize-javascript": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmmirror.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
+      "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "randombytes": "^2.1.0"
+      }
+    },
+    "node_modules/serve-index": {
+      "version": "1.9.2",
+      "resolved": "https://registry.npmmirror.com/serve-index/-/serve-index-1.9.2.tgz",
+      "integrity": "sha512-KDj11HScOaLmrPxl70KYNW1PksP4Nb/CLL2yvC+Qd2kHMPEEpfc4Re2e4FOay+bC/+XQl/7zAcWON3JVo5v3KQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "accepts": "~1.3.8",
+        "batch": "0.6.1",
+        "debug": "2.6.9",
+        "escape-html": "~1.0.3",
+        "http-errors": "~1.8.0",
+        "mime-types": "~2.1.35",
+        "parseurl": "~1.3.3"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/express"
+      }
+    },
+    "node_modules/serve-index/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/serve-index/node_modules/depd": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/depd/-/depd-1.1.2.tgz",
+      "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/serve-index/node_modules/http-errors": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-1.8.1.tgz",
+      "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "depd": "~1.1.2",
+        "inherits": "2.0.4",
+        "setprototypeof": "1.2.0",
+        "statuses": ">= 1.5.0 < 2",
+        "toidentifier": "1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/serve-index/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/serve-static": {
+      "version": "1.16.3",
+      "resolved": "https://registry.npmmirror.com/serve-static/-/serve-static-1.16.3.tgz",
+      "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "encodeurl": "~2.0.0",
+        "escape-html": "~1.0.3",
+        "parseurl": "~1.3.3",
+        "send": "~0.19.1"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/serve-static/node_modules/encodeurl": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-2.0.0.tgz",
+      "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/setprototypeof": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz",
+      "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/shallow-clone": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/shallow-clone/-/shallow-clone-3.0.1.tgz",
+      "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "kind-of": "^6.0.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/shebang-command": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",
+      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "shebang-regex": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/shebang-regex": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz",
+      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/shell-quote": {
+      "version": "1.8.3",
+      "resolved": "https://registry.npmmirror.com/shell-quote/-/shell-quote-1.8.3.tgz",
+      "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/side-channel": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.1.0.tgz",
+      "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "object-inspect": "^1.13.3",
+        "side-channel-list": "^1.0.0",
+        "side-channel-map": "^1.0.1",
+        "side-channel-weakmap": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/side-channel-list": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/side-channel-list/-/side-channel-list-1.0.0.tgz",
+      "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "object-inspect": "^1.13.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/side-channel-map": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/side-channel-map/-/side-channel-map-1.0.1.tgz",
+      "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.5",
+        "object-inspect": "^1.13.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/side-channel-weakmap": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+      "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.5",
+        "object-inspect": "^1.13.3",
+        "side-channel-map": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/signal-exit": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-4.1.0.tgz",
+      "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/sigstore": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/sigstore/-/sigstore-3.1.0.tgz",
+      "integrity": "sha512-ZpzWAFHIFqyFE56dXqgX/DkDRZdz+rRcjoIk/RQU4IX0wiCv1l8S7ZrXDHcCc+uaf+6o7w3h2l3g6GYG5TKN9Q==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@sigstore/bundle": "^3.1.0",
+        "@sigstore/core": "^2.0.0",
+        "@sigstore/protobuf-specs": "^0.4.0",
+        "@sigstore/sign": "^3.1.0",
+        "@sigstore/tuf": "^3.1.0",
+        "@sigstore/verify": "^2.1.0"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/slash": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/slash/-/slash-5.1.0.tgz",
+      "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=14.16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/slice-ansi": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/slice-ansi/-/slice-ansi-5.0.0.tgz",
+      "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-styles": "^6.0.0",
+        "is-fullwidth-code-point": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+      }
+    },
+    "node_modules/slice-ansi/node_modules/ansi-styles": {
+      "version": "6.2.3",
+      "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.3.tgz",
+      "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/smart-buffer": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmmirror.com/smart-buffer/-/smart-buffer-4.2.0.tgz",
+      "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 6.0.0",
+        "npm": ">= 3.0.0"
+      }
+    },
+    "node_modules/socket.io": {
+      "version": "4.8.3",
+      "resolved": "https://registry.npmmirror.com/socket.io/-/socket.io-4.8.3.tgz",
+      "integrity": "sha512-2Dd78bqzzjE6KPkD5fHZmDAKRNe3J15q+YHDrIsy9WEkqttc7GY+kT9OBLSMaPbQaEd0x1BjcmtMtXkfpc+T5A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "accepts": "~1.3.4",
+        "base64id": "~2.0.0",
+        "cors": "~2.8.5",
+        "debug": "~4.4.1",
+        "engine.io": "~6.6.0",
+        "socket.io-adapter": "~2.5.2",
+        "socket.io-parser": "~4.2.4"
+      },
+      "engines": {
+        "node": ">=10.2.0"
+      }
+    },
+    "node_modules/socket.io-adapter": {
+      "version": "2.5.6",
+      "resolved": "https://registry.npmmirror.com/socket.io-adapter/-/socket.io-adapter-2.5.6.tgz",
+      "integrity": "sha512-DkkO/dz7MGln0dHn5bmN3pPy+JmywNICWrJqVWiVOyvXjWQFIv9c2h24JrQLLFJ2aQVQf/Cvl1vblnd4r2apLQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "debug": "~4.4.1",
+        "ws": "~8.18.3"
+      }
+    },
+    "node_modules/socket.io-parser": {
+      "version": "4.2.5",
+      "resolved": "https://registry.npmmirror.com/socket.io-parser/-/socket.io-parser-4.2.5.tgz",
+      "integrity": "sha512-bPMmpy/5WWKHea5Y/jYAP6k74A+hvmRCQaJuJB6I/ML5JZq/KfNieUVo/3Mh7SAqn7TyFdIo6wqYHInG1MU1bQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@socket.io/component-emitter": "~3.1.0",
+        "debug": "~4.4.1"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/sockjs": {
+      "version": "0.3.24",
+      "resolved": "https://registry.npmmirror.com/sockjs/-/sockjs-0.3.24.tgz",
+      "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "faye-websocket": "^0.11.3",
+        "uuid": "^8.3.2",
+        "websocket-driver": "^0.7.4"
+      }
+    },
+    "node_modules/socks": {
+      "version": "2.8.7",
+      "resolved": "https://registry.npmmirror.com/socks/-/socks-2.8.7.tgz",
+      "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==",
+      "dev": true,
+      "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.npmmirror.com/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz",
+      "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==",
+      "dev": true,
+      "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.7.4",
+      "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.7.4.tgz",
+      "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/source-map-js": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz",
+      "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/source-map-loader": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/source-map-loader/-/source-map-loader-5.0.0.tgz",
+      "integrity": "sha512-k2Dur7CbSLcAH73sBcIkV5xjPV4SzqO1NJ7+XaQl8if3VODDUj3FNchNGpqgJSKbvUfJuhVdv8K2Eu8/TNl2eA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "iconv-lite": "^0.6.3",
+        "source-map-js": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 18.12.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "webpack": "^5.72.1"
+      }
+    },
+    "node_modules/source-map-loader/node_modules/iconv-lite": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz",
+      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/source-map-support": {
+      "version": "0.5.21",
+      "resolved": "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz",
+      "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "buffer-from": "^1.0.0",
+        "source-map": "^0.6.0"
+      }
+    },
+    "node_modules/source-map-support/node_modules/source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/spdx-correct": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmmirror.com/spdx-correct/-/spdx-correct-3.2.0.tgz",
+      "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "spdx-expression-parse": "^3.0.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "node_modules/spdx-exceptions": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmmirror.com/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
+      "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
+      "dev": true,
+      "license": "CC-BY-3.0"
+    },
+    "node_modules/spdx-expression-parse": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+      "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "spdx-exceptions": "^2.1.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "node_modules/spdx-license-ids": {
+      "version": "3.0.22",
+      "resolved": "https://registry.npmmirror.com/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz",
+      "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==",
+      "dev": true,
+      "license": "CC0-1.0"
+    },
+    "node_modules/spdy": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/spdy/-/spdy-4.0.2.tgz",
+      "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "debug": "^4.1.0",
+        "handle-thing": "^2.0.0",
+        "http-deceiver": "^1.2.7",
+        "select-hose": "^2.0.0",
+        "spdy-transport": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/spdy-transport": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/spdy-transport/-/spdy-transport-3.0.0.tgz",
+      "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "debug": "^4.1.0",
+        "detect-node": "^2.0.4",
+        "hpack.js": "^2.1.6",
+        "obuf": "^1.1.2",
+        "readable-stream": "^3.0.6",
+        "wbuf": "^1.7.3"
+      }
+    },
+    "node_modules/ssri": {
+      "version": "12.0.0",
+      "resolved": "https://registry.npmmirror.com/ssri/-/ssri-12.0.0.tgz",
+      "integrity": "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "minipass": "^7.0.3"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/statuses": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmmirror.com/statuses/-/statuses-1.5.0.tgz",
+      "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/streamroller": {
+      "version": "3.1.5",
+      "resolved": "https://registry.npmmirror.com/streamroller/-/streamroller-3.1.5.tgz",
+      "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "date-format": "^4.0.14",
+        "debug": "^4.3.4",
+        "fs-extra": "^8.1.0"
+      },
+      "engines": {
+        "node": ">=8.0"
+      }
+    },
+    "node_modules/string_decoder": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz",
+      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "safe-buffer": "~5.2.0"
+      }
+    },
+    "node_modules/string-width": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmmirror.com/string-width/-/string-width-7.2.0.tgz",
+      "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "emoji-regex": "^10.3.0",
+        "get-east-asian-width": "^1.0.0",
+        "strip-ansi": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/string-width-cjs": {
+      "name": "string-width",
+      "version": "4.2.3",
+      "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+      "dev": true,
+      "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/string-width-cjs/node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/string-width/node_modules/ansi-regex": {
+      "version": "6.2.2",
+      "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.2.2.tgz",
+      "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+      }
+    },
+    "node_modules/string-width/node_modules/strip-ansi": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.2.tgz",
+      "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-regex": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+      }
+    },
+    "node_modules/strip-ansi": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz",
+      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/strip-ansi-cjs": {
+      "name": "strip-ansi",
+      "version": "6.0.1",
+      "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz",
+      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/supports-color": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
+      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/supports-preserve-symlinks-flag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/symbol-observable": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/symbol-observable/-/symbol-observable-4.0.0.tgz",
+      "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/tapable": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/tapable/-/tapable-2.3.0.tgz",
+      "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      }
+    },
+    "node_modules/tar": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmmirror.com/tar/-/tar-6.2.1.tgz",
+      "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "chownr": "^2.0.0",
+        "fs-minipass": "^2.0.0",
+        "minipass": "^5.0.0",
+        "minizlib": "^2.1.1",
+        "mkdirp": "^1.0.3",
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/tar/node_modules/fs-minipass": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/fs-minipass/-/fs-minipass-2.1.0.tgz",
+      "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "minipass": "^3.0.0"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": {
+      "version": "3.3.6",
+      "resolved": "https://registry.npmmirror.com/minipass/-/minipass-3.3.6.tgz",
+      "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/tar/node_modules/minipass": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/minipass/-/minipass-5.0.0.tgz",
+      "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/tar/node_modules/minizlib": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmmirror.com/minizlib/-/minizlib-2.1.2.tgz",
+      "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "minipass": "^3.0.0",
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/tar/node_modules/minizlib/node_modules/minipass": {
+      "version": "3.3.6",
+      "resolved": "https://registry.npmmirror.com/minipass/-/minipass-3.3.6.tgz",
+      "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/tar/node_modules/mkdirp": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmmirror.com/mkdirp/-/mkdirp-1.0.4.tgz",
+      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "mkdirp": "bin/cmd.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/tar/node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/terser": {
+      "version": "5.39.0",
+      "resolved": "https://registry.npmmirror.com/terser/-/terser-5.39.0.tgz",
+      "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==",
+      "dev": true,
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "@jridgewell/source-map": "^0.3.3",
+        "acorn": "^8.8.2",
+        "commander": "^2.20.0",
+        "source-map-support": "~0.5.20"
+      },
+      "bin": {
+        "terser": "bin/terser"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/terser-webpack-plugin": {
+      "version": "5.3.16",
+      "resolved": "https://registry.npmmirror.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz",
+      "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@jridgewell/trace-mapping": "^0.3.25",
+        "jest-worker": "^27.4.5",
+        "schema-utils": "^4.3.0",
+        "serialize-javascript": "^6.0.2",
+        "terser": "^5.31.1"
+      },
+      "engines": {
+        "node": ">= 10.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "webpack": "^5.1.0"
+      },
+      "peerDependenciesMeta": {
+        "@swc/core": {
+          "optional": true
+        },
+        "esbuild": {
+          "optional": true
+        },
+        "uglify-js": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/thingies": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmmirror.com/thingies/-/thingies-2.5.0.tgz",
+      "integrity": "sha512-s+2Bwztg6PhWUD7XMfeYm5qliDdSiZm7M7n8KjTkIsm3l/2lgVRc2/Gx/v+ZX8lT4FMA+i8aQvhcWylldc+ZNw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=10.18"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "^2"
+      }
+    },
+    "node_modules/thunky": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/thunky/-/thunky-1.1.0.tgz",
+      "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/tinyglobby": {
+      "version": "0.2.15",
+      "resolved": "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.15.tgz",
+      "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "fdir": "^6.5.0",
+        "picomatch": "^4.0.3"
+      },
+      "engines": {
+        "node": ">=12.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/SuperchupuDev"
+      }
+    },
+    "node_modules/tinyglobby/node_modules/picomatch": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz",
+      "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/to-regex-range": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz",
+      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-number": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=8.0"
+      }
+    },
+    "node_modules/toidentifier": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz",
+      "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/tree-dump": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/tree-dump/-/tree-dump-1.1.0.tgz",
+      "integrity": "sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=10.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/streamich"
+      },
+      "peerDependencies": {
+        "tslib": "2"
+      }
+    },
+    "node_modules/tree-kill": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmmirror.com/tree-kill/-/tree-kill-1.2.2.tgz",
+      "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "tree-kill": "cli.js"
+      }
+    },
+    "node_modules/tslib": {
+      "version": "2.8.1",
+      "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.8.1.tgz",
+      "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+      "license": "0BSD"
+    },
+    "node_modules/tuf-js": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/tuf-js/-/tuf-js-3.1.0.tgz",
+      "integrity": "sha512-3T3T04WzowbwV2FDiGXBbr81t64g1MUGGJRgT4x5o97N+8ArdhVCAF9IxFrxuSJmM3E5Asn7nKHkao0ibcZXAg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@tufjs/models": "3.0.1",
+        "debug": "^4.4.1",
+        "make-fetch-happen": "^14.0.3"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/type-is": {
+      "version": "1.6.18",
+      "resolved": "https://registry.npmmirror.com/type-is/-/type-is-1.6.18.tgz",
+      "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "media-typer": "0.3.0",
+        "mime-types": "~2.1.24"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/typed-assert": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmmirror.com/typed-assert/-/typed-assert-1.0.9.tgz",
+      "integrity": "sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/typescript": {
+      "version": "5.5.4",
+      "resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.5.4.tgz",
+      "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "bin": {
+        "tsc": "bin/tsc",
+        "tsserver": "bin/tsserver"
+      },
+      "engines": {
+        "node": ">=14.17"
+      }
+    },
+    "node_modules/ua-parser-js": {
+      "version": "0.7.41",
+      "resolved": "https://registry.npmmirror.com/ua-parser-js/-/ua-parser-js-0.7.41.tgz",
+      "integrity": "sha512-O3oYyCMPYgNNHuO7Jjk3uacJWZF8loBgwrfd/5LE/HyZ3lUIOdniQ7DNXJcIgZbwioZxk0fLfI4EVnetdiX5jg==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/ua-parser-js"
+        },
+        {
+          "type": "paypal",
+          "url": "https://paypal.me/faisalman"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/faisalman"
+        }
+      ],
+      "license": "MIT",
+      "bin": {
+        "ua-parser-js": "script/cli.js"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/undici-types": {
+      "version": "6.21.0",
+      "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.21.0.tgz",
+      "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/unicode-canonical-property-names-ecmascript": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz",
+      "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/unicode-match-property-ecmascript": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
+      "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "unicode-canonical-property-names-ecmascript": "^2.0.0",
+        "unicode-property-aliases-ecmascript": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/unicode-match-property-value-ecmascript": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmmirror.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz",
+      "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/unicode-property-aliases-ecmascript": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmmirror.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz",
+      "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/unicorn-magic": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmmirror.com/unicorn-magic/-/unicorn-magic-0.3.0.tgz",
+      "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/unique-filename": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/unique-filename/-/unique-filename-4.0.0.tgz",
+      "integrity": "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "unique-slug": "^5.0.0"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/unique-slug": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/unique-slug/-/unique-slug-5.0.0.tgz",
+      "integrity": "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "imurmurhash": "^0.1.4"
+      },
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/universalify": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmmirror.com/universalify/-/universalify-0.1.2.tgz",
+      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 4.0.0"
+      }
+    },
+    "node_modules/unpipe": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/unpipe/-/unpipe-1.0.0.tgz",
+      "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/update-browserslist-db": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
+      "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "escalade": "^3.2.0",
+        "picocolors": "^1.1.1"
+      },
+      "bin": {
+        "update-browserslist-db": "cli.js"
+      },
+      "peerDependencies": {
+        "browserslist": ">= 4.21.0"
+      }
+    },
+    "node_modules/util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/utils-merge": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz",
+      "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/uuid": {
+      "version": "8.3.2",
+      "resolved": "https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz",
+      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "uuid": "dist/bin/uuid"
+      }
+    },
+    "node_modules/validate-npm-package-license": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmmirror.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+      "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "spdx-correct": "^3.0.0",
+        "spdx-expression-parse": "^3.0.0"
+      }
+    },
+    "node_modules/validate-npm-package-name": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmmirror.com/validate-npm-package-name/-/validate-npm-package-name-6.0.2.tgz",
+      "integrity": "sha512-IUoow1YUtvoBBC06dXs8bR8B9vuA3aJfmQNKMoaPG/OFsPmoQvw8xh+6Ye25Gx9DQhoEom3Pcu9MKHerm/NpUQ==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": "^18.17.0 || >=20.5.0"
+      }
+    },
+    "node_modules/vary": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz",
+      "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/vite": {
+      "version": "6.4.1",
+      "resolved": "https://registry.npmmirror.com/vite/-/vite-6.4.1.tgz",
+      "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "esbuild": "^0.25.0",
+        "fdir": "^6.4.4",
+        "picomatch": "^4.0.2",
+        "postcss": "^8.5.3",
+        "rollup": "^4.34.9",
+        "tinyglobby": "^0.2.13"
+      },
+      "bin": {
+        "vite": "bin/vite.js"
+      },
+      "engines": {
+        "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/vitejs/vite?sponsor=1"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.3"
+      },
+      "peerDependencies": {
+        "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+        "jiti": ">=1.21.0",
+        "less": "*",
+        "lightningcss": "^1.21.0",
+        "sass": "*",
+        "sass-embedded": "*",
+        "stylus": "*",
+        "sugarss": "*",
+        "terser": "^5.16.0",
+        "tsx": "^4.8.1",
+        "yaml": "^2.4.2"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        },
+        "jiti": {
+          "optional": true
+        },
+        "less": {
+          "optional": true
+        },
+        "lightningcss": {
+          "optional": true
+        },
+        "sass": {
+          "optional": true
+        },
+        "sass-embedded": {
+          "optional": true
+        },
+        "stylus": {
+          "optional": true
+        },
+        "sugarss": {
+          "optional": true
+        },
+        "terser": {
+          "optional": true
+        },
+        "tsx": {
+          "optional": true
+        },
+        "yaml": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/vite/node_modules/@rollup/rollup-android-arm-eabi": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.1.tgz",
+      "integrity": "sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ]
+    },
+    "node_modules/vite/node_modules/@rollup/rollup-android-arm64": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.57.1.tgz",
+      "integrity": "sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ]
+    },
+    "node_modules/vite/node_modules/@rollup/rollup-darwin-arm64": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.57.1.tgz",
+      "integrity": "sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/vite/node_modules/@rollup/rollup-darwin-x64": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.57.1.tgz",
+      "integrity": "sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/vite/node_modules/@rollup/rollup-freebsd-arm64": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.57.1.tgz",
+      "integrity": "sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ]
+    },
+    "node_modules/vite/node_modules/@rollup/rollup-freebsd-x64": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.57.1.tgz",
+      "integrity": "sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ]
+    },
+    "node_modules/vite/node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.57.1.tgz",
+      "integrity": "sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/vite/node_modules/@rollup/rollup-linux-arm-musleabihf": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.57.1.tgz",
+      "integrity": "sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/vite/node_modules/@rollup/rollup-linux-arm64-gnu": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.57.1.tgz",
+      "integrity": "sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/vite/node_modules/@rollup/rollup-linux-arm64-musl": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.57.1.tgz",
+      "integrity": "sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/vite/node_modules/@rollup/rollup-linux-riscv64-gnu": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.57.1.tgz",
+      "integrity": "sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/vite/node_modules/@rollup/rollup-linux-s390x-gnu": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.57.1.tgz",
+      "integrity": "sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/vite/node_modules/@rollup/rollup-linux-x64-gnu": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.57.1.tgz",
+      "integrity": "sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/vite/node_modules/@rollup/rollup-linux-x64-musl": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.57.1.tgz",
+      "integrity": "sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/vite/node_modules/@rollup/rollup-win32-arm64-msvc": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.57.1.tgz",
+      "integrity": "sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/vite/node_modules/@rollup/rollup-win32-ia32-msvc": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.57.1.tgz",
+      "integrity": "sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/vite/node_modules/@rollup/rollup-win32-x64-msvc": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.57.1.tgz",
+      "integrity": "sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/vite/node_modules/@types/estree": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.8.tgz",
+      "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/vite/node_modules/rollup": {
+      "version": "4.57.1",
+      "resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.57.1.tgz",
+      "integrity": "sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/estree": "1.0.8"
+      },
+      "bin": {
+        "rollup": "dist/bin/rollup"
+      },
+      "engines": {
+        "node": ">=18.0.0",
+        "npm": ">=8.0.0"
+      },
+      "optionalDependencies": {
+        "@rollup/rollup-android-arm-eabi": "4.57.1",
+        "@rollup/rollup-android-arm64": "4.57.1",
+        "@rollup/rollup-darwin-arm64": "4.57.1",
+        "@rollup/rollup-darwin-x64": "4.57.1",
+        "@rollup/rollup-freebsd-arm64": "4.57.1",
+        "@rollup/rollup-freebsd-x64": "4.57.1",
+        "@rollup/rollup-linux-arm-gnueabihf": "4.57.1",
+        "@rollup/rollup-linux-arm-musleabihf": "4.57.1",
+        "@rollup/rollup-linux-arm64-gnu": "4.57.1",
+        "@rollup/rollup-linux-arm64-musl": "4.57.1",
+        "@rollup/rollup-linux-loong64-gnu": "4.57.1",
+        "@rollup/rollup-linux-loong64-musl": "4.57.1",
+        "@rollup/rollup-linux-ppc64-gnu": "4.57.1",
+        "@rollup/rollup-linux-ppc64-musl": "4.57.1",
+        "@rollup/rollup-linux-riscv64-gnu": "4.57.1",
+        "@rollup/rollup-linux-riscv64-musl": "4.57.1",
+        "@rollup/rollup-linux-s390x-gnu": "4.57.1",
+        "@rollup/rollup-linux-x64-gnu": "4.57.1",
+        "@rollup/rollup-linux-x64-musl": "4.57.1",
+        "@rollup/rollup-openbsd-x64": "4.57.1",
+        "@rollup/rollup-openharmony-arm64": "4.57.1",
+        "@rollup/rollup-win32-arm64-msvc": "4.57.1",
+        "@rollup/rollup-win32-ia32-msvc": "4.57.1",
+        "@rollup/rollup-win32-x64-gnu": "4.57.1",
+        "@rollup/rollup-win32-x64-msvc": "4.57.1",
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/void-elements": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/void-elements/-/void-elements-2.0.1.tgz",
+      "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/watchpack": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmmirror.com/watchpack/-/watchpack-2.4.2.tgz",
+      "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "glob-to-regexp": "^0.4.1",
+        "graceful-fs": "^4.1.2"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/wbuf": {
+      "version": "1.7.3",
+      "resolved": "https://registry.npmmirror.com/wbuf/-/wbuf-1.7.3.tgz",
+      "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "node_modules/wcwidth": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/wcwidth/-/wcwidth-1.0.1.tgz",
+      "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "defaults": "^1.0.3"
+      }
+    },
+    "node_modules/weak-lru-cache": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmmirror.com/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz",
+      "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/webpack": {
+      "version": "5.98.0",
+      "resolved": "https://registry.npmmirror.com/webpack/-/webpack-5.98.0.tgz",
+      "integrity": "sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/eslint-scope": "^3.7.7",
+        "@types/estree": "^1.0.6",
+        "@webassemblyjs/ast": "^1.14.1",
+        "@webassemblyjs/wasm-edit": "^1.14.1",
+        "@webassemblyjs/wasm-parser": "^1.14.1",
+        "acorn": "^8.14.0",
+        "browserslist": "^4.24.0",
+        "chrome-trace-event": "^1.0.2",
+        "enhanced-resolve": "^5.17.1",
+        "es-module-lexer": "^1.2.1",
+        "eslint-scope": "5.1.1",
+        "events": "^3.2.0",
+        "glob-to-regexp": "^0.4.1",
+        "graceful-fs": "^4.2.11",
+        "json-parse-even-better-errors": "^2.3.1",
+        "loader-runner": "^4.2.0",
+        "mime-types": "^2.1.27",
+        "neo-async": "^2.6.2",
+        "schema-utils": "^4.3.0",
+        "tapable": "^2.1.1",
+        "terser-webpack-plugin": "^5.3.11",
+        "watchpack": "^2.4.1",
+        "webpack-sources": "^3.2.3"
+      },
+      "bin": {
+        "webpack": "bin/webpack.js"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependenciesMeta": {
+        "webpack-cli": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/webpack-dev-middleware": {
+      "version": "7.4.2",
+      "resolved": "https://registry.npmmirror.com/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz",
+      "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "colorette": "^2.0.10",
+        "memfs": "^4.6.0",
+        "mime-types": "^2.1.31",
+        "on-finished": "^2.4.1",
+        "range-parser": "^1.2.1",
+        "schema-utils": "^4.0.0"
+      },
+      "engines": {
+        "node": ">= 18.12.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "webpack": "^5.0.0"
+      },
+      "peerDependenciesMeta": {
+        "webpack": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/webpack-dev-server": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npmmirror.com/webpack-dev-server/-/webpack-dev-server-5.2.2.tgz",
+      "integrity": "sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/bonjour": "^3.5.13",
+        "@types/connect-history-api-fallback": "^1.5.4",
+        "@types/express": "^4.17.21",
+        "@types/express-serve-static-core": "^4.17.21",
+        "@types/serve-index": "^1.9.4",
+        "@types/serve-static": "^1.15.5",
+        "@types/sockjs": "^0.3.36",
+        "@types/ws": "^8.5.10",
+        "ansi-html-community": "^0.0.8",
+        "bonjour-service": "^1.2.1",
+        "chokidar": "^3.6.0",
+        "colorette": "^2.0.10",
+        "compression": "^1.7.4",
+        "connect-history-api-fallback": "^2.0.0",
+        "express": "^4.21.2",
+        "graceful-fs": "^4.2.6",
+        "http-proxy-middleware": "^2.0.9",
+        "ipaddr.js": "^2.1.0",
+        "launch-editor": "^2.6.1",
+        "open": "^10.0.3",
+        "p-retry": "^6.2.0",
+        "schema-utils": "^4.2.0",
+        "selfsigned": "^2.4.1",
+        "serve-index": "^1.9.1",
+        "sockjs": "^0.3.24",
+        "spdy": "^4.0.2",
+        "webpack-dev-middleware": "^7.4.2",
+        "ws": "^8.18.0"
+      },
+      "bin": {
+        "webpack-dev-server": "bin/webpack-dev-server.js"
+      },
+      "engines": {
+        "node": ">= 18.12.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "webpack": "^5.0.0"
+      },
+      "peerDependenciesMeta": {
+        "webpack": {
+          "optional": true
+        },
+        "webpack-cli": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": {
+      "version": "2.0.9",
+      "resolved": "https://registry.npmmirror.com/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz",
+      "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/http-proxy": "^1.17.8",
+        "http-proxy": "^1.18.1",
+        "is-glob": "^4.0.1",
+        "is-plain-obj": "^3.0.0",
+        "micromatch": "^4.0.2"
+      },
+      "engines": {
+        "node": ">=12.0.0"
+      },
+      "peerDependencies": {
+        "@types/express": "^4.17.13"
+      },
+      "peerDependenciesMeta": {
+        "@types/express": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/webpack-merge": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmmirror.com/webpack-merge/-/webpack-merge-6.0.1.tgz",
+      "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "clone-deep": "^4.0.1",
+        "flat": "^5.0.2",
+        "wildcard": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      }
+    },
+    "node_modules/webpack-sources": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmmirror.com/webpack-sources/-/webpack-sources-3.3.3.tgz",
+      "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/webpack-subresource-integrity": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz",
+      "integrity": "sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "typed-assert": "^1.0.8"
+      },
+      "engines": {
+        "node": ">= 12"
+      },
+      "peerDependencies": {
+        "html-webpack-plugin": ">= 5.0.0-beta.1 < 6",
+        "webpack": "^5.12.0"
+      },
+      "peerDependenciesMeta": {
+        "html-webpack-plugin": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/webpack/node_modules/json-parse-even-better-errors": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmmirror.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/websocket-driver": {
+      "version": "0.7.4",
+      "resolved": "https://registry.npmmirror.com/websocket-driver/-/websocket-driver-0.7.4.tgz",
+      "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "http-parser-js": ">=0.5.1",
+        "safe-buffer": ">=5.1.0",
+        "websocket-extensions": ">=0.1.1"
+      },
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/websocket-extensions": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmmirror.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
+      "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/which": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmmirror.com/which/-/which-1.3.1.tgz",
+      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "which": "bin/which"
+      }
+    },
+    "node_modules/wildcard": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/wildcard/-/wildcard-2.0.1.tgz",
+      "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/wrap-ansi": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+      "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/wrap-ansi-cjs": {
+      "name": "wrap-ansi",
+      "version": "7.0.0",
+      "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+      "dev": true,
+      "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/wrap-ansi-cjs/node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/wrap-ansi-cjs/node_modules/string-width": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+      "dev": true,
+      "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/wrap-ansi/node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/wrap-ansi/node_modules/string-width": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+      "dev": true,
+      "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/wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/ws": {
+      "version": "8.18.3",
+      "resolved": "https://registry.npmmirror.com/ws/-/ws-8.18.3.tgz",
+      "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=10.0.0"
+      },
+      "peerDependencies": {
+        "bufferutil": "^4.0.1",
+        "utf-8-validate": ">=5.0.2"
+      },
+      "peerDependenciesMeta": {
+        "bufferutil": {
+          "optional": true
+        },
+        "utf-8-validate": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/y18n": {
+      "version": "5.0.8",
+      "resolved": "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz",
+      "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/yallist": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz",
+      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/yargs": {
+      "version": "17.7.2",
+      "resolved": "https://registry.npmmirror.com/yargs/-/yargs-17.7.2.tgz",
+      "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+      "dev": true,
+      "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/yargs-parser": {
+      "version": "21.1.1",
+      "resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-21.1.1.tgz",
+      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/yargs/node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/yargs/node_modules/is-fullwidth-code-point": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/yargs/node_modules/string-width": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+      "dev": true,
+      "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/yocto-queue": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-1.2.2.tgz",
+      "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12.20"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/yoctocolors-cjs": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmmirror.com/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz",
+      "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/zone.js": {
+      "version": "0.15.1",
+      "resolved": "https://registry.npmmirror.com/zone.js/-/zone.js-0.15.1.tgz",
+      "integrity": "sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w==",
+      "license": "MIT"
+    }
+  }
+}

+ 40 - 0
lead-discovery/package.json

@@ -0,0 +1,40 @@
+{
+  "name": "lead-discovery",
+  "version": "0.0.0",
+  "scripts": {
+    "ng": "ng",
+    "start": "ng serve",
+    "build": "ng build",
+    "watch": "ng build --watch --configuration development",
+    "test": "ng test"
+  },
+  "private": true,
+  "dependencies": {
+    "@angular/animations": "^19.2.18",
+    "@angular/cdk": "^19.2.19",
+    "@angular/common": "^19.2.18",
+    "@angular/compiler": "^19.2.18",
+    "@angular/core": "^19.2.18",
+    "@angular/forms": "^19.2.18",
+    "@angular/material": "^19.2.19",
+    "@angular/platform-browser": "^19.2.18",
+    "@angular/platform-browser-dynamic": "^19.2.18",
+    "@angular/router": "^19.2.18",
+    "rxjs": "~7.8.0",
+    "tslib": "^2.3.0",
+    "zone.js": "~0.15.1"
+  },
+  "devDependencies": {
+    "@angular-devkit/build-angular": "^19.2.19",
+    "@angular/cli": "^19.2.19",
+    "@angular/compiler-cli": "^19.2.18",
+    "@types/jasmine": "~5.1.0",
+    "jasmine-core": "~5.2.0",
+    "karma": "~6.4.0",
+    "karma-chrome-launcher": "~3.2.0",
+    "karma-coverage": "~2.2.0",
+    "karma-jasmine": "~5.1.0",
+    "karma-jasmine-html-reporter": "~2.1.0",
+    "typescript": "~5.5.2"
+  }
+}

BIN
lead-discovery/public/favicon.ico


+ 0 - 0
lead-discovery/src/app/app.component.scss


+ 130 - 0
lead-discovery/src/app/app.component.ts

@@ -0,0 +1,130 @@
+import { Component } from '@angular/core';
+import { RouterOutlet, RouterLink, RouterLinkActive } from '@angular/router';
+import { MatToolbarModule } from '@angular/material/toolbar';
+import { MatSidenavModule } from '@angular/material/sidenav';
+import { MatIconModule } from '@angular/material/icon';
+import { MatButtonModule } from '@angular/material/button';
+import { MatListModule } from '@angular/material/list';
+import { MatBadgeModule } from '@angular/material/badge';
+
+@Component({
+    selector: 'app-root',
+    imports: [
+        RouterOutlet, RouterLink, RouterLinkActive,
+        MatToolbarModule, MatSidenavModule, MatIconModule,
+        MatButtonModule, MatListModule, MatBadgeModule,
+    ],
+    template: `
+    <div class="app-shell">
+      <!-- Top Bar -->
+      <mat-toolbar class="top-bar">
+        <button mat-icon-button (click)="sidenavOpen = !sidenavOpen">
+          <mat-icon>menu</mat-icon>
+        </button>
+        <span class="brand">
+          <mat-icon class="brand-icon">local_hospital</mat-icon>
+          线索管理
+        </span>
+        <span class="spacer"></span>
+        <span class="env-badge">DEMO</span>
+      </mat-toolbar>
+
+      <mat-sidenav-container class="sidenav-container">
+        <!-- Side Nav -->
+        <mat-sidenav [opened]="sidenavOpen" mode="side" class="sidenav">
+          <mat-nav-list>
+            <a mat-list-item routerLink="/dashboard" routerLinkActive="active-link">
+              <mat-icon matListItemIcon>auto_awesome</mat-icon>
+              <span matListItemTitle>AI 工作台</span>
+              <span class="nav-badge" matListItemMeta>5</span>
+            </a>
+            <a mat-list-item routerLink="/list" routerLinkActive="active-link">
+              <mat-icon matListItemIcon>hub</mat-icon>
+              <span matListItemTitle>线索中心</span>
+              <span class="nav-badge" matListItemMeta>10</span>
+            </a>
+            <a mat-list-item routerLink="/personas" routerLinkActive="active-link">
+              <mat-icon matListItemIcon>psychology</mat-icon>
+              <span matListItemTitle>画像知识库</span>
+            </a>
+            <a mat-list-item routerLink="/products" routerLinkActive="active-link">
+              <mat-icon matListItemIcon>inventory_2</mat-icon>
+              <span matListItemTitle>产品目录</span>
+            </a>
+          </mat-nav-list>
+        </mat-sidenav>
+
+        <!-- Main Content -->
+        <mat-sidenav-content class="main-content">
+          <router-outlet></router-outlet>
+        </mat-sidenav-content>
+      </mat-sidenav-container>
+    </div>
+  `,
+    styles: [`
+    :host {
+      display: flex;
+      flex-direction: column;
+      height: 100vh;
+      overflow: hidden;
+    }
+    .app-shell {
+      display: flex;
+      flex-direction: column;
+      height: 100%;
+    }
+    .top-bar {
+      background: linear-gradient(135deg, #1565c0, #0d47a1);
+      color: #fff;
+      z-index: 100;
+      box-shadow: 0 2px 8px rgba(0,0,0,0.15);
+      flex-shrink: 0;
+    }
+    .brand {
+      display: flex;
+      align-items: center;
+      gap: 8px;
+      font-size: 18px;
+      font-weight: 500;
+      margin-left: 8px;
+    }
+    .brand-icon { font-size: 24px; }
+    .spacer { flex: 1; }
+    .env-badge {
+      background: rgba(255,255,255,0.2);
+      padding: 2px 12px;
+      border-radius: 12px;
+      font-size: 12px;
+      font-weight: 500;
+      letter-spacing: 1px;
+    }
+    .sidenav-container {
+      flex: 1;
+      background: #f5f7fa;
+    }
+    .sidenav {
+      width: 220px;
+      background: #fff;
+      border-right: 1px solid #e8e8e8;
+    }
+    .main-content {
+      background: #f5f7fa;
+    }
+    .active-link {
+      background: #e3f2fd !important;
+      color: #1565c0 !important;
+      border-right: 3px solid #1565c0;
+    }
+    .nav-badge {
+      background: #e0e0e0;
+      color: #555;
+      padding: 1px 8px;
+      border-radius: 10px;
+      font-size: 11px;
+      font-weight: 600;
+    }
+  `]
+})
+export class AppComponent {
+  sidenavOpen = true;
+}

+ 15 - 0
lead-discovery/src/app/app.config.ts

@@ -0,0 +1,15 @@
+import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
+import { provideRouter } from '@angular/router';
+import { provideHttpClient } from '@angular/common/http';
+
+import { routes } from './app.routes';
+import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
+
+export const appConfig: ApplicationConfig = {
+  providers: [
+    provideZoneChangeDetection({ eventCoalescing: true }),
+    provideRouter(routes),
+    provideAnimationsAsync(),
+    provideHttpClient(),
+  ]
+};

+ 28 - 0
lead-discovery/src/app/app.routes.ts

@@ -0,0 +1,28 @@
+import { Routes } from '@angular/router';
+
+export const routes: Routes = [
+  { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
+  {
+    path: 'dashboard',
+    loadComponent: () => import('./pages/dashboard/dashboard.component').then(m => m.DashboardComponent),
+  },
+  {
+    path: 'list',
+    loadComponent: () => import('./pages/list/list.component').then(m => m.ListComponent),
+  },
+  {
+    path: 'leads/:id',
+    loadComponent: () => import('./pages/lead-detail/lead-detail.component').then(m => m.LeadDetailComponent),
+  },
+  {
+    path: 'personas',
+    loadComponent: () => import('./pages/personas/personas.component').then(m => m.PersonasComponent),
+  },
+  {
+    path: 'products',
+    loadComponent: () => import('./pages/product-catalog/product-catalog.component').then(m => m.ProductCatalogComponent),
+  },
+  // Redirects for old routes
+  { path: 'kanban', redirectTo: 'list', pathMatch: 'full' },
+  { path: 'leads', redirectTo: 'list', pathMatch: 'full' },
+];

+ 179 - 0
lead-discovery/src/app/components/deep-research-package/deep-research-package.component.html

@@ -0,0 +1,179 @@
+<div class="research-package-card">
+  <!-- Header -->
+  <div class="package-header">
+    <mat-icon class="package-icon">folder_special</mat-icon>
+    <h2>📋 跟进准备包 — {{ lead?.companyName || '客户' }}</h2>
+  </div>
+
+  <!-- Company Profile -->
+  <div class="section-card">
+    <div class="section-header">
+      <mat-icon>business</mat-icon>
+      <h3>🏢 公司画像</h3>
+    </div>
+    <div class="section-content">
+      <p class="profile-description">{{ researchResult?.companyProfile?.description || '暂无描述' }}</p>
+      <div class="profile-details" *ngIf="researchResult?.companyProfile">
+        <div class="detail-item" *ngIf="researchResult?.companyProfile?.coverage?.length">
+          <span class="detail-label">覆盖区域:</span>
+          <span class="detail-value">{{ researchResult?.companyProfile?.coverage?.join('、') }}</span>
+        </div>
+        <div class="detail-item" *ngIf="researchResult?.companyProfile?.employees">
+          <span class="detail-label">LinkedIn:</span>
+          <span class="detail-value">约 {{ researchResult?.companyProfile?.employees }} 员工</span>
+        </div>
+        <div class="detail-item" *ngIf="researchResult?.companyProfile?.productLines?.length">
+          <span class="detail-label">官网产品线:</span>
+          <span class="detail-value">{{ researchResult?.companyProfile?.productLines?.join('、') }}</span>
+        </div>
+      </div>
+    </div>
+  </div>
+
+  <!-- Contact Profile -->
+  <div class="section-card">
+    <div class="section-header">
+      <mat-icon>person</mat-icon>
+      <h3>👤 联系人画像</h3>
+    </div>
+    <div class="section-content">
+      <div class="contact-info" *ngIf="researchResult?.contactProfile">
+        <div class="contact-name-title">
+          <span class="contact-name">{{ researchResult?.contactProfile?.name }}</span>
+          <span class="contact-title">— {{ researchResult?.contactProfile?.title }}</span>
+        </div>
+        <div class="contact-details">
+          <div class="detail-item">
+            <span class="detail-label">决策权限:</span>
+            <span class="detail-value decision-power" [class]="'power-' + (researchResult?.contactProfile?.decisionPower || 'low')">
+              {{ getDecisionPowerLabel(researchResult?.contactProfile?.decisionPower || 'low') }}
+            </span>
+          </div>
+          <div class="detail-item" *ngIf="researchResult?.contactProfile?.linkedInSummary">
+            <span class="detail-label">LinkedIn:</span>
+            <span class="detail-value">{{ researchResult?.contactProfile?.linkedInSummary }}</span>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+
+  <!-- Product Matching Table -->
+  <div class="section-card" *ngIf="researchResult?.productMatching?.length">
+    <div class="section-header">
+      <mat-icon>shopping_cart</mat-icon>
+      <h3>📦 需求 vs 我方产品匹配</h3>
+    </div>
+    <div class="section-content">
+      <table class="matching-table">
+        <thead>
+          <tr>
+            <th>客户需求</th>
+            <th>推荐产品</th>
+            <th>年采购额</th>
+          </tr>
+        </thead>
+        <tbody>
+          <tr *ngFor="let match of researchResult?.productMatching">
+            <td>{{ match?.customerNeed }}</td>
+            <td>
+              <span class="product-name">{{ match?.recommendedProduct?.name }}</span>
+              <span class="product-sku">({{ match?.recommendedProduct?.sku }})</span>
+            </td>
+            <td class="value-cell">${{ formatNumber(match?.annualValue || 0) }}</td>
+          </tr>
+        </tbody>
+      </table>
+      <div class="total-value-row" *ngIf="researchResult?.totalEstimatedValue">
+        💰 预估年采购总额:${{ formatNumber(researchResult?.totalEstimatedValue || 0) }}
+      </div>
+    </div>
+  </div>
+
+  <!-- Certification Match -->
+  <div class="section-card" *ngIf="researchResult?.certificationMatch?.length">
+    <div class="section-header">
+      <mat-icon>verified</mat-icon>
+      <h3>✅ 认证匹配检查</h3>
+    </div>
+    <div class="section-content">
+      <div class="cert-list">
+        <div class="cert-item" *ngFor="let cert of researchResult?.certificationMatch">
+          <span class="cert-name">· {{ cert?.required }}</span>
+          <span class="cert-status" [class]="'status-' + (cert?.status || 'missing')">
+            <mat-icon>{{ cert?.status === 'matched' ? 'check_circle' : 'cancel' }}</mat-icon>
+            {{ cert?.status === 'matched' ? '✅ 我方已有' : '❌ 我方无' }}
+          </span>
+          <span class="cert-our" *ngIf="cert?.ourCert">({{ cert?.ourCert }})</span>
+        </div>
+      </div>
+    </div>
+  </div>
+
+  <!-- Follow-up Strategy -->
+  <div class="section-card" *ngIf="researchResult?.followUpStrategy">
+    <div class="section-header">
+      <mat-icon>lightbulb</mat-icon>
+      <h3>🎯 建议跟进策略</h3>
+    </div>
+    <div class="section-content">
+      <div class="strategy-steps">
+        <div class="strategy-step">
+          <span class="step-number">1.</span>
+          <span class="step-timeframe">{{ researchResult?.followUpStrategy?.timeframe }}</span>内回复邮件,附上:
+          <ul class="files-list">
+            <li *ngFor="let file of researchResult?.followUpStrategy?.filesToSend">· {{ file }}</li>
+          </ul>
+        </div>
+        <div class="strategy-step" *ngIf="researchResult?.followUpStrategy?.additionalActions?.length">
+          <span class="step-number">2.</span>
+          <span class="step-content" *ngFor="let action of researchResult?.followUpStrategy?.additionalActions">
+            {{ action }}
+          </span>
+        </div>
+        <div class="strategy-step">
+          <span class="step-number">3.</span>
+          重点强调:
+          <span class="key-points">
+            <span class="key-point" *ngFor="let point of researchResult?.followUpStrategy?.keyPoints; let last = last">
+              {{ point }}<span *ngIf="!last">、</span>
+            </span>
+          </span>
+        </div>
+      </div>
+    </div>
+  </div>
+
+  <!-- Suggested Script -->
+  <div class="section-card" *ngIf="researchResult?.suggestedScript">
+    <div class="section-header">
+      <mat-icon>edit</mat-icon>
+      <h3>📝 建议回复话术(可编辑)</h3>
+    </div>
+    <div class="section-content">
+      <mat-form-field appearance="outline" class="script-field">
+        <textarea
+          matInput
+          [(ngModel)]="editedScript"
+          rows="12"
+          [readonly]="!researchResult?.suggestedScript?.editable"
+          placeholder="AI 生成的个性化回复草稿...">
+        </textarea>
+      </mat-form-field>
+    </div>
+  </div>
+
+  <!-- Action Buttons -->
+  <div class="action-buttons">
+    <button mat-stroked-button (click)="editScript.emit()" *ngIf="researchResult?.suggestedScript?.editable">
+      <mat-icon>edit</mat-icon> 编辑话术
+    </button>
+    <button mat-raised-button color="primary" (click)="sendEmail.emit()">
+      <mat-icon>email</mat-icon> 发送邮件
+    </button>
+    <button mat-raised-button color="accent" (click)="createLead.emit()">
+      <mat-icon>check_circle</mat-icon> 建档并设置提醒
+    </button>
+  </div>
+</div>
+

+ 268 - 0
lead-discovery/src/app/components/deep-research-package/deep-research-package.component.scss

@@ -0,0 +1,268 @@
+.research-package-card {
+  background: #fff;
+  border-radius: 16px;
+  padding: 24px;
+  box-shadow: 0 4px 20px rgba(0,0,0,0.1);
+  max-width: 900px;
+}
+
+.package-header {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+  margin-bottom: 24px;
+  padding-bottom: 16px;
+  border-bottom: 2px solid #e0e0e0;
+}
+.package-icon {
+  font-size: 32px;
+  width: 32px;
+  height: 32px;
+  color: #1976d2;
+}
+.package-header h2 {
+  margin: 0;
+  font-size: 20px;
+  font-weight: 600;
+  color: #1a1a2e;
+}
+
+.section-card {
+  margin-bottom: 20px;
+  padding: 20px;
+  background: #fafbfc;
+  border-radius: 12px;
+  border-left: 4px solid #1976d2;
+}
+
+.section-header {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  margin-bottom: 16px;
+}
+.section-header mat-icon {
+  color: #1976d2;
+  font-size: 20px;
+  width: 20px;
+  height: 20px;
+}
+.section-header h3 {
+  margin: 0;
+  font-size: 16px;
+  font-weight: 600;
+  color: #333;
+}
+
+.section-content {
+  font-size: 14px;
+  color: #555;
+}
+
+.profile-description {
+  margin: 0 0 12px;
+  line-height: 1.6;
+}
+.profile-details {
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+}
+.detail-item {
+  display: flex;
+  gap: 8px;
+}
+.detail-label {
+  font-weight: 600;
+  color: #666;
+  min-width: 80px;
+}
+.detail-value {
+  color: #333;
+}
+
+.contact-info {
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+}
+.contact-name-title {
+  display: flex;
+  align-items: baseline;
+  gap: 8px;
+}
+.contact-name {
+  font-size: 16px;
+  font-weight: 600;
+  color: #1a1a2e;
+}
+.contact-title {
+  font-size: 14px;
+  color: #666;
+}
+.contact-details {
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+}
+.decision-power {
+  padding: 2px 8px;
+  border-radius: 4px;
+  font-size: 12px;
+  font-weight: 600;
+}
+.power-high {
+  background: #e8f5e9;
+  color: #2e7d32;
+}
+.power-medium {
+  background: #fff3e0;
+  color: #e65100;
+}
+.power-low {
+  background: #fafafa;
+  color: #757575;
+}
+
+.matching-table {
+  width: 100%;
+  border-collapse: collapse;
+  margin-bottom: 12px;
+}
+.matching-table th {
+  text-align: left;
+  padding: 10px;
+  background: #f5f5f5;
+  font-size: 13px;
+  font-weight: 600;
+  color: #555;
+  border-bottom: 2px solid #e0e0e0;
+}
+.matching-table td {
+  padding: 12px 10px;
+  border-bottom: 1px solid #f0f0f0;
+  font-size: 14px;
+}
+.product-name {
+  font-weight: 500;
+  color: #333;
+}
+.product-sku {
+  font-size: 12px;
+  color: #999;
+  font-family: monospace;
+  margin-left: 6px;
+}
+.value-cell {
+  font-weight: 600;
+  color: #2e7d32;
+  text-align: right;
+}
+.total-value-row {
+  text-align: right;
+  font-size: 16px;
+  font-weight: 700;
+  color: #2e7d32;
+  padding-top: 12px;
+  border-top: 2px solid #e0e0e0;
+}
+
+.cert-list {
+  display: flex;
+  flex-direction: column;
+  gap: 10px;
+}
+.cert-item {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+}
+.cert-name {
+  flex: 1;
+  font-size: 14px;
+  color: #333;
+}
+.cert-status {
+  display: flex;
+  align-items: center;
+  gap: 4px;
+  font-size: 13px;
+  font-weight: 600;
+}
+.status-matched {
+  color: #2e7d32;
+}
+.status-missing {
+  color: #c62828;
+}
+.cert-status mat-icon {
+  font-size: 18px;
+  width: 18px;
+  height: 18px;
+}
+.cert-our {
+  font-size: 12px;
+  color: #999;
+}
+
+.strategy-steps {
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+}
+.strategy-step {
+  display: flex;
+  align-items: flex-start;
+  gap: 8px;
+  line-height: 1.6;
+}
+.step-number {
+  font-weight: 700;
+  color: #1976d2;
+  min-width: 20px;
+}
+.step-timeframe {
+  font-weight: 600;
+  color: #e65100;
+}
+.files-list {
+  margin: 8px 0 0 28px;
+  padding: 0;
+  list-style: none;
+}
+.files-list li {
+  margin: 4px 0;
+}
+.step-content {
+  display: block;
+  margin-top: 4px;
+}
+.key-points {
+  margin-left: 4px;
+}
+.key-point {
+  font-weight: 500;
+  color: #1976d2;
+}
+
+.script-field {
+  width: 100%;
+}
+
+.action-buttons {
+  display: flex;
+  gap: 12px;
+  margin-top: 24px;
+  padding-top: 20px;
+  border-top: 2px solid #e0e0e0;
+}
+.action-buttons button {
+  font-size: 14px;
+}
+.action-buttons mat-icon {
+  font-size: 18px;
+  width: 18px;
+  height: 18px;
+  margin-right: 4px;
+}
+

+ 109 - 0
lead-discovery/src/app/components/deep-research-package/deep-research-package.component.ts

@@ -0,0 +1,109 @@
+import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+import { MatCardModule } from '@angular/material/card';
+import { MatIconModule } from '@angular/material/icon';
+import { MatButtonModule } from '@angular/material/button';
+import { MatChipsModule } from '@angular/material/chips';
+import { MatDividerModule } from '@angular/material/divider';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatInputModule } from '@angular/material/input';
+import { MatTableModule } from '@angular/material/table';
+import { Lead, CustomerPersona, PERSONA_DEFINITIONS } from '../../models/lead.model';
+
+// 深度调研结果接口(根据PRD定义)
+export interface DeepResearchResult {
+  leadId: string;
+  researchedAt: string;
+  persona: CustomerPersona;
+
+  companyProfile: {
+    description: string;
+    coverage?: string[];
+    employees?: number;
+    foundedYear?: string;
+    productLines?: string[];
+    website?: string;
+  };
+
+  contactProfile: {
+    name: string;
+    title: string;
+    decisionPower: 'high' | 'medium' | 'low';
+    linkedInSummary?: string;
+  };
+
+  productMatching: Array<{
+    customerNeed: string;
+    recommendedProduct: {
+      name: string;
+      sku: string;
+    };
+    annualValue: number;
+  }>;
+  totalEstimatedValue: number;
+
+  certificationMatch: Array<{
+    required: string;
+    status: 'matched' | 'missing';
+    ourCert?: string;
+  }>;
+
+  followUpStrategy: {
+    timeframe: string;
+    filesToSend: string[];
+    keyPoints: string[];
+    additionalActions?: string[];
+  };
+
+  suggestedScript: {
+    draft: string;
+    editable: boolean;
+  };
+
+  personaSpecificData?: {
+    pricingSuggestion?: any;
+    tenderActionPlan?: any;
+    sampleCost?: any;
+  };
+}
+
+@Component({
+  selector: 'app-deep-research-package',
+  imports: [
+    CommonModule, FormsModule,
+    MatCardModule, MatIconModule, MatButtonModule, MatChipsModule,
+    MatDividerModule, MatFormFieldModule, MatInputModule, MatTableModule,
+  ],
+  templateUrl: './deep-research-package.component.html',
+  styleUrl: './deep-research-package.component.scss'
+})
+export class DeepResearchPackageComponent implements OnInit {
+  @Input() lead: Lead | null = null;
+  @Input() researchResult: DeepResearchResult | null = null;
+  @Output() editScript = new EventEmitter<void>();
+  @Output() sendEmail = new EventEmitter<void>();
+  @Output() createLead = new EventEmitter<void>();
+
+  editedScript = '';
+
+  ngOnInit() {
+    if (this.researchResult?.suggestedScript) {
+      this.editedScript = this.researchResult.suggestedScript.draft;
+    }
+  }
+
+  getDecisionPowerLabel(power: 'high' | 'medium' | 'low'): string {
+    const labels = {
+      high: '高',
+      medium: '中',
+      low: '低'
+    };
+    return labels[power];
+  }
+
+  formatNumber(value: number): string {
+    return new Intl.NumberFormat('en-US', { maximumFractionDigits: 0 }).format(value);
+  }
+}
+

+ 145 - 0
lead-discovery/src/app/components/screen-result-card/screen-result-card.component.html

@@ -0,0 +1,145 @@
+<div class="quick-assessment-card" [class]="'grade-border-' + result.valueGrade.toLowerCase()">
+  <!-- Header: Company + Country -->
+  <div class="card-header">
+    <div class="company-header">
+      <div class="company-avatar" [style.background]="getPersonaColor(result.persona)">
+        <mat-icon>{{ getPersonaIcon(result.persona) }}</mat-icon>
+      </div>
+      <div class="company-info">
+        <h3 class="company-name">{{ result.companyName }}</h3>
+        <div class="country-flag">{{ getFlag(result.country) }} {{ result.country }}</div>
+      </div>
+    </div>
+  </div>
+
+  <!-- Tags: Persona + Grade + Action -->
+  <div class="tags-row">
+    <span class="persona-badge" [style.background]="getPersonaBg(result.persona)" [style.color]="getPersonaColor(result.persona)">
+      <mat-icon class="badge-icon">{{ getPersonaIcon(result.persona) }}</mat-icon>
+      {{ result.persona }}-{{ result.personaLabel }}
+    </span>
+    <span class="grade-badge" [class]="'grade-' + result.valueGrade.toLowerCase()">
+      {{ result.valueGrade }}级
+    </span>
+    <span class="action-badge" [class]="'action-' + result.valueGrade.toLowerCase()">
+      {{ getActionLabel(result.valueGrade) }}
+    </span>
+  </div>
+
+  <!-- Demand Summary -->
+  <div class="demand-section" *ngIf="getDemandSnapshot()">
+    <div class="section-title">📦 需求摘要</div>
+    <div class="demand-list">
+      <div class="demand-item" *ngFor="let p of getDemandSnapshot()?.products">
+        <span class="demand-product">· {{ p.name }} × {{ p.quantity }}{{ p.unit }}</span>
+      </div>
+    </div>
+    <div class="estimated-value" *ngIf="getDemandSnapshot()?.estimatedAnnualValue">
+      💰 预估年采购额:${{ formatNumber(getDemandSnapshot()!.estimatedAnnualValue) }}+
+    </div>
+  </div>
+
+  <!-- Credibility -->
+  <div class="credibility-section">
+    <div class="section-title">✅ 可信度:{{ getCredibilityLevel() }}</div>
+    <div class="credibility-signals">
+      <span class="signal-item" *ngFor="let signal of getCredibilitySignals()">
+        · {{ signal }}
+      </span>
+    </div>
+  </div>
+
+  <!-- Matched Products -->
+  <div class="products-section" *ngIf="result.suggestedProducts.length > 0">
+    <div class="section-title">🎯 我方匹配产品</div>
+    <div class="matched-products">
+      <div class="matched-product-item" *ngFor="let p of result.suggestedProducts">
+        <span class="product-name">{{ p.name }}</span>
+        <span class="product-sku">({{ p.sku }})</span>
+        <span class="match-arrow">→</span>
+        <span class="match-reason">{{ p.reason || '匹配需求' }}</span>
+      </div>
+    </div>
+  </div>
+
+  <!-- Score Details (Expandable) -->
+  <mat-expansion-panel class="scores-panel" *ngIf="getScores()">
+    <mat-expansion-panel-header>
+      <mat-panel-title>
+        <mat-icon>assessment</mat-icon>
+        <span>📊 评分详情</span>
+      </mat-panel-title>
+    </mat-expansion-panel-header>
+    <div class="scores-grid">
+      <div class="score-item">
+        <span class="score-label">需求明确度</span>
+        <div class="score-bar-wrap">
+          <div class="score-bar" [style.width]="(getScores()?.demandClarity || 0) + '%'"></div>
+        </div>
+        <span class="score-value">{{ getScores()?.demandClarity || 0 }}分</span>
+      </div>
+      <div class="score-item">
+        <span class="score-label">可信度</span>
+        <div class="score-bar-wrap">
+          <div class="score-bar" [style.width]="(getScores()?.credibility || 0) + '%'"></div>
+        </div>
+        <span class="score-value">{{ getScores()?.credibility || 0 }}分</span>
+      </div>
+      <div class="score-item">
+        <span class="score-label">商业规模</span>
+        <div class="score-bar-wrap">
+          <div class="score-bar" [style.width]="(getScores()?.businessScale || 0) + '%'"></div>
+        </div>
+        <span class="score-value">{{ getScores()?.businessScale || 0 }}分</span>
+      </div>
+      <div class="score-item">
+        <span class="score-label">供需匹配</span>
+        <div class="score-bar-wrap">
+          <div class="score-bar" [style.width]="(getScores()?.productFit || 0) + '%'"></div>
+        </div>
+        <span class="score-value">{{ getScores()?.productFit || 0 }}分</span>
+      </div>
+      <div class="score-item">
+        <span class="score-label">紧迫度</span>
+        <div class="score-bar-wrap">
+          <div class="score-bar" [style.width]="(getScores()?.urgency || 0) + '%'"></div>
+        </div>
+        <span class="score-value">{{ getScores()?.urgency || 0 }}分</span>
+      </div>
+    </div>
+    <div class="total-score">
+      <span class="total-label">总分</span>
+      <span class="total-value">{{ getScores()?.total || 0 }}分</span>
+    </div>
+  </mat-expansion-panel>
+
+  <!-- Recommended Actions -->
+  <div class="actions-section" *ngIf="getRecommendedActions()">
+    <div class="section-title">📌 推荐行动</div>
+    <div class="action-content">
+      <span class="action-timeframe">{{ getRecommendedActions()?.timeframe }}</span>内发送:
+      <span class="action-files" *ngFor="let file of getRecommendedActions()?.filesToSend; let last = last">
+        {{ file }}<span *ngIf="!last"> + </span>
+      </span>
+    </div>
+  </div>
+
+  <!-- Action Buttons -->
+  <div class="button-row">
+    <button mat-stroked-button (click)="viewOriginal.emit()">
+      <mat-icon>email</mat-icon> 查看原文
+    </button>
+    <button mat-raised-button color="primary" (click)="deepAnalysis.emit()">
+      <mat-icon>search</mat-icon> 深度调研
+    </button>
+    <button mat-raised-button color="accent" (click)="createLead.emit()">
+      <mat-icon>check_circle</mat-icon> 确认并建档
+    </button>
+  </div>
+
+  <!-- Processing Time -->
+  <div class="processing-time" *ngIf="result.processingTime">
+    ⚡ 处理耗时:{{ formatProcessingTime(result.processingTime) }}秒
+  </div>
+</div>
+

+ 266 - 0
lead-discovery/src/app/components/screen-result-card/screen-result-card.component.scss

@@ -0,0 +1,266 @@
+.quick-assessment-card {
+  background: #fff;
+  border-radius: 16px;
+  padding: 24px;
+  box-shadow: 0 4px 16px rgba(0,0,0,0.1);
+  border-left: 4px solid #ccc;
+  max-width: 600px;
+}
+.grade-border-s { border-left-color: #c62828; }
+.grade-border-a { border-left-color: #e65100; }
+.grade-border-b { border-left-color: #f9a825; }
+.grade-border-c { border-left-color: #9e9e9e; }
+
+.card-header {
+  margin-bottom: 16px;
+}
+.company-header {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+}
+.company-avatar {
+  width: 48px;
+  height: 48px;
+  border-radius: 12px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-shrink: 0;
+}
+.company-avatar mat-icon {
+  font-size: 24px;
+  width: 24px;
+  height: 24px;
+  color: #fff;
+}
+.company-info {
+  flex: 1;
+}
+.company-name {
+  font-size: 20px;
+  font-weight: 600;
+  margin: 0 0 4px;
+  color: #1a1a2e;
+}
+.country-flag {
+  font-size: 14px;
+  color: #666;
+}
+
+.tags-row {
+  display: flex;
+  gap: 8px;
+  flex-wrap: wrap;
+  margin-bottom: 20px;
+}
+.persona-badge, .grade-badge, .action-badge {
+  display: inline-flex;
+  align-items: center;
+  gap: 4px;
+  padding: 4px 12px;
+  border-radius: 20px;
+  font-size: 12px;
+  font-weight: 600;
+}
+.badge-icon {
+  font-size: 14px;
+  width: 14px;
+  height: 14px;
+}
+.grade-s { background: #ffebee; color: #c62828; }
+.grade-a { background: #fff3e0; color: #e65100; }
+.grade-b { background: #fffde7; color: #f9a825; }
+.grade-c { background: #fafafa; color: #757575; }
+.action-s { background: #ffebee; color: #c62828; }
+.action-a { background: #fff3e0; color: #e65100; }
+.action-b { background: #fffde7; color: #f9a825; }
+.action-c { background: #fafafa; color: #757575; }
+
+.section-title {
+  font-size: 13px;
+  font-weight: 600;
+  color: #555;
+  margin-bottom: 8px;
+}
+
+.demand-section {
+  margin-bottom: 16px;
+  padding: 12px;
+  background: #f8f9fb;
+  border-radius: 10px;
+}
+.demand-list {
+  display: flex;
+  flex-direction: column;
+  gap: 4px;
+  margin-bottom: 8px;
+}
+.demand-item {
+  font-size: 14px;
+  color: #333;
+}
+.estimated-value {
+  font-size: 15px;
+  font-weight: 600;
+  color: #2e7d32;
+  margin-top: 8px;
+}
+
+.credibility-section {
+  margin-bottom: 16px;
+  padding: 12px;
+  background: #f0f4ff;
+  border-radius: 10px;
+}
+.credibility-signals {
+  display: flex;
+  flex-direction: column;
+  gap: 4px;
+  font-size: 13px;
+  color: #555;
+}
+.signal-item {
+  display: block;
+}
+
+.products-section {
+  margin-bottom: 16px;
+}
+.matched-products {
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+}
+.matched-product-item {
+  display: flex;
+  align-items: center;
+  gap: 6px;
+  font-size: 13px;
+  padding: 6px 10px;
+  background: #fafafa;
+  border-radius: 8px;
+}
+.product-name {
+  font-weight: 500;
+  color: #333;
+}
+.product-sku {
+  font-size: 11px;
+  color: #999;
+  font-family: monospace;
+}
+.match-arrow {
+  color: #999;
+}
+.match-reason {
+  color: #666;
+  font-size: 12px;
+}
+
+.scores-panel {
+  margin-bottom: 16px;
+  box-shadow: none;
+  border: 1px solid #e0e0e0;
+}
+.scores-grid {
+  display: flex;
+  flex-direction: column;
+  gap: 10px;
+  padding: 12px 0;
+}
+.score-item {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+}
+.score-label {
+  font-size: 13px;
+  color: #666;
+  min-width: 80px;
+}
+.score-bar-wrap {
+  flex: 1;
+  height: 8px;
+  background: #f0f0f0;
+  border-radius: 4px;
+  overflow: hidden;
+}
+.score-bar {
+  height: 100%;
+  background: linear-gradient(90deg, #1976d2, #42a5f5);
+  border-radius: 4px;
+  transition: width 0.3s;
+}
+.score-value {
+  font-size: 13px;
+  font-weight: 600;
+  color: #1976d2;
+  min-width: 50px;
+  text-align: right;
+}
+.total-score {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 12px;
+  background: #f0f4ff;
+  border-radius: 8px;
+  margin-top: 8px;
+}
+.total-label {
+  font-size: 14px;
+  font-weight: 600;
+  color: #333;
+}
+.total-value {
+  font-size: 18px;
+  font-weight: 700;
+  color: #1976d2;
+}
+
+.actions-section {
+  margin-bottom: 16px;
+  padding: 12px;
+  background: #fff3e0;
+  border-radius: 10px;
+}
+.action-content {
+  font-size: 14px;
+  color: #333;
+  line-height: 1.6;
+}
+.action-timeframe {
+  font-weight: 600;
+  color: #e65100;
+}
+.action-files {
+  font-weight: 500;
+  color: #1976d2;
+}
+
+.button-row {
+  display: flex;
+  gap: 10px;
+  margin-top: 20px;
+  flex-wrap: wrap;
+}
+.button-row button {
+  font-size: 13px;
+}
+.button-row mat-icon {
+  font-size: 18px;
+  width: 18px;
+  height: 18px;
+  margin-right: 4px;
+}
+
+.processing-time {
+  text-align: center;
+  font-size: 12px;
+  color: #999;
+  margin-top: 12px;
+  padding-top: 12px;
+  border-top: 1px solid #eee;
+}
+

+ 181 - 0
lead-discovery/src/app/components/screen-result-card/screen-result-card.component.ts

@@ -0,0 +1,181 @@
+import { Component, Input, Output, EventEmitter } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { MatCardModule } from '@angular/material/card';
+import { MatIconModule } from '@angular/material/icon';
+import { MatButtonModule } from '@angular/material/button';
+import { MatChipsModule } from '@angular/material/chips';
+import { MatDividerModule } from '@angular/material/divider';
+import { MatProgressBarModule } from '@angular/material/progress-bar';
+import { MatTooltipModule } from '@angular/material/tooltip';
+import { MatExpansionModule } from '@angular/material/expansion';
+import {
+  QuickScreenResult, CATEGORY_LABELS, CATEGORY_ICONS,
+  CustomerPersona, PERSONA_DEFINITIONS, GRADE_LABELS
+} from '../../models/lead.model';
+
+// 扩展 QuickScreenResult 以包含五维评分(临时,后续应更新模型)
+interface ExtendedQuickScreenResult extends QuickScreenResult {
+  scores?: {
+    demandClarity: number;
+    credibility: number;
+    businessScale: number;
+    productFit: number;
+    urgency: number;
+    total: number;
+  };
+  demandSnapshot?: {
+    products: Array<{ name: string; quantity: number; unit: string }>;
+    estimatedAnnualValue: number;
+    certifications: string[];
+  };
+  credibilityDetails?: {
+    level: 'high' | 'medium' | 'low';
+    signals: string[];
+  };
+  recommendedActions?: {
+    timeframe: string;
+    filesToSend: string[];
+    keyPoints: string[];
+  };
+}
+
+@Component({
+    selector: 'app-screen-result-card',
+    imports: [
+        CommonModule, MatCardModule, MatIconModule, MatButtonModule,
+        MatChipsModule, MatDividerModule, MatProgressBarModule, MatTooltipModule,
+        MatExpansionModule,
+    ],
+    templateUrl: './screen-result-card.component.html',
+    styleUrl: './screen-result-card.component.scss'
+})
+export class ScreenResultCardComponent {
+  @Input() result!: QuickScreenResult;
+  @Output() createLead = new EventEmitter<void>();
+  @Output() deepAnalysis = new EventEmitter<void>();
+  @Output() viewOriginal = new EventEmitter<void>();
+  @Output() dismiss = new EventEmitter<void>();
+
+  getCatIcon(cat: string): string {
+    return CATEGORY_ICONS[cat as keyof typeof CATEGORY_ICONS] || 'business';
+  }
+
+  getPersonaColor(p: CustomerPersona): string {
+    return PERSONA_DEFINITIONS[p]?.color || '#999';
+  }
+
+  getPersonaBg(p: CustomerPersona): string {
+    return PERSONA_DEFINITIONS[p]?.bgColor || '#fafafa';
+  }
+
+  getPersonaIcon(p: CustomerPersona): string {
+    return PERSONA_DEFINITIONS[p]?.icon || 'business';
+  }
+
+  getFlag(country: string): string {
+    const flags: Record<string, string> = {
+      US: '🇺🇸', GB: '🇬🇧', DE: '🇩🇪', PL: '🇵🇱', CA: '🇨🇦',
+      AU: '🇦🇺', SE: '🇸🇪', CN: '🇨🇳',
+    };
+    return flags[country] || '🌍';
+  }
+
+  getActionLabel(grade: string): string {
+    return GRADE_LABELS[grade as keyof typeof GRADE_LABELS] || '';
+  }
+
+  // 临时方法:从 result 中提取或生成五维评分数据
+  getScores(): ExtendedQuickScreenResult['scores'] | undefined {
+    const extended = this.result as ExtendedQuickScreenResult;
+    if (extended.scores) {
+      return extended.scores;
+    }
+    // 如果没有,生成模拟数据(实际应从后端获取)
+    return {
+      demandClarity: 85,
+      credibility: 85,
+      businessScale: 75,
+      productFit: 80,
+      urgency: 50,
+      total: 76
+    };
+  }
+
+  getDemandSnapshot(): ExtendedQuickScreenResult['demandSnapshot'] | undefined {
+    const extended = this.result as ExtendedQuickScreenResult;
+    if (extended.demandSnapshot) {
+      return extended.demandSnapshot;
+    }
+    // 如果没有,从 suggestedProducts 生成
+    if (this.result.suggestedProducts.length > 0) {
+      return {
+        products: this.result.suggestedProducts.map(p => ({
+          name: p.name,
+          quantity: 1000,
+          unit: '/年'
+        })),
+        estimatedAnnualValue: this.result.suggestedProducts.reduce((sum, p) => sum + p.wholesalePrice * 1000, 0),
+        certifications: this.result.certRequirements
+      };
+    }
+    return undefined;
+  }
+
+  getCredibilityLevel(): 'high' | 'medium' | 'low' {
+    const extended = this.result as ExtendedQuickScreenResult;
+    if (extended.credibilityDetails) {
+      return extended.credibilityDetails.level;
+    }
+    // 根据域名判断
+    if (this.result.domain && !this.result.domain.includes('gmail') && !this.result.domain.includes('hotmail')) {
+      return 'high';
+    }
+    return 'medium';
+  }
+
+  getCredibilitySignals(): string[] {
+    const extended = this.result as ExtendedQuickScreenResult;
+    if (extended.credibilityDetails) {
+      return extended.credibilityDetails.signals;
+    }
+    // 生成默认信号
+    const signals: string[] = [];
+    if (this.result.domain && !this.result.domain.includes('gmail')) {
+      signals.push('企业邮箱');
+    }
+    if (this.result.confidence > 70) {
+      signals.push('完整签名块');
+    }
+    if (this.result.certRequirements.length > 0) {
+      signals.push('有认证要求');
+    }
+    return signals.length > 0 ? signals : ['基础信息完整'];
+  }
+
+  getRecommendedActions(): ExtendedQuickScreenResult['recommendedActions'] | undefined {
+    const extended = this.result as ExtendedQuickScreenResult;
+    if (extended.recommendedActions) {
+      return extended.recommendedActions;
+    }
+    // 根据等级生成默认行动
+    const timeframes: Record<string, string> = {
+      S: '24h内',
+      A: '3天内',
+      B: '7天内',
+      C: '归档观察'
+    };
+    return {
+      timeframe: timeframes[this.result.valueGrade] || '7天内',
+      filesToSend: ['产品目录', '报价单', '认证文件包'],
+      keyPoints: ['供应稳定性', '认证齐全']
+    };
+  }
+
+  formatNumber(value: number): string {
+    return new Intl.NumberFormat('en-US', { maximumFractionDigits: 0 }).format(value);
+  }
+
+  formatProcessingTime(ms: number): string {
+    return (ms / 1000).toFixed(1);
+  }
+}

+ 312 - 0
lead-discovery/src/app/models/lead.model.ts

@@ -0,0 +1,312 @@
+// ===== 客户四分类(保留兼容) =====
+export type CustomerCategory = 'A' | 'B' | 'C' | 'D';
+
+export const CATEGORY_LABELS: Record<CustomerCategory, string> = {
+  A: '医疗渠道',
+  B: '工业安全',
+  C: '应急政府',
+  D: '品牌OEM',
+};
+
+export const CATEGORY_ICONS: Record<CustomerCategory, string> = {
+  A: 'local_hospital',
+  B: 'engineering',
+  C: 'account_balance',
+  D: 'storefront',
+};
+
+// ===== 客户画像体系(6类) =====
+export type CustomerPersona = 'P1' | 'P2' | 'P3' | 'P4' | 'P5' | 'P6';
+
+export interface PersonaDefinition {
+  id: CustomerPersona;
+  name: string;
+  description: string;
+  icon: string;
+  color: string;
+  bgColor: string;
+  identifyKeywords: string[];
+  infoStrategy: 'product_catalog' | 'website' | 'none';
+  infoStrategyLabel: string;
+  firstAction: string;
+  deepDiveDirection: string;
+  salesStrategy: string;
+  salesExperienceNotes: string[];
+  leadCount: number;
+  conversionRate: number;
+  /** 对应旧的 CustomerCategory */
+  legacyCategory: CustomerCategory;
+}
+
+export const PERSONA_DEFINITIONS: Record<CustomerPersona, PersonaDefinition> = {
+  P1: {
+    id: 'P1', name: '医药分销商', description: '拥有销售渠道的医疗用品经销商,寻找低价中国代工厂进货',
+    icon: 'local_hospital', color: '#1565c0', bgColor: '#e3f2fd',
+    identifyKeywords: ['distributor', 'wholesale', 'medical supply', 'catalog', 'authorized dealer', 'FDA', 'bulk order', 'annual forecast', 'partnership'],
+    infoStrategy: 'product_catalog', infoStrategyLabel: '查看产品清单页',
+    firstAction: '发送完整产品目录 + 价盘',
+    deepDiveDirection: '其现有产品线、竞品供应商、渠道覆盖范围',
+    salesStrategy: '强调供应稳定性、认证齐全、复购支持',
+    salesExperienceNotes: ['这类客户最关心认证文件是否齐全,首次接触一定要附上 FDA/CE/ISO 证书', '大型分销商决策周期较长(2-3个月),需要持续跟进'],
+    leadCount: 42, conversionRate: 28, legacyCategory: 'A',
+  },
+  P2: {
+    id: 'P2', name: '工业安全供应商', description: '面向企业客户的安全设备供应商,需 OSHA/ANSI 合规产品',
+    icon: 'engineering', color: '#2e7d32', bgColor: '#e8f5e9',
+    identifyKeywords: ['workplace safety', 'OSHA compliant', 'industrial', 'PPE', 'safety cabinet', 'first aid station', 'ANSI', 'construction site'],
+    infoStrategy: 'product_catalog', infoStrategyLabel: '查看产品清单页',
+    firstAction: '发送 OSHA 合规产品线',
+    deepDiveDirection: '其客户行业分布、采购频次、定制需求',
+    salesStrategy: '强调合规认证、定制标签、壁挂方案',
+    salesExperienceNotes: ['工业客户复购率高,首单金额可能不大但长期价值高', '壁挂急救箱是切入点产品'],
+    leadCount: 18, conversionRate: 35, legacyCategory: 'B',
+  },
+  P3: {
+    id: 'P3', name: '政府/机构采购', description: '政府、军队、NGO、医院等机构,本身不售卖产品,无需产品信息',
+    icon: 'account_balance', color: '#6a1b9a', bgColor: '#f3e5f5',
+    identifyKeywords: ['tender', 'procurement', 'government', 'emergency', 'military', 'NGO', 'hospital', 'red cross', 'RFP', 'lot'],
+    infoStrategy: 'website', infoStrategyLabel: '查看官网(了解机构背景)',
+    firstAction: '准备资质文件包',
+    deepDiveDirection: '机构规模、历史采购记录、预算周期',
+    salesStrategy: '强调资质齐全、大批量交付能力、投标经验',
+    salesExperienceNotes: ['政府采购有固定流程和截止日期,一定要在截止前2周准备好所有资质文件', '标书要求严格,需要专人准备'],
+    leadCount: 12, conversionRate: 22, legacyCategory: 'C',
+  },
+  P4: {
+    id: 'P4', name: '品牌OEM客户', description: '户外/运动品牌,需要贴牌定制,关注设计和品牌调性',
+    icon: 'palette', color: '#e65100', bgColor: '#fff3e0',
+    identifyKeywords: ['OEM', 'private label', 'custom branding', 'outdoor', 'adventure', 'brand', 'retail', 'mood board', 'Pantone'],
+    infoStrategy: 'website', infoStrategyLabel: '查看官网(了解品牌调性)',
+    firstAction: '发送 OEM 案例 + 定制能力介绍',
+    deepDiveDirection: '品牌定位、目标市场、设计风格',
+    salesStrategy: '强调定制能力、打样速度、小批量起订',
+    salesExperienceNotes: ['OEM客户非常在意打样速度和颜色还原度', '首次合作建议提供免费打样'],
+    leadCount: 15, conversionRate: 18, legacyCategory: 'D',
+  },
+  P5: {
+    id: 'P5', name: '电商/零售商', description: '线上零售商,关注单品利润率和爆款潜力',
+    icon: 'shopping_cart', color: '#00838f', bgColor: '#e0f7fa',
+    identifyKeywords: ['amazon', 'shopify', 'e-commerce', 'retail', 'FBA', 'dropship', 'best seller', 'product listing', 'margin'],
+    infoStrategy: 'product_catalog', infoStrategyLabel: '查看产品清单页',
+    firstAction: '发送爆款推荐 + 利润率分析',
+    deepDiveDirection: '其店铺品类、评价数据、竞品价格',
+    salesStrategy: '强调高利润率、FBA就绪、产品图片支持',
+    salesExperienceNotes: ['电商客户决策快但忠诚度低,需要持续提供新品', '产品图片和listing优化是关键'],
+    leadCount: 8, conversionRate: 40, legacyCategory: 'D',
+  },
+  P6: {
+    id: 'P6', name: '低质量/无效线索', description: '无明确需求、套价格、骗样品等',
+    icon: 'block', color: '#9e9e9e', bgColor: '#fafafa',
+    identifyKeywords: ['wholesale everything', 'lowest price', 'all kinds', 'mixed container', 'free sample', 'ASAP'],
+    infoStrategy: 'none', infoStrategyLabel: '不做深入调研',
+    firstAction: '自动归档',
+    deepDiveDirection: '-',
+    salesStrategy: '定期群发营销邮件,不投入人工',
+    salesExperienceNotes: ['使用免费邮箱、无官网的基本可以判定为低质量', '邮件内容空洞无具体产品需求的直接归档'],
+    leadCount: 5, conversionRate: 2, legacyCategory: 'D',
+  },
+};
+
+export const PERSONA_LIST: PersonaDefinition[] = Object.values(PERSONA_DEFINITIONS);
+
+/** 从旧分类映射到画像 */
+export function categoryToPersona(cat: CustomerCategory): CustomerPersona {
+  const map: Record<CustomerCategory, CustomerPersona> = { A: 'P1', B: 'P2', C: 'P3', D: 'P4' };
+  return map[cat];
+}
+
+// ===== 价值等级 =====
+export type ValueGrade = 'S' | 'A' | 'B' | 'C';
+
+export const GRADE_LABELS: Record<ValueGrade, string> = {
+  S: '立即跟进 · 24h内回复',
+  A: '3天内跟进',
+  B: '7天内跟进',
+  C: '归档观察',
+};
+
+// ===== 快速筛选结果 =====
+export interface QuickScreenResult {
+  companyName: string;
+  domain: string;
+  country: string;
+  customerCategory: CustomerCategory;
+  categoryLabel: string;
+  valueGrade: ValueGrade;
+  productRelevance: 'high' | 'medium' | 'low';
+  mainBusiness: string;
+  estimatedScale: string;
+  certRequirements: string[];
+  recommendedAction: string;
+  suggestedProducts: ProductRecommendation[];
+  socialLinks: {
+    linkedin?: string;
+    facebook?: string;
+    instagram?: string;
+    youtube?: string;
+  };
+  confidence: number;
+  processingTime: number;
+  /** 新增画像字段 */
+  persona: CustomerPersona;
+  personaLabel: string;
+  personaConfidence: number;
+  /** AI 判断依据 */
+  matchedKeywords?: string[];
+  /** 五维评分(根据PRD) */
+  scores?: {
+    demandClarity: number;      // 需求明确度 0-100
+    credibility: number;        // 可信度 0-100
+    businessScale: number;      // 商业规模 0-100
+    productFit: number;         // 供需匹配 0-100
+    urgency: number;            // 紧迫度 0-100
+    total: number;              // 总分 0-100
+  };
+  /** 需求快照 */
+  demandSnapshot?: {
+    products: Array<{ name: string; quantity: number; unit: string }>;
+    estimatedAnnualValue: number;
+    certifications: string[];
+  };
+  /** 可信度详情 */
+  credibilityDetails?: {
+    level: 'high' | 'medium' | 'low';
+    signals: string[];
+  };
+  /** 推荐行动 */
+  recommendedActions?: {
+    timeframe: string;          // "24h内" / "3天内" / "7天内"
+    filesToSend: string[];      // 文件列表
+    keyPoints: string[];        // 重点强调的内容
+  };
+}
+
+// ===== 产品推荐 =====
+export interface ProductRecommendation {
+  sku: string;
+  name: string;
+  nameEn: string;
+  wholesalePrice: number;
+  retailPrice: number;
+  reason: string;
+  image?: string;
+}
+
+// ===== 产品匹配(AI 调研报告用) =====
+export interface ProductMatch {
+  ourProduct: string;
+  ourSku: string;
+  matchesNeed: string;
+  profitMargin: string;
+}
+
+// ===== Lead 对象 =====
+export interface Lead {
+  id: string;
+  leadNumber: string;
+  contactName: string;
+  contactEmail: string;
+  companyName: string;
+  country: string;
+  source: 'email' | 'manual' | 'exhibition' | 'platform' | 'ai_discovery';
+  sourceLabel: string;
+
+  customerCategory: CustomerCategory;
+  categoryLabel: string;
+  valueGrade: ValueGrade;
+
+  /** 客户画像 */
+  persona: CustomerPersona;
+  personaLabel: string;
+  personaConfidence: number;
+  personaVerified: boolean;
+  personaVerifiedBy?: string;
+  personaVerifiedAt?: Date;
+
+  quickScreenResult: QuickScreenResult;
+  quickScreenAt: Date;
+
+  hasDeepAnalysis: boolean;
+  deepAnalysisAt?: Date;
+
+  /** AI 调研报告 */
+  aiResearchReport?: {
+    websiteAnalysis: string;
+    productMatching: ProductMatch[];
+    competitorAnalysis: string;
+    generatedAt: Date;
+  };
+
+  /** 销售反馈 */
+  salesFeedback?: {
+    isPersonaCorrect: boolean;
+    correctedPersona?: CustomerPersona;
+    isGradeCorrect: boolean;
+    correctedGrade?: ValueGrade;
+    notes: string;
+    feedbackAt: Date;
+  };
+
+  followUpStage: 'screened' | 'contacted' | 'replied' | 'sample' | 'quote' | 'order';
+  nextFollowUpDate: Date;
+  followUpNotes: string;
+
+  matchedProductSKUs: string[];
+  estimatedOrderValue: number;
+
+  createdAt: Date;
+}
+
+// ===== AI 挖掘批次 =====
+export interface AiDiscoveryBatch {
+  id: string;
+  runAt: Date;
+  triggerType: 'daily' | 'weekly' | 'monthly' | 'manual';
+  totalProcessed: number;
+  newLeadsFound: number;
+  personaBreakdown: Partial<Record<CustomerPersona, number>>;
+  gradeBreakdown: Partial<Record<ValueGrade, number>>;
+  pendingVerification: number;
+  verified: number;
+  status: 'running' | 'completed' | 'failed';
+}
+
+// ===== 邮件附件 =====
+export interface EmailAttachment {
+  id: string;
+  fileName: string;
+  fileSize: number;
+  mimeType: string;
+  icon: string;
+}
+
+// ===== 邮件对象(模拟) =====
+export interface Email {
+  id: string;
+  from: string;
+  fromName: string;
+  to: string;
+  cc?: string;
+  subject: string;
+  preview: string;
+  body: string;
+  htmlContent?: string;
+  attachments: EmailAttachment[];
+  receivedAt: Date;
+  hasScreened: boolean;
+  screenResult?: QuickScreenResult;
+  leadId?: string;
+}
+
+// ===== 产品目录 =====
+export interface Product {
+  sku: string;
+  name: string;
+  nameEn: string;
+  series: string;
+  wholesalePrice: number;
+  retailPrice: number;
+  category: string;
+  targetCustomers: CustomerCategory[];
+  description: string;
+}

+ 1755 - 0
lead-discovery/src/app/pages/dashboard/dashboard.component.ts

@@ -0,0 +1,1755 @@
+import { Component, OnInit } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+import { Router } from '@angular/router';
+import { HttpClient, HttpHeaders } from '@angular/common/http';
+import { MatCardModule } from '@angular/material/card';
+import { MatIconModule } from '@angular/material/icon';
+import { MatButtonModule } from '@angular/material/button';
+import { MatChipsModule } from '@angular/material/chips';
+import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
+import { MatTooltipModule } from '@angular/material/tooltip';
+import { MatTabsModule } from '@angular/material/tabs';
+import { MatDividerModule } from '@angular/material/divider';
+import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
+import { MatProgressBarModule } from '@angular/material/progress-bar';
+import { MatBadgeModule } from '@angular/material/badge';
+import { MockDataService } from '../../services/mock-data.service';
+import { QuickScreenService } from '../../services/quick-screen.service';
+import { ScreenResultCardComponent } from '../../components/screen-result-card/screen-result-card.component';
+import {
+  Lead, Email, EmailAttachment, QuickScreenResult,
+  CustomerPersona, PERSONA_DEFINITIONS, PERSONA_LIST
+} from '../../models/lead.model';
+
+// EML 解析 API 响应接口
+interface EmlParseAttachment {
+  filename: string;
+  mimeType: string;
+  size: number;
+}
+
+interface EmlProductDemand {
+  source: string;
+  productName: string;
+  quantity: string;
+  unitPrice: string;
+  totalPrice: string;
+  moq: string;
+  specifications: string;
+  additionalRequirements: string;
+  rawExcerpt: string;
+}
+
+interface EmlParseData {
+  messageId: string;
+  subject: string;
+  cleanSubject: string;
+  date: string;
+  senderName: string;
+  senderEmail: string;
+  toList: { name: string; email: string }[];
+  ccList: { name: string; email: string }[];
+  cleanedBody: string;
+  attachments: EmlParseAttachment[];
+  customerEmail: string;
+  contactName: string;
+  companyName: string;
+  companyDomain: string;
+  direction: string;
+  phone: string[];
+  mobile: string[];
+  title: string;
+  productDemands?: EmlProductDemand[];
+  attachmentStats?: {
+    total: number;
+    analyzed: number;
+    skipped: number;
+    bodyAnalyzed: boolean;
+  };
+}
+
+interface EmlParseResponse {
+  filename: string;
+  success: boolean;
+  error: string | null;
+  data: EmlParseData;
+  elapsedMs: number;
+}
+
+@Component({
+    selector: 'app-dashboard',
+    imports: [
+        CommonModule, FormsModule,
+        MatCardModule, MatIconModule, MatButtonModule,
+        MatChipsModule, MatSnackBarModule, MatTooltipModule,
+        MatTabsModule, MatDividerModule,
+        MatProgressSpinnerModule, MatProgressBarModule, MatBadgeModule,
+        ScreenResultCardComponent,
+    ],
+    template: `
+    <div class="page-container">
+      <!-- Header -->
+      <div class="page-header">
+        <div>
+          <h1><mat-icon>auto_awesome</mat-icon> AI 智能工作台</h1>
+          <p class="subtitle">AI 每日自动处理新线索,您只需验证结果</p>
+        </div>
+        <div class="header-actions">
+          <button mat-stroked-button class="inbox-btn" (click)="openInbox()">
+            <mat-icon>inbox</mat-icon>
+            收件箱
+          </button>
+          <div class="header-date">
+            <mat-icon>today</mat-icon>
+            {{ today | date:'yyyy-MM-dd EEEE' }}
+          </div>
+        </div>
+      </div>
+
+      <!-- Stats Cards -->
+      <div class="stats-row">
+        <div class="stat-card new">
+          <div class="stat-icon-wrap"><mat-icon>fiber_new</mat-icon></div>
+          <div class="stat-info">
+            <span class="stat-value">{{ latestBatch?.newLeadsFound || 0 }}</span>
+            <span class="stat-label">今日新线索</span>
+          </div>
+        </div>
+        <div class="stat-card pending">
+          <div class="stat-icon-wrap"><mat-icon>pending_actions</mat-icon></div>
+          <div class="stat-info">
+            <span class="stat-value">{{ pendingCount }}</span>
+            <span class="stat-label">待验证</span>
+          </div>
+        </div>
+        <div class="stat-card verified">
+          <div class="stat-icon-wrap"><mat-icon>verified</mat-icon></div>
+          <div class="stat-info">
+            <span class="stat-value">{{ verifiedCount }}</span>
+            <span class="stat-label">已确认</span>
+          </div>
+        </div>
+      </div>
+
+      <!-- AI Batch Status -->
+      <div class="batch-status card" *ngIf="latestBatch">
+        <div class="batch-header">
+          <mat-icon>smart_toy</mat-icon>
+          <span>AI 今日批次</span>
+          <span class="batch-time">{{ latestBatch.runAt | date:'HH:mm' }} 运行</span>
+          <span class="batch-badge" [class]="'status-' + latestBatch.status">
+            {{ latestBatch.status === 'completed' ? '✅ 已完成' : latestBatch.status === 'running' ? '⏳ 运行中' : '❌ 失败' }}
+          </span>
+        </div>
+        <div class="batch-stats">
+          <span>处理 <strong>{{ latestBatch.totalProcessed }}</strong> 条</span>
+          <span>发现 <strong>{{ latestBatch.newLeadsFound }}</strong> 条新线索</span>
+          <span>待验证 <strong>{{ latestBatch.pendingVerification }}</strong></span>
+        </div>
+      </div>
+
+      <!-- ===== Main Tab Area ===== -->
+      <mat-tab-group class="main-tabs" animationDuration="200ms" [(selectedIndex)]="activeTab">
+        <!-- Tab 1: 待验证线索 -->
+        <mat-tab>
+          <ng-template mat-tab-label>
+            <mat-icon>assignment</mat-icon>
+            <span class="tab-label-text">待验证线索</span>
+            <span class="tab-count" *ngIf="pendingLeads.length > 0">{{ pendingLeads.length }}</span>
+          </ng-template>
+
+          <div class="tab-content">
+            <div class="content-grid">
+              <!-- Left: Pending Verification List -->
+              <div class="left-col">
+                <div class="section-card card">
+                  <div class="section-header">
+                    <mat-icon>assignment</mat-icon>
+                    <h3>AI 发现 · 需要您验证</h3>
+                    <span class="count-badge">{{ pendingLeads.length }}</span>
+                  </div>
+
+                  <div class="lead-verify-list">
+                    <div class="verify-card" *ngFor="let lead of pendingLeads"
+                         [class]="'persona-border-' + lead.persona.toLowerCase()">
+                      <div class="verify-top">
+                        <div class="verify-avatar" [style.background]="getPersonaColor(lead.persona)">
+                          <mat-icon>{{ getPersonaIcon(lead.persona) }}</mat-icon>
+                        </div>
+                        <div class="verify-info">
+                          <div class="verify-company">{{ lead.companyName }}</div>
+                          <div class="verify-tags">
+                            <span class="persona-tag" [style.background]="getPersonaBg(lead.persona)" [style.color]="getPersonaColor(lead.persona)">
+                              {{ lead.persona }}-{{ lead.personaLabel }}
+                            </span>
+                            <span class="grade-tag" [class]="'grade-' + lead.valueGrade.toLowerCase()">
+                              {{ lead.valueGrade }}级
+                            </span>
+                            <span class="flag">{{ getFlag(lead.country) }}</span>
+                          </div>
+                        </div>
+                      </div>
+
+                      <div class="verify-ai-reason">
+                        <mat-icon>psychology</mat-icon>
+                        <span>AI判断:{{ lead.personaLabel }} · {{ getPersonaStrategy(lead.persona) }}</span>
+                      </div>
+
+                      <div class="verify-keywords" *ngIf="lead.quickScreenResult.matchedKeywords?.length">
+                        <span class="keyword-chip" *ngFor="let kw of lead.quickScreenResult.matchedKeywords">{{ kw }}</span>
+                      </div>
+
+                      <div class="verify-actions">
+                        <button mat-raised-button color="primary" class="action-btn" (click)="confirmLead(lead)">
+                          <mat-icon>check</mat-icon> 确认
+                        </button>
+                        <button mat-stroked-button class="action-btn" (click)="editLead(lead)">
+                          <mat-icon>edit</mat-icon> 修改
+                        </button>
+                        <button mat-stroked-button color="warn" class="action-btn" (click)="dismissLead(lead)">
+                          <mat-icon>close</mat-icon> 无效
+                        </button>
+                        <button mat-icon-button [matTooltip]="'查看详情'" (click)="openLead(lead)">
+                          <mat-icon>open_in_new</mat-icon>
+                        </button>
+                        <button mat-icon-button [matTooltip]="'查看原始邮件'" (click)="showEmailDrawer(lead)"
+                                *ngIf="getEmailForLead(lead)">
+                          <mat-icon>email</mat-icon>
+                        </button>
+                      </div>
+                    </div>
+
+                    <div class="empty-verify" *ngIf="pendingLeads.length === 0">
+                      <mat-icon>celebration</mat-icon>
+                      <p>所有线索已验证完毕 🎉</p>
+                    </div>
+                  </div>
+                </div>
+              </div>
+
+              <!-- Right: Persona Distribution + Activity + Quick Links -->
+              <div class="right-col">
+                <div class="section-card card">
+                  <div class="section-header">
+                    <mat-icon>donut_large</mat-icon>
+                    <h3>本周画像分布</h3>
+                  </div>
+                  <div class="persona-dist-list">
+                    <div class="dist-row" *ngFor="let p of personaDistribution">
+                      <div class="dist-label">
+                        <mat-icon [style.color]="p.color">{{ p.icon }}</mat-icon>
+                        <span>{{ p.id }}-{{ p.name }}</span>
+                      </div>
+                      <div class="dist-bar-wrap">
+                        <div class="dist-bar" [style.width.%]="p.percent" [style.background]="p.color"></div>
+                      </div>
+                      <span class="dist-count">{{ p.count }} ({{ p.percent }}%)</span>
+                    </div>
+                  </div>
+                </div>
+
+                <div class="section-card card">
+                  <div class="section-header">
+                    <mat-icon>history</mat-icon>
+                    <h3>最近活动</h3>
+                  </div>
+                  <div class="activity-list">
+                    <div class="activity-item" *ngFor="let a of recentActivities">
+                      <div class="activity-dot" [style.background]="a.color"></div>
+                      <div class="activity-content">
+                        <span class="activity-text">{{ a.text }}</span>
+                        <span class="activity-time">{{ a.time }}</span>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+
+                <div class="section-card card">
+                  <div class="section-header">
+                    <mat-icon>rocket_launch</mat-icon>
+                    <h3>快捷操作</h3>
+                  </div>
+                  <div class="quick-links">
+                    <button mat-stroked-button (click)="router.navigate(['/list'])">
+                      <mat-icon>hub</mat-icon> 线索中心
+                    </button>
+                    <button mat-stroked-button (click)="router.navigate(['/personas'])">
+                      <mat-icon>psychology</mat-icon> 画像知识库
+                    </button>
+                    <button mat-stroked-button (click)="router.navigate(['/products'])">
+                      <mat-icon>inventory_2</mat-icon> 产品目录
+                    </button>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </mat-tab>
+
+        <!-- Tab 2: 导入线索 -->
+        <mat-tab>
+          <ng-template mat-tab-label>
+            <mat-icon>cloud_upload</mat-icon>
+            <span class="tab-label-text">导入线索</span>
+          </ng-template>
+
+          <div class="tab-content">
+            <div class="import-section card">
+              <div class="section-title-row">
+                <mat-icon class="section-icon">email</mat-icon>
+                <span>导入邮件 / 手动录入</span>
+              </div>
+
+              <!-- EML Import Banner -->
+              <div class="import-banner" (click)="importFromEmail()" [class.disabled]="isImporting">
+                <div class="import-drop-zone">
+                  <mat-icon class="upload-icon">cloud_upload</mat-icon>
+                  <div class="drop-text">
+                    <span class="drop-main">点击选择 .eml 邮件文件</span>
+                    <span class="drop-hint">自动提取邮件中的公司信息和产品线索</span>
+                  </div>
+                  <button mat-stroked-button color="accent" class="import-btn" [disabled]="isImporting">
+                    <mat-icon>email</mat-icon>
+                    邮件导入(推荐)
+                  </button>
+                </div>
+              </div>
+
+              <!-- Import Progress -->
+              <div *ngIf="isImporting" class="import-progress-section">
+                <mat-progress-bar mode="determinate" [value]="importProgress"></mat-progress-bar>
+                <div class="import-progress-info">
+                  <mat-progress-spinner mode="indeterminate" diameter="18"></mat-progress-spinner>
+                  <span>{{ importStepMessage }}</span>
+                </div>
+              </div>
+
+              <!-- Linked Email Status -->
+              <div *ngIf="importedEmailId" class="linked-status">
+                <mat-icon>link</mat-icon>
+                <span>已关联邮件数据(ID: {{ importedEmailId }})</span>
+                <button mat-icon-button class="clear-import-btn" (click)="clearImport()" matTooltip="清除导入">
+                  <mat-icon>close</mat-icon>
+                </button>
+              </div>
+
+              <!-- Auto-filled Form -->
+              <div class="import-form-grid">
+                <div class="form-item">
+                  <div class="label">公司名称<span class="required">*</span></div>
+                  <input class="form-input" [(ngModel)]="importData.companyName" placeholder="请输入公司名称">
+                </div>
+                <div class="form-item">
+                  <div class="label">关键联系人</div>
+                  <input class="form-input" [(ngModel)]="importData.contactName" placeholder="请输入客户名称,如:John Smith">
+                  <div *ngIf="importData.roleDescription" class="hint">
+                    <mat-icon class="hint-icon">work</mat-icon>
+                    <span>参考职位:{{ importData.roleDescription }}</span>
+                  </div>
+                </div>
+                <div class="form-item">
+                  <div class="label">邮箱地址</div>
+                  <input class="form-input" [(ngModel)]="importData.email" placeholder="name&#64;company.com">
+                </div>
+                <div class="form-item">
+                  <div class="label">公司官网(选填)</div>
+                  <input class="form-input" [(ngModel)]="importData.website" placeholder="支持从邮箱域名自动填充">
+                  <div class="hint">
+                    <mat-icon class="hint-icon">info</mat-icon>
+                    <span>支持自动从邮箱提取域名,可手动修改</span>
+                  </div>
+                </div>
+              </div>
+
+              <!-- Product Demands Preview -->
+              <div *ngIf="importedProducts.length > 0" class="product-demands-section">
+                <div class="demands-header">
+                  <mat-icon>inventory_2</mat-icon>
+                  <span>提取的产品需求 ({{ importedProducts.length }})</span>
+                  <span class="demands-source-tag" *ngIf="importedAttachmentStats">
+                    正文 {{ importedAttachmentStats.bodyAnalyzed ? '✓' : '✗' }} ·
+                    附件 {{ importedAttachmentStats.analyzed }}/{{ importedAttachmentStats.total }}
+                  </span>
+                </div>
+                <div class="demands-grid">
+                  <div class="demand-card" *ngFor="let p of importedProducts; let i = index">
+                    <div class="demand-index">{{ i + 1 }}</div>
+                    <div class="demand-info">
+                      <div class="demand-name">{{ p.productName }}</div>
+                      <div class="demand-meta">
+                        <span *ngIf="p.quantity" class="meta-tag">📦 {{ p.quantity }}</span>
+                        <span *ngIf="p.moq" class="meta-tag">MOQ: {{ p.moq }}</span>
+                        <span *ngIf="p.specifications" class="meta-tag">{{ p.specifications }}</span>
+                      </div>
+                      <div class="demand-source">来源: {{ p.source }}</div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+
+              <!-- Info Box -->
+              <div class="info-box">
+                <div class="info-title">
+                  <mat-icon class="info-icon">info</mat-icon>
+                  <span>产品清单来源说明</span>
+                </div>
+                <div class="info-content">
+                  <div class="info-item">📧 邮件正文及附件中的产品描述</div>
+                  <div class="info-item">🌐 公司官网的产品页面</div>
+                </div>
+              </div>
+
+              <!-- Action Buttons -->
+              <div class="import-actions">
+                <button mat-raised-button color="primary"
+                        (click)="importAndScreen()"
+                        [disabled]="!importData.companyName || isImporting || isScreening">
+                  <mat-icon>bolt</mat-icon>
+                  快速筛选并创建线索
+                </button>
+              </div>
+
+              <!-- Screening Progress -->
+              <div *ngIf="isScreening" class="screening-progress card">
+                <mat-progress-spinner mode="indeterminate" diameter="36"></mat-progress-spinner>
+                <div class="progress-text">
+                  <h4>AI 快速筛选中...</h4>
+                  <p>{{ screeningStep }}</p>
+                </div>
+              </div>
+
+              <!-- Screen Result -->
+              <div *ngIf="importScreenResult" class="import-result">
+                <app-screen-result-card
+                  [result]="importScreenResult"
+                  (createLead)="onCreateImportLead()"
+                  (dismiss)="importScreenResult = null">
+                </app-screen-result-card>
+              </div>
+            </div>
+          </div>
+        </mat-tab>
+      </mat-tab-group>
+
+      <!-- ===== Email Drawer Overlay ===== -->
+      <div class="drawer-overlay" *ngIf="drawerEmail" (click)="closeEmailDrawer()"></div>
+      <div class="email-drawer" [class.open]="drawerEmail">
+        <div class="drawer-header" *ngIf="drawerEmail">
+          <h3>📧 原始邮件</h3>
+          <button mat-icon-button (click)="closeEmailDrawer()">
+            <mat-icon>close</mat-icon>
+          </button>
+        </div>
+        <div class="drawer-body" *ngIf="drawerEmail">
+          <div class="drawer-meta">
+            <div class="drawer-meta-row">
+              <span class="drawer-label">发件人</span>
+              <span>{{ drawerEmail.fromName }} &lt;{{ drawerEmail.from }}&gt;</span>
+            </div>
+            <div class="drawer-meta-row">
+              <span class="drawer-label">收件人</span>
+              <span>{{ drawerEmail.to }}</span>
+            </div>
+            <div class="drawer-meta-row" *ngIf="drawerEmail.cc">
+              <span class="drawer-label">抄送</span>
+              <span>{{ drawerEmail.cc }}</span>
+            </div>
+            <div class="drawer-meta-row">
+              <span class="drawer-label">时间</span>
+              <span>{{ drawerEmail.receivedAt | date:'yyyy-MM-dd HH:mm:ss' }}</span>
+            </div>
+            <div class="drawer-meta-row">
+              <span class="drawer-label">主题</span>
+              <span class="drawer-subject">{{ drawerEmail.subject }}</span>
+            </div>
+          </div>
+
+          <!-- Attachments -->
+          <div class="drawer-attachments" *ngIf="drawerEmail.attachments.length > 0">
+            <div class="drawer-att-header">
+              <mat-icon>attach_file</mat-icon>
+              附件 ({{ drawerEmail.attachments.length }})
+              <span class="att-total-size">共 {{ getTotalSize(drawerEmail.attachments) }}</span>
+            </div>
+            <div class="drawer-att-grid">
+              <div class="drawer-att-card" *ngFor="let att of drawerEmail.attachments" (click)="downloadAttachment(att)">
+                <div class="att-icon-wrap" [class]="getAttColorClass(att.mimeType)">
+                  <mat-icon>{{ att.icon }}</mat-icon>
+                </div>
+                <div class="att-info">
+                  <span class="att-name" [title]="att.fileName">{{ att.fileName }}</span>
+                  <span class="att-size">{{ formatFileSize(att.fileSize) }}</span>
+                </div>
+                <mat-icon class="att-download-icon">download</mat-icon>
+              </div>
+            </div>
+          </div>
+
+          <mat-divider></mat-divider>
+
+          <div class="drawer-email-body">
+            <pre class="email-body-text">{{ drawerEmail.body }}</pre>
+          </div>
+        </div>
+      </div>
+
+    </div>
+
+    <!-- ===== Inbox Full-Screen Overlay (outside page-container to avoid sidenav clipping) ===== -->
+    <div class="inbox-overlay" *ngIf="inboxOpen" (click)="closeInbox()"></div>
+    <div class="inbox-modal" *ngIf="inboxOpen">
+      <!-- Inbox Header -->
+      <div class="inbox-header">
+          <div class="inbox-title">
+            <mat-icon>inbox</mat-icon>
+            <h2>收件箱</h2>
+            <span class="inbox-count">{{ emails.length }} 封邮件</span>
+          </div>
+          <div class="inbox-header-actions">
+            <button mat-icon-button (click)="closeInbox()" matTooltip="关闭">
+              <mat-icon>close</mat-icon>
+            </button>
+          </div>
+        </div>
+
+        <!-- Inbox Body: List + Detail -->
+        <div class="inbox-body">
+          <!-- Left: Email List -->
+          <div class="inbox-list">
+            <div class="inbox-list-item" *ngFor="let email of emails"
+                 [class.active]="selectedInboxEmail?.id === email.id"
+                 (click)="selectInboxEmail(email)">
+              <div class="inbox-item-avatar">
+                <mat-icon>mail</mat-icon>
+              </div>
+              <div class="inbox-item-content">
+                <div class="inbox-item-top">
+                  <span class="inbox-item-sender">{{ email.fromName }}</span>
+                  <span class="inbox-item-time">{{ email.receivedAt | date:'MM/dd HH:mm' }}</span>
+                </div>
+                <div class="inbox-item-subject">{{ email.subject }}</div>
+                <div class="inbox-item-preview">{{ email.preview }}</div>
+                <div class="inbox-item-tags">
+                  <span class="inbox-att-tag" *ngIf="email.attachments.length > 0">
+                    <mat-icon>attach_file</mat-icon> {{ email.attachments.length }}
+                  </span>
+                  <span class="inbox-lead-tag" *ngIf="email.leadId">
+                    <mat-icon>person</mat-icon> 已关联线索
+                  </span>
+                </div>
+              </div>
+            </div>
+          </div>
+
+          <!-- Right: Email Detail -->
+          <div class="inbox-detail" *ngIf="selectedInboxEmail">
+            <div class="inbox-detail-subject">
+              <mat-icon class="subject-icon">email</mat-icon>
+              {{ selectedInboxEmail.subject }}
+            </div>
+
+            <div class="inbox-detail-meta">
+              <div class="inbox-detail-sender-row">
+                <div class="sender-avatar">
+                  <mat-icon>person</mat-icon>
+                </div>
+                <div class="sender-info">
+                  <span class="sender-name">{{ selectedInboxEmail.fromName }}</span>
+                  <span class="sender-email">&lt;{{ selectedInboxEmail.from }}&gt;</span>
+                </div>
+                <span class="detail-time">{{ selectedInboxEmail.receivedAt | date:'yyyy-MM-dd HH:mm:ss' }}</span>
+              </div>
+              <div class="inbox-detail-recipients">
+                <span class="recipient-label">收件人:</span>
+                <span>{{ selectedInboxEmail.to }}</span>
+              </div>
+              <div class="inbox-detail-recipients" *ngIf="selectedInboxEmail.cc">
+                <span class="recipient-label">抄送:</span>
+                <span>{{ selectedInboxEmail.cc }}</span>
+              </div>
+            </div>
+
+            <!-- Attachments -->
+            <div class="inbox-detail-attachments" *ngIf="selectedInboxEmail.attachments.length > 0">
+              <div class="inbox-att-header">
+                <mat-icon>attach_file</mat-icon>
+                <span>附件 ({{ selectedInboxEmail.attachments.length }})</span>
+                <span class="att-total-size">共 {{ getTotalSize(selectedInboxEmail.attachments) }}</span>
+              </div>
+              <div class="inbox-att-list">
+                <div class="inbox-att-chip" *ngFor="let att of selectedInboxEmail.attachments" (click)="downloadAttachment(att)">
+                  <div class="att-icon-wrap" [class]="getAttColorClass(att.mimeType)">
+                    <mat-icon>{{ att.icon }}</mat-icon>
+                  </div>
+                  <div class="att-info">
+                    <span class="att-name" [title]="att.fileName">{{ att.fileName }}</span>
+                    <span class="att-size">{{ formatFileSize(att.fileSize) }}</span>
+                  </div>
+                  <mat-icon class="att-download-icon">download</mat-icon>
+                </div>
+              </div>
+            </div>
+
+            <mat-divider></mat-divider>
+
+            <!-- Email Body -->
+            <div class="inbox-detail-body">
+              <pre class="email-body-text">{{ selectedInboxEmail.body }}</pre>
+            </div>
+
+            <!-- Actions -->
+            <div class="inbox-detail-actions" *ngIf="getLeadForEmail(selectedInboxEmail) as lead">
+              <button mat-raised-button color="primary" (click)="openLead(lead); closeInbox()">
+                <mat-icon>open_in_new</mat-icon> 查看关联线索:{{ lead.companyName }}
+              </button>
+            </div>
+          </div>
+
+          <!-- Empty State -->
+          <div class="inbox-detail inbox-empty-detail" *ngIf="!selectedInboxEmail">
+            <mat-icon>markunread_mailbox</mat-icon>
+            <p>选择一封邮件查看详情</p>
+          </div>
+        </div>
+      </div>
+  `,
+    styles: [`
+    /* ===== Page Header ===== */
+    .page-header {
+      display: flex;
+      justify-content: space-between;
+      align-items: flex-start;
+      margin-bottom: 24px;
+    }
+    .page-header h1 {
+      display: flex; align-items: center; gap: 8px;
+      font-size: 24px; font-weight: 600; margin: 0;
+    }
+    .page-header h1 mat-icon { color: #1976d2; }
+    .subtitle { font-size: 14px; color: #666; margin: 4px 0 0; }
+    .header-date {
+      display: flex; align-items: center; gap: 6px;
+      font-size: 14px; color: #888;
+      background: #fff; padding: 8px 16px; border-radius: 10px;
+      box-shadow: 0 1px 4px rgba(0,0,0,0.06);
+    }
+    .header-date mat-icon { font-size: 18px; width: 18px; height: 18px; }
+
+    /* ===== Stats Row ===== */
+    .stats-row {
+      display: grid;
+      grid-template-columns: repeat(4, 1fr);
+      gap: 16px;
+      margin-bottom: 20px;
+    }
+    .stat-card {
+      display: flex; align-items: center; gap: 14px;
+      padding: 18px 20px;
+      background: #fff;
+      border-radius: 14px;
+      box-shadow: 0 2px 8px rgba(0,0,0,0.06);
+      transition: transform 0.2s;
+    }
+    .stat-card:hover { transform: translateY(-2px); }
+    .stat-icon-wrap {
+      width: 48px; height: 48px; border-radius: 12px;
+      display: flex; align-items: center; justify-content: center;
+    }
+    .stat-icon-wrap mat-icon { font-size: 24px; width: 24px; height: 24px; color: #fff; }
+    .stat-card.new .stat-icon-wrap { background: linear-gradient(135deg, #1976d2, #1565c0); }
+    .stat-card.pending .stat-icon-wrap { background: linear-gradient(135deg, #ff9800, #ef6c00); }
+    .stat-card.verified .stat-icon-wrap { background: linear-gradient(135deg, #43a047, #2e7d32); }
+    .stat-card.pipeline .stat-icon-wrap { background: linear-gradient(135deg, #8e24aa, #6a1b9a); }
+    .stat-value { display: block; font-size: 24px; font-weight: 700; color: #1a1a2e; }
+    .stat-label { font-size: 12px; color: #888; }
+
+    /* ===== Batch Status ===== */
+    .batch-status { padding: 14px 20px; margin-bottom: 20px; }
+    .batch-header {
+      display: flex; align-items: center; gap: 8px;
+      font-size: 14px; font-weight: 600;
+    }
+    .batch-header mat-icon { color: #1976d2; }
+    .batch-time { font-size: 12px; color: #999; font-weight: 400; }
+    .batch-badge {
+      margin-left: auto;
+      font-size: 12px; padding: 2px 10px; border-radius: 10px;
+    }
+    .status-completed { background: #e8f5e9; color: #2e7d32; }
+    .status-running { background: #fff3e0; color: #e65100; }
+    .status-failed { background: #ffebee; color: #c62828; }
+    .batch-stats {
+      display: flex; gap: 20px; margin-top: 8px;
+      font-size: 13px; color: #666;
+    }
+    .batch-stats strong { color: #1a1a2e; }
+
+    /* ===== Tabs ===== */
+    .main-tabs {
+      background: transparent;
+    }
+    ::ng-deep .main-tabs .mat-mdc-tab-labels {
+      background: #fff;
+      border-radius: 12px 12px 0 0;
+      padding: 0 8px;
+      box-shadow: 0 1px 4px rgba(0,0,0,0.04);
+    }
+    ::ng-deep .main-tabs .mat-mdc-tab {
+      min-width: 140px;
+    }
+    .tab-label-text { margin-left: 6px; }
+    .tab-count {
+      margin-left: 6px;
+      background: #c62828;
+      color: #fff;
+      padding: 1px 7px;
+      border-radius: 10px;
+      font-size: 11px;
+      font-weight: 600;
+    }
+    .tab-content { padding-top: 20px; }
+
+    /* ===== Content Grid (Tab 1) ===== */
+    .content-grid {
+      display: grid;
+      grid-template-columns: 1.2fr 1fr;
+      gap: 20px;
+    }
+    .section-card { padding: 20px; }
+    .section-header {
+      display: flex; align-items: center; gap: 8px; margin-bottom: 16px;
+    }
+    .section-header mat-icon { color: #1976d2; }
+    .section-header h3 { margin: 0; font-size: 16px; flex: 1; }
+    .count-badge {
+      background: #e3f2fd; color: #1565c0;
+      padding: 2px 10px; border-radius: 10px;
+      font-size: 12px; font-weight: 600;
+    }
+
+    /* Verify Cards */
+    .lead-verify-list { display: flex; flex-direction: column; gap: 12px; }
+    .verify-card {
+      padding: 16px;
+      background: #fafbfc;
+      border-radius: 12px;
+      border-left: 4px solid #ccc;
+      transition: all 0.2s;
+    }
+    .verify-card:hover { background: #f0f4ff; box-shadow: 0 2px 8px rgba(0,0,0,0.06); }
+    .persona-border-p1 { border-left-color: #1565c0; }
+    .persona-border-p2 { border-left-color: #2e7d32; }
+    .persona-border-p3 { border-left-color: #6a1b9a; }
+    .persona-border-p4 { border-left-color: #e65100; }
+    .persona-border-p5 { border-left-color: #00838f; }
+    .persona-border-p6 { border-left-color: #9e9e9e; }
+
+    .verify-top { display: flex; gap: 12px; align-items: center; }
+    .verify-avatar {
+      width: 40px; height: 40px; border-radius: 10px;
+      display: flex; align-items: center; justify-content: center;
+      flex-shrink: 0;
+    }
+    .verify-avatar mat-icon { font-size: 20px; width: 20px; height: 20px; color: #fff; }
+    .verify-info { flex: 1; }
+    .verify-company { font-size: 15px; font-weight: 600; color: #1a1a2e; }
+    .verify-tags { display: flex; gap: 6px; margin-top: 4px; flex-wrap: wrap; align-items: center; }
+    .persona-tag {
+      font-size: 11px; padding: 2px 8px; border-radius: 8px; font-weight: 600;
+    }
+    .grade-tag {
+      font-size: 11px; padding: 2px 8px; border-radius: 8px; font-weight: 600;
+    }
+    .grade-s { background: #ffebee; color: #c62828; }
+    .grade-a { background: #fff3e0; color: #e65100; }
+    .grade-b { background: #fffde7; color: #f9a825; }
+    .grade-c { background: #fafafa; color: #757575; }
+    .flag { font-size: 14px; }
+    .verify-value { font-size: 18px; font-weight: 700; color: #2e7d32; white-space: nowrap; }
+
+    .verify-ai-reason {
+      display: flex; align-items: center; gap: 6px;
+      margin-top: 10px; padding: 8px 12px;
+      background: #f0f4ff; border-radius: 8px;
+      font-size: 13px; color: #1565c0;
+    }
+    .verify-ai-reason mat-icon { font-size: 16px; width: 16px; height: 16px; }
+
+    .verify-keywords {
+      display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px;
+    }
+    .keyword-chip {
+      font-size: 11px; padding: 2px 8px;
+      background: #e8eaf6; color: #5c6bc0;
+      border-radius: 6px; font-family: monospace;
+    }
+
+    .verify-actions {
+      display: flex; gap: 8px; margin-top: 12px; align-items: center;
+    }
+    .action-btn { font-size: 12px; }
+    .action-btn mat-icon { font-size: 16px; width: 16px; height: 16px; margin-right: 2px; }
+
+    .empty-verify {
+      text-align: center; padding: 40px 20px; color: #999;
+    }
+    .empty-verify mat-icon { font-size: 48px; width: 48px; height: 48px; color: #ddd; }
+
+    /* Persona Distribution */
+    .persona-dist-list { display: flex; flex-direction: column; gap: 12px; }
+    .dist-row { display: flex; align-items: center; gap: 10px; }
+    .dist-label {
+      display: flex; align-items: center; gap: 6px;
+      font-size: 13px; min-width: 130px; color: #555;
+    }
+    .dist-label mat-icon { font-size: 18px; width: 18px; height: 18px; }
+    .dist-bar-wrap {
+      flex: 1; height: 8px; background: #f0f0f0;
+      border-radius: 4px; overflow: hidden;
+    }
+    .dist-bar { height: 100%; border-radius: 4px; transition: width 0.5s; }
+    .dist-count { font-size: 12px; color: #888; min-width: 70px; text-align: right; }
+
+    /* Activity */
+    .activity-list { display: flex; flex-direction: column; gap: 10px; }
+    .activity-item { display: flex; gap: 10px; align-items: flex-start; }
+    .activity-dot {
+      width: 8px; height: 8px; border-radius: 50%;
+      margin-top: 5px; flex-shrink: 0;
+    }
+    .activity-content { flex: 1; }
+    .activity-text { font-size: 13px; color: #444; display: block; }
+    .activity-time { font-size: 11px; color: #999; }
+
+    /* Quick Links */
+    .quick-links { display: flex; gap: 10px; flex-wrap: wrap; }
+    .quick-links button { font-size: 13px; }
+    .quick-links mat-icon { font-size: 18px; width: 18px; height: 18px; margin-right: 4px; }
+
+    /* ===== Tab 2: Import Section ===== */
+    .import-section { padding: 24px; }
+    .section-title-row {
+      display: inline-flex;
+      gap: 10px;
+      align-items: center;
+      font-size: 16px;
+      font-weight: 700;
+      color: #1a1a2e;
+      margin-bottom: 16px;
+    }
+    .section-title-row .section-icon { color: #1976d2; }
+
+    .import-banner {
+      border: 2px dashed #d1d5db;
+      border-radius: 14px;
+      background: linear-gradient(135deg, #f8fafc 0%, #f0f4ff 100%);
+      cursor: pointer;
+      transition: all 0.2s;
+      margin-bottom: 16px;
+    }
+    .import-banner:hover { border-color: #1976d2; background: linear-gradient(135deg, #f0f4ff 0%, #e8f0fe 100%); }
+    .import-banner.disabled { opacity: 0.6; pointer-events: none; }
+    .import-drop-zone {
+      display: flex;
+      align-items: center;
+      gap: 16px;
+      padding: 16px 20px;
+    }
+    .upload-icon { font-size: 36px; width: 36px; height: 36px; color: #1976d2; flex-shrink: 0; }
+    .drop-text { flex: 1; display: flex; flex-direction: column; gap: 2px; }
+    .drop-main { font-size: 14px; font-weight: 600; color: #333; }
+    .drop-hint { font-size: 12px; color: #6b7280; }
+    .import-btn { white-space: nowrap; flex-shrink: 0; }
+
+    .import-progress-section {
+      margin-bottom: 16px;
+      background: #f8fafc;
+      border-radius: 10px;
+      padding: 12px 16px;
+      border: 1px solid #e5e7eb;
+    }
+    .import-progress-info {
+      display: flex;
+      align-items: center;
+      gap: 8px;
+      margin-top: 8px;
+      font-size: 13px;
+      color: #555;
+    }
+
+    .linked-status {
+      margin-bottom: 16px;
+      padding: 10px 14px;
+      border-radius: 12px;
+      border: 1px solid #d1fae5;
+      background: #ecfdf5;
+      color: #065f46;
+      display: flex;
+      align-items: center;
+      gap: 8px;
+      font-size: 12px;
+      font-weight: 700;
+    }
+    .linked-status mat-icon { width: 18px; height: 18px; font-size: 18px; }
+    .clear-import-btn { margin-left: auto; }
+    .clear-import-btn mat-icon { font-size: 16px; width: 16px; height: 16px; }
+
+    .import-form-grid {
+      display: grid;
+      grid-template-columns: 1fr 1fr;
+      gap: 16px;
+      margin-bottom: 16px;
+    }
+    .form-item {
+      display: flex;
+      flex-direction: column;
+      gap: 6px;
+    }
+    .form-item .label {
+      font-size: 13px;
+      font-weight: 600;
+      color: #374151;
+    }
+    .form-item .required { margin-left: 4px; color: #ef4444; font-weight: 800; }
+    .form-input {
+      width: 100%;
+      padding: 10px 14px;
+      border: 1px solid #e5e7eb;
+      border-radius: 10px;
+      font-size: 14px;
+      color: #111827;
+      background: #fff;
+      transition: border-color 0.15s, box-shadow 0.15s;
+      box-sizing: border-box;
+    }
+    .form-input::placeholder { color: #9ca3af; }
+    .form-input:hover { border-color: #d1d5db; }
+    .form-input:focus { outline: none; border-color: #1976d2; box-shadow: 0 0 0 3px rgba(25,118,210,0.1); }
+    .form-item .hint {
+      font-size: 12px;
+      color: #6b7280;
+      display: inline-flex;
+      gap: 6px;
+      align-items: center;
+    }
+    .form-item .hint-icon { width: 16px; height: 16px; font-size: 16px; opacity: 0.85; }
+
+    /* Product Demands */
+    .product-demands-section {
+      margin-bottom: 16px;
+      background: #f8f9fb;
+      border-radius: 12px;
+      padding: 14px 16px;
+      border: 1px solid #eef0f4;
+    }
+    .demands-header {
+      display: flex;
+      align-items: center;
+      gap: 6px;
+      font-size: 13px;
+      font-weight: 600;
+      color: #555;
+      margin-bottom: 10px;
+    }
+    .demands-header mat-icon { font-size: 18px; width: 18px; height: 18px; color: #1976d2; }
+    .demands-source-tag {
+      margin-left: auto;
+      font-size: 11px;
+      font-weight: 400;
+      color: #999;
+    }
+    .demands-grid {
+      display: flex;
+      flex-direction: column;
+      gap: 6px;
+      max-height: 240px;
+      overflow-y: auto;
+    }
+    .demand-card {
+      display: flex;
+      align-items: flex-start;
+      gap: 10px;
+      padding: 8px 12px;
+      background: #fff;
+      border-radius: 8px;
+      border: 1px solid #e8eaee;
+      transition: all 0.15s;
+    }
+    .demand-card:hover { border-color: #1976d2; background: #f0f4ff; }
+    .demand-index {
+      width: 22px; height: 22px;
+      border-radius: 50%;
+      background: #1976d2;
+      color: #fff;
+      font-size: 11px;
+      font-weight: 700;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      flex-shrink: 0;
+      margin-top: 2px;
+    }
+    .demand-info { flex: 1; min-width: 0; }
+    .demand-name { font-size: 13px; font-weight: 600; color: #333; }
+    .demand-meta { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 2px; }
+    .meta-tag {
+      font-size: 11px;
+      padding: 1px 6px;
+      border-radius: 6px;
+      background: #f0f4ff;
+      color: #1976d2;
+    }
+    .demand-source { font-size: 11px; color: #999; margin-top: 2px; }
+
+    /* Info Box */
+    .info-box {
+      margin-bottom: 16px;
+      padding: 12px 14px;
+      border-radius: 10px;
+      border: 1px solid #e5e7eb;
+      background: #fafafa;
+    }
+    .info-title {
+      display: flex;
+      align-items: center;
+      gap: 6px;
+      font-size: 13px;
+      font-weight: 600;
+      color: #555;
+      margin-bottom: 6px;
+    }
+    .info-title .info-icon { font-size: 16px; width: 16px; height: 16px; color: #1976d2; }
+    .info-content { display: flex; flex-direction: column; gap: 4px; }
+    .info-item { font-size: 12px; color: #6b7280; padding-left: 22px; }
+
+    .import-actions {
+      display: flex;
+      gap: 12px;
+      align-items: center;
+    }
+    .import-result { margin-top: 16px; }
+
+    .screening-progress {
+      display: flex;
+      align-items: center;
+      gap: 16px;
+      padding: 20px;
+      margin-top: 16px;
+    }
+    .progress-text h4 { margin: 0; font-size: 15px; }
+    .progress-text p { margin: 4px 0 0; font-size: 13px; color: #666; }
+
+    /* ===== Email Drawer ===== */
+    .drawer-overlay {
+      position: fixed;
+      top: 0; left: 0; right: 0; bottom: 0;
+      background: rgba(0,0,0,0.35);
+      z-index: 999;
+      animation: fadeIn 0.2s;
+    }
+    .email-drawer {
+      position: fixed;
+      top: 0; right: -520px; bottom: 0;
+      width: 520px;
+      background: #fff;
+      box-shadow: -4px 0 24px rgba(0,0,0,0.15);
+      z-index: 1000;
+      transition: right 0.3s ease;
+      display: flex;
+      flex-direction: column;
+      overflow: hidden;
+    }
+    .email-drawer.open { right: 0; }
+
+    .drawer-header {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      padding: 16px 20px;
+      border-bottom: 1px solid #eee;
+      flex-shrink: 0;
+    }
+    .drawer-header h3 { margin: 0; font-size: 16px; }
+
+    .drawer-body {
+      flex: 1;
+      overflow-y: auto;
+      padding: 20px;
+    }
+
+    .drawer-meta {
+      display: flex;
+      flex-direction: column;
+      gap: 8px;
+      margin-bottom: 16px;
+    }
+    .drawer-meta-row {
+      display: flex;
+      gap: 10px;
+      font-size: 13px;
+      color: #555;
+    }
+    .drawer-label {
+      color: #999;
+      font-size: 12px;
+      min-width: 48px;
+      flex-shrink: 0;
+    }
+    .drawer-subject {
+      font-weight: 600;
+      color: #1a1a2e;
+    }
+
+    /* Drawer Attachments */
+    .drawer-attachments {
+      margin: 16px 0;
+      background: #f8f9fb;
+      border-radius: 10px;
+      padding: 12px 16px;
+      border: 1px solid #eef0f4;
+    }
+    .drawer-att-header {
+      display: flex;
+      align-items: center;
+      gap: 6px;
+      font-size: 13px;
+      font-weight: 600;
+      color: #555;
+      margin-bottom: 10px;
+    }
+    .drawer-att-header mat-icon { font-size: 18px; width: 18px; height: 18px; color: #888; }
+    .att-total-size {
+      margin-left: auto;
+      font-size: 11px;
+      font-weight: 400;
+      color: #999;
+    }
+    .drawer-att-grid {
+      display: flex;
+      flex-direction: column;
+      gap: 6px;
+    }
+    .drawer-att-card {
+      display: flex;
+      align-items: center;
+      gap: 10px;
+      padding: 8px 12px;
+      background: #fff;
+      border-radius: 8px;
+      border: 1px solid #e8eaee;
+      cursor: pointer;
+      transition: all 0.15s;
+    }
+    .drawer-att-card:hover {
+      border-color: #1976d2;
+      background: #f0f4ff;
+    }
+    .att-icon-wrap {
+      width: 34px; height: 34px; border-radius: 8px;
+      display: flex; align-items: center; justify-content: center;
+      flex-shrink: 0;
+    }
+    .att-icon-wrap mat-icon { font-size: 18px; width: 18px; height: 18px; color: #fff; }
+    .att-color-pdf { background: linear-gradient(135deg, #e53935, #c62828); }
+    .att-color-doc { background: linear-gradient(135deg, #1976d2, #1565c0); }
+    .att-color-xls { background: linear-gradient(135deg, #43a047, #2e7d32); }
+    .att-color-zip { background: linear-gradient(135deg, #ff9800, #ef6c00); }
+    .att-color-img { background: linear-gradient(135deg, #8e24aa, #6a1b9a); }
+    .att-color-other { background: linear-gradient(135deg, #78909c, #546e7a); }
+
+    .att-info { flex: 1; min-width: 0; }
+    .att-name {
+      display: block;
+      font-size: 12px;
+      font-weight: 500;
+      color: #333;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+    }
+    .att-size { font-size: 11px; color: #999; }
+    .att-download-icon {
+      font-size: 18px; width: 18px; height: 18px;
+      color: #bbb; flex-shrink: 0;
+    }
+    .drawer-att-card:hover .att-download-icon { color: #1976d2; }
+
+    .drawer-email-body { padding-top: 16px; }
+    .email-body-text {
+      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+      font-size: 14px;
+      line-height: 1.7;
+      color: #333;
+      white-space: pre-wrap;
+      word-wrap: break-word;
+      margin: 0;
+      padding: 0;
+      background: transparent;
+      border: none;
+    }
+
+    @keyframes fadeIn {
+      from { opacity: 0; }
+      to { opacity: 1; }
+    }
+
+    /* ===== Header Actions ===== */
+    .header-actions { display: flex; align-items: center; gap: 12px; }
+    .inbox-btn {
+      display: flex; align-items: center; gap: 6px;
+      font-size: 14px; font-weight: 500;
+      border-radius: 10px; padding: 6px 16px;
+    }
+    .inbox-btn mat-icon { font-size: 20px; width: 20px; height: 20px; }
+
+    /* ===== Inbox Modal (centered in content area) ===== */
+    :host {
+      position: relative;
+    }
+    .inbox-overlay {
+      position: fixed;
+      top: 0; left: 0; right: 0; bottom: 0;
+      background: rgba(0,0,0,0.35);
+      z-index: 1100;
+      animation: fadeIn 0.2s;
+    }
+    .inbox-modal {
+      position: fixed;
+      top: 50%;
+      left: calc((100vw + 220px) / 2);  /* center of the content area (right of 220px sidenav) */
+      transform: translate(-50%, -50%);
+      width: calc(100vw - 220px - 80px);  /* content width minus padding */
+      max-width: 1100px;
+      height: calc(100vh - 140px);  /* leave room for toolbar + padding */
+      max-height: 720px;
+      background: #fff;
+      border-radius: 16px;
+      z-index: 1101;
+      display: flex;
+      flex-direction: column;
+      overflow: hidden;
+      box-shadow: 0 20px 60px rgba(0,0,0,0.25);
+      animation: inboxSlideIn 0.3s ease;
+    }
+    @keyframes inboxSlideIn {
+      from { opacity: 0; transform: translate(-50%, -50%) scale(0.95); }
+      to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
+    }
+
+    .inbox-header {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      padding: 16px 24px;
+      border-bottom: 1px solid #eee;
+      flex-shrink: 0;
+      background: linear-gradient(135deg, #f8fafc, #f0f4ff);
+    }
+    .inbox-title {
+      display: flex; align-items: center; gap: 10px;
+    }
+    .inbox-title mat-icon { font-size: 24px; width: 24px; height: 24px; color: #1976d2; }
+    .inbox-title h2 { margin: 0; font-size: 18px; font-weight: 700; color: #1a1a2e; }
+    .inbox-count {
+      font-size: 12px; color: #666;
+      background: #e3f2fd; padding: 2px 10px; border-radius: 10px;
+    }
+    .inbox-header-actions { display: flex; align-items: center; gap: 8px; }
+
+    /* Inbox Body: Split Layout */
+    .inbox-body {
+      display: flex;
+      flex: 1;
+      overflow: hidden;
+    }
+
+    /* Left: Email List */
+    .inbox-list {
+      width: 380px;
+      flex-shrink: 0;
+      border-right: 1px solid #eee;
+      overflow-y: auto;
+      background: #fafbfc;
+    }
+    .inbox-list-item {
+      display: flex;
+      gap: 12px;
+      padding: 14px 18px;
+      cursor: pointer;
+      border-bottom: 1px solid #f0f0f0;
+      transition: all 0.15s;
+    }
+    .inbox-list-item:hover { background: #f0f4ff; }
+    .inbox-list-item.active {
+      background: #e3f2fd;
+      border-left: 3px solid #1976d2;
+      padding-left: 15px;
+    }
+    .inbox-item-avatar {
+      width: 36px; height: 36px; border-radius: 50%;
+      display: flex; align-items: center; justify-content: center;
+      background: #e8eaf6; flex-shrink: 0; margin-top: 2px;
+    }
+    .inbox-item-avatar mat-icon { font-size: 18px; width: 18px; height: 18px; color: #5c6bc0; }
+
+    .inbox-item-content { flex: 1; min-width: 0; }
+    .inbox-item-top {
+      display: flex; justify-content: space-between; align-items: center;
+    }
+    .inbox-item-sender { font-size: 13px; color: #333; font-weight: 500; }
+    .inbox-item-time { font-size: 11px; color: #999; flex-shrink: 0; }
+    .inbox-item-subject {
+      font-size: 13px; color: #555; margin-top: 2px;
+      white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
+    }
+    .inbox-item-preview {
+      font-size: 12px; color: #999; margin-top: 2px;
+      white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
+    }
+    .inbox-item-tags {
+      display: flex; gap: 6px; margin-top: 4px;
+    }
+    .inbox-att-tag, .inbox-lead-tag {
+      display: inline-flex; align-items: center; gap: 2px;
+      font-size: 10px; padding: 1px 6px; border-radius: 6px;
+    }
+    .inbox-att-tag {
+      background: #f5f5f5; color: #888;
+    }
+    .inbox-att-tag mat-icon, .inbox-lead-tag mat-icon {
+      font-size: 12px; width: 12px; height: 12px;
+    }
+    .inbox-lead-tag {
+      background: #e8f5e9; color: #2e7d32;
+    }
+
+    /* Right: Email Detail */
+    .inbox-detail {
+      flex: 1;
+      overflow-y: auto;
+      padding: 24px 28px;
+      display: flex;
+      flex-direction: column;
+    }
+    .inbox-empty-detail {
+      align-items: center;
+      justify-content: center;
+      color: #bbb;
+    }
+    .inbox-empty-detail mat-icon {
+      font-size: 64px; width: 64px; height: 64px; color: #ddd; margin-bottom: 12px;
+    }
+    .inbox-empty-detail p { font-size: 15px; }
+
+    .inbox-detail-subject {
+      display: flex; align-items: flex-start; gap: 10px;
+      font-size: 20px; font-weight: 700; color: #1a1a2e;
+      margin-bottom: 20px; line-height: 1.4;
+    }
+    .subject-icon {
+      color: #1976d2; font-size: 24px; width: 24px; height: 24px;
+      flex-shrink: 0; margin-top: 2px;
+    }
+
+    .inbox-detail-meta {
+      background: #f8f9fb;
+      border-radius: 12px;
+      padding: 16px;
+      margin-bottom: 16px;
+      border: 1px solid #eef0f4;
+    }
+    .inbox-detail-sender-row {
+      display: flex; align-items: center; gap: 12px; margin-bottom: 10px;
+    }
+    .sender-avatar {
+      width: 40px; height: 40px; border-radius: 50%;
+      background: linear-gradient(135deg, #1976d2, #1565c0);
+      display: flex; align-items: center; justify-content: center;
+      flex-shrink: 0;
+    }
+    .sender-avatar mat-icon { color: #fff; font-size: 20px; width: 20px; height: 20px; }
+    .sender-info { flex: 1; }
+    .sender-name { font-size: 15px; font-weight: 600; color: #1a1a2e; display: block; }
+    .sender-email { font-size: 12px; color: #888; }
+    .detail-time { font-size: 12px; color: #999; flex-shrink: 0; }
+
+    .inbox-detail-recipients {
+      font-size: 13px; color: #666; padding: 4px 0 4px 52px;
+    }
+    .recipient-label { color: #999; font-size: 12px; margin-right: 4px; }
+
+    .inbox-detail-attachments {
+      background: #f8f9fb;
+      border-radius: 12px;
+      padding: 14px 16px;
+      margin-bottom: 16px;
+      border: 1px solid #eef0f4;
+    }
+    .inbox-att-header {
+      display: flex; align-items: center; gap: 6px;
+      font-size: 13px; font-weight: 600; color: #555;
+      margin-bottom: 10px;
+    }
+    .inbox-att-header mat-icon { font-size: 18px; width: 18px; height: 18px; color: #888; }
+    .inbox-att-list {
+      display: flex; flex-direction: column; gap: 6px;
+    }
+    .inbox-att-chip {
+      display: flex; align-items: center; gap: 10px;
+      padding: 8px 12px; background: #fff; border-radius: 8px;
+      border: 1px solid #e8eaee; cursor: pointer; transition: all 0.15s;
+    }
+    .inbox-att-chip:hover { border-color: #1976d2; background: #f0f4ff; }
+    .inbox-att-chip:hover .att-download-icon { color: #1976d2; }
+
+    .inbox-detail-body {
+      flex: 1; padding-top: 16px;
+    }
+
+    .inbox-detail-actions {
+      padding: 16px 0;
+      border-top: 1px solid #eee;
+      margin-top: 16px;
+    }
+
+    /* ===== Responsive ===== */
+    @media (max-width: 1000px) {
+      .stats-row { grid-template-columns: repeat(2, 1fr); }
+      .content-grid { grid-template-columns: 1fr; }
+      .email-drawer { width: 100%; right: -100%; }
+      .inbox-modal {
+        left: 50%; width: calc(100vw - 32px); max-height: calc(100vh - 80px);
+        border-radius: 12px;
+      }
+      .inbox-list { width: 280px; }
+    }
+    @media (max-width: 600px) {
+      .stats-row { grid-template-columns: 1fr; }
+      .import-form-grid { grid-template-columns: 1fr; }
+      .inbox-body { flex-direction: column; }
+      .inbox-list { width: 100%; max-height: 40%; border-right: none; border-bottom: 1px solid #eee; }
+    }
+  `]
+})
+export class DashboardComponent implements OnInit {
+  today = new Date();
+  leads: Lead[] = [];
+  pendingLeads: Lead[] = [];
+  pendingCount = 0;
+  verifiedCount = 0;
+  totalPipeline = 0;
+  latestBatch: any = null;
+  activeTab = 0;
+
+  personaDistribution: { id: string; name: string; icon: string; color: string; count: number; percent: number }[] = [];
+  recentActivities: { text: string; time: string; color: string }[] = [];
+
+  // ===== Email Drawer =====
+  emails: Email[] = [];
+  drawerEmail: Email | null = null;
+
+  // ===== Inbox =====
+  inboxOpen = false;
+  selectedInboxEmail: Email | null = null;
+
+  // ===== Import (migrated from Inbox) =====
+  isImporting = false;
+  isScreening = false;
+  screeningStep = '';
+  importProgress = 0;
+  importStepMessage = '';
+  importedEmailId: string | null = null;
+  importScreenResult: QuickScreenResult | null = null;
+
+  importData = {
+    companyName: '',
+    contactName: '',
+    roleDescription: '',
+    email: '',
+    website: ''
+  };
+
+  importedProducts: EmlProductDemand[] = [];
+  importedAttachmentStats: { total: number; analyzed: number; skipped: number; bodyAnalyzed: boolean } | null = null;
+
+  // EML API 配置
+  private readonly EML_API_URL = 'https://eml.brainwork.club:8900';
+  private readonly EML_API_KEY = 'fmode_cb_tgUyPSUXWZeLCgXVoLoCfOBingKQ9yAp';
+
+  constructor(
+    private mockData: MockDataService,
+    private screenService: QuickScreenService,
+    private snackBar: MatSnackBar,
+    public router: Router,
+    private http: HttpClient,
+  ) {}
+
+  ngOnInit() {
+    this.leads = [...this.mockData.leads];
+    this.emails = [...this.mockData.emails];
+    this.pendingLeads = this.leads.filter(l => !l.personaVerified);
+    this.pendingCount = this.pendingLeads.length;
+    this.verifiedCount = this.leads.filter(l => l.personaVerified).length;
+    this.totalPipeline = this.leads.reduce((sum, l) => sum + l.estimatedOrderValue, 0);
+    this.latestBatch = this.mockData.discoveryBatches[0] || null;
+
+    this.buildPersonaDistribution();
+    this.buildRecentActivities();
+  }
+
+  // ===== Dashboard Logic =====
+
+  private buildPersonaDistribution() {
+    const counts: Record<string, number> = {};
+    for (const l of this.leads) {
+      counts[l.persona] = (counts[l.persona] || 0) + 1;
+    }
+    const total = this.leads.length || 1;
+    this.personaDistribution = PERSONA_LIST.map(p => ({
+      id: p.id,
+      name: p.name,
+      icon: p.icon,
+      color: p.color,
+      count: counts[p.id] || 0,
+      percent: Math.round(((counts[p.id] || 0) / total) * 100),
+    })).sort((a, b) => b.count - a.count);
+  }
+
+  private buildRecentActivities() {
+    this.recentActivities = [
+      { text: 'AI 完成每日批量处理,发现 12 条新线索', time: '今天 08:00', color: '#1976d2' },
+      { text: 'Acme Medical Supplies 标记为 S 级 · P1-医药分销商', time: '今天 08:30', color: '#c62828' },
+      { text: 'Polish Red Cross 招标通知已入库', time: '昨天 14:00', color: '#6a1b9a' },
+      { text: 'WildGear OEM 询盘已分类为 P4-品牌OEM', time: '昨天 10:45', color: '#e65100' },
+      { text: 'MediTech Supply 进入寄样阶段', time: '2天前', color: '#2e7d32' },
+      { text: 'Global Trading 88 标记为低质量线索', time: '3天前', color: '#9e9e9e' },
+    ];
+  }
+
+  getPersonaColor(p: CustomerPersona): string { return PERSONA_DEFINITIONS[p]?.color || '#999'; }
+  getPersonaBg(p: CustomerPersona): string { return PERSONA_DEFINITIONS[p]?.bgColor || '#fafafa'; }
+  getPersonaIcon(p: CustomerPersona): string { return PERSONA_DEFINITIONS[p]?.icon || 'business'; }
+  getPersonaStrategy(p: CustomerPersona): string { return PERSONA_DEFINITIONS[p]?.firstAction || ''; }
+
+  getFlag(country: string): string {
+    const flags: Record<string, string> = {
+      US: '🇺🇸', GB: '🇬🇧', DE: '🇩🇪', PL: '🇵🇱', CA: '🇨🇦',
+      AU: '🇦🇺', SE: '🇸🇪', CN: '🇨🇳',
+    };
+    return flags[country] || '🌍';
+  }
+
+  confirmLead(lead: Lead) {
+    lead.personaVerified = true;
+    this.pendingLeads = this.pendingLeads.filter(l => l.id !== lead.id);
+    this.pendingCount--;
+    this.verifiedCount++;
+    this.snackBar.open(`✅ 已确认:${lead.companyName} → ${lead.personaLabel}`, '', { duration: 2000 });
+  }
+
+  editLead(lead: Lead) {
+    this.router.navigate(['/leads', lead.id]);
+  }
+
+  dismissLead(lead: Lead) {
+    lead.personaVerified = true;
+    lead.persona = 'P6';
+    lead.personaLabel = '低质量/无效线索';
+    this.pendingLeads = this.pendingLeads.filter(l => l.id !== lead.id);
+    this.pendingCount--;
+    this.verifiedCount++;
+    this.snackBar.open(`❌ 已标记为无效:${lead.companyName}`, '', { duration: 2000 });
+  }
+
+  openLead(lead: Lead) {
+    this.router.navigate(['/leads', lead.id]);
+  }
+
+  // ===== Email Drawer =====
+
+  getEmailForLead(lead: Lead): Email | undefined {
+    return this.emails.find(e => e.from === lead.contactEmail);
+  }
+
+  showEmailDrawer(lead: Lead) {
+    const email = this.getEmailForLead(lead);
+    if (email) {
+      this.drawerEmail = email;
+    }
+  }
+
+  closeEmailDrawer() {
+    this.drawerEmail = null;
+  }
+
+  // ===== Inbox =====
+
+  openInbox() {
+    this.inboxOpen = true;
+    this.selectedInboxEmail = null;
+  }
+
+  closeInbox() {
+    this.inboxOpen = false;
+    this.selectedInboxEmail = null;
+  }
+
+  selectInboxEmail(email: Email) {
+    this.selectedInboxEmail = email;
+  }
+
+  getLeadForEmail(email: Email): Lead | undefined {
+    return this.leads.find(l => l.contactEmail === email.from);
+  }
+
+  // ===== Import (migrated from Inbox) =====
+
+  importFromEmail() {
+    if (this.isImporting) return;
+    const fileInput = document.createElement('input');
+    fileInput.type = 'file';
+    fileInput.accept = '.eml';
+    fileInput.style.display = 'none';
+
+    fileInput.onchange = async (event: Event) => {
+      await this.onEmlFileSelected(event);
+      document.body.removeChild(fileInput);
+    };
+
+    document.body.appendChild(fileInput);
+    fileInput.click();
+  }
+
+  async onEmlFileSelected(event: Event) {
+    const input = event.target as HTMLInputElement;
+    if (!input.files || input.files.length === 0) return;
+
+    const file = input.files[0];
+    this.isImporting = true;
+    this.importProgress = 0;
+    this.importStepMessage = '📥 正在上传 EML 文件...';
+
+    try {
+      this.importProgress = 15;
+      this.importStepMessage = '📧 正在解析邮件内容...';
+
+      const formData = new FormData();
+      formData.append('file', file, file.name);
+
+      const response = await this.http.post<EmlParseResponse>(
+        `${this.EML_API_URL}/api/parse?analyze_attachments=true`,
+        formData,
+        { headers: new HttpHeaders({ 'X-API-Key': this.EML_API_KEY }) }
+      ).toPromise();
+
+      if (!response || !response.success) {
+        throw new Error(response?.error || '邮件解析失败');
+      }
+
+      this.importProgress = 60;
+      this.importStepMessage = '🔍 正在提取公司信息...';
+      await this.delay(300);
+
+      const data = response.data;
+
+      this.importData.companyName = data.companyName || this.extractCompanyFromDomain(data.companyDomain) || '';
+      this.importData.contactName = data.contactName || data.senderName || '';
+      this.importData.email = data.customerEmail || data.senderEmail || '';
+      this.importData.website = data.companyDomain ? `https://${data.companyDomain}` : '';
+      this.importData.roleDescription = data.title || '';
+
+      this.importedEmailId = data.messageId || `eml-${Date.now()}`;
+      this.importedProducts = data.productDemands || [];
+      this.importedAttachmentStats = data.attachmentStats || null;
+
+      this.importProgress = 90;
+      this.importStepMessage = '✅ 邮件解析完成';
+      await this.delay(300);
+
+      this.importProgress = 100;
+      this.importStepMessage = '✅ 导入成功';
+
+      this.snackBar.open(
+        `✅ 邮件导入成功:${this.importData.companyName || '未知公司'}` +
+        (this.importedProducts.length > 0 ? `,提取 ${this.importedProducts.length} 条产品需求` : ''),
+        '关闭',
+        { duration: 4000 }
+      );
+    } catch (error) {
+      console.error('[email-import] EML导入失败:', error);
+      this.snackBar.open(
+        '❌ 导入EML文件失败: ' + (error as Error).message,
+        '关闭',
+        { duration: 5000 }
+      );
+    } finally {
+      input.value = '';
+      this.isImporting = false;
+    }
+  }
+
+  private extractCompanyFromDomain(domain: string): string {
+    if (!domain) return '';
+    const name = domain.split('.')[0];
+    return name.charAt(0).toUpperCase() + name.slice(1);
+  }
+
+  clearImport() {
+    this.importedEmailId = null;
+    this.importData = { companyName: '', contactName: '', roleDescription: '', email: '', website: '' };
+    this.importedProducts = [];
+    this.importedAttachmentStats = null;
+    this.importScreenResult = null;
+  }
+
+  async importAndScreen() {
+    this.isScreening = true;
+    this.screeningStep = '邮件导入快速筛选中...';
+    this.importScreenResult = await this.screenService.screenManual(
+      this.importData.companyName,
+      this.importData.email
+    );
+    this.isScreening = false;
+  }
+
+  onCreateImportLead() {
+    if (!this.importScreenResult) return;
+    const lead = this.screenService.createLeadFromScreen(this.importScreenResult);
+    this.snackBar.open(`✅ 线索已创建:${lead.companyName}`, '查看看板', { duration: 4000 })
+      .onAction().subscribe(() => {
+        this.router.navigate(['/list']);
+      });
+    this.clearImport();
+  }
+
+  // ===== Attachment Helpers =====
+
+  formatFileSize(bytes: number): string {
+    if (bytes < 1024) return bytes + ' B';
+    if (bytes < 1048576) return (bytes / 1024).toFixed(1) + ' KB';
+    return (bytes / 1048576).toFixed(1) + ' MB';
+  }
+
+  getTotalSize(attachments: EmailAttachment[]): string {
+    const total = attachments.reduce((sum, a) => sum + a.fileSize, 0);
+    return this.formatFileSize(total);
+  }
+
+  getAttColorClass(mimeType: string): string {
+    if (mimeType.includes('pdf')) return 'att-color-pdf';
+    if (mimeType.includes('word') || mimeType.includes('document')) return 'att-color-doc';
+    if (mimeType.includes('sheet') || mimeType.includes('excel')) return 'att-color-xls';
+    if (mimeType.includes('zip') || mimeType.includes('compressed')) return 'att-color-zip';
+    if (mimeType.includes('image')) return 'att-color-img';
+    return 'att-color-other';
+  }
+
+  downloadAttachment(att: EmailAttachment) {
+    this.snackBar.open(`📎 正在下载: ${att.fileName} (${this.formatFileSize(att.fileSize)})`, '', { duration: 2000 });
+  }
+
+  private delay(ms: number): Promise<void> {
+    return new Promise(resolve => setTimeout(resolve, ms));
+  }
+}

+ 356 - 0
lead-discovery/src/app/pages/kanban/kanban.component.ts

@@ -0,0 +1,356 @@
+import { Component, OnInit } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { Router } from '@angular/router';
+import { MatCardModule } from '@angular/material/card';
+import { MatIconModule } from '@angular/material/icon';
+import { MatButtonModule } from '@angular/material/button';
+import { MatChipsModule } from '@angular/material/chips';
+import { MatButtonToggleModule } from '@angular/material/button-toggle';
+import { MatTooltipModule } from '@angular/material/tooltip';
+import { FormsModule } from '@angular/forms';
+import { MockDataService } from '../../services/mock-data.service';
+import {
+  Lead, CustomerCategory, ValueGrade, CustomerPersona,
+  CATEGORY_LABELS, CATEGORY_ICONS, GRADE_LABELS,
+  PERSONA_DEFINITIONS, PERSONA_LIST
+} from '../../models/lead.model';
+
+@Component({
+    selector: 'app-kanban',
+    imports: [
+        CommonModule, FormsModule,
+        MatCardModule, MatIconModule, MatButtonModule,
+        MatChipsModule, MatButtonToggleModule, MatTooltipModule,
+    ],
+    template: `
+    <div class="page-container">
+      <div class="page-header">
+        <div>
+          <h1><mat-icon>view_kanban</mat-icon> 线索看板</h1>
+          <p class="subtitle">多维度看板视图,快速定位高优先级线索</p>
+        </div>
+        <div class="header-stats">
+          <div class="stat-item">
+            <span class="stat-value">{{ leads.length }}</span>
+            <span class="stat-label">总线索</span>
+          </div>
+          <div class="stat-item highlight">
+            <span class="stat-value">{{ getSGradeCount() }}</span>
+            <span class="stat-label">S级</span>
+          </div>
+        </div>
+      </div>
+
+      <!-- View Mode Toggle -->
+      <div class="view-bar card">
+        <div class="view-toggle">
+          <span class="toggle-label">视图:</span>
+          <mat-button-toggle-group [(ngModel)]="viewMode" (change)="onViewChange()">
+            <mat-button-toggle value="grade">
+              <mat-icon>grade</mat-icon> 按等级
+            </mat-button-toggle>
+            <mat-button-toggle value="persona">
+              <mat-icon>category</mat-icon> 按画像
+            </mat-button-toggle>
+            <mat-button-toggle value="stage">
+              <mat-icon>linear_scale</mat-icon> 按阶段
+            </mat-button-toggle>
+          </mat-button-toggle-group>
+        </div>
+
+        <!-- Category Filter -->
+        <mat-button-toggle-group [(ngModel)]="selectedCategory" (change)="filterLeads()">
+          <mat-button-toggle value="all">全部 ({{ leads.length }})</mat-button-toggle>
+          <mat-button-toggle value="A">A-医疗 ({{ countByCategory('A') }})</mat-button-toggle>
+          <mat-button-toggle value="B">B-工业 ({{ countByCategory('B') }})</mat-button-toggle>
+          <mat-button-toggle value="C">C-政府 ({{ countByCategory('C') }})</mat-button-toggle>
+          <mat-button-toggle value="D">D-OEM ({{ countByCategory('D') }})</mat-button-toggle>
+        </mat-button-toggle-group>
+      </div>
+
+      <!-- ===== GRADE VIEW ===== -->
+      <div class="kanban-board" *ngIf="viewMode === 'grade'">
+        <div class="kanban-column" *ngFor="let grade of grades">
+          <div class="column-header" [class]="'col-header-' + grade.toLowerCase()">
+            <div class="col-title">
+              <span class="grade-dot" [class]="'dot-' + grade.toLowerCase()"></span>
+              {{ grade }}级
+              <span class="col-subtitle">{{ gradeLabels[grade] }}</span>
+            </div>
+            <span class="col-count">{{ getFilteredByGrade(grade).length }}</span>
+          </div>
+          <div class="column-body">
+            <div class="lead-card" *ngFor="let lead of getFilteredByGrade(grade)"
+                 [style.border-left-color]="getPersonaColor(lead.persona)"
+                 (click)="openLead(lead)">
+              <ng-container *ngTemplateOutlet="leadCardTpl; context: { $implicit: lead }"></ng-container>
+            </div>
+            <div class="empty-column" *ngIf="getFilteredByGrade(grade).length === 0">
+              <mat-icon>inbox</mat-icon><span>暂无{{ grade }}级线索</span>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- ===== PERSONA VIEW ===== -->
+      <div class="kanban-board persona-board" *ngIf="viewMode === 'persona'">
+        <div class="kanban-column" *ngFor="let p of activePersonas">
+          <div class="column-header persona-col-header" [style.border-bottom-color]="p.color">
+            <div class="col-title">
+              <div class="persona-dot" [style.background]="p.color">
+                <mat-icon>{{ p.icon }}</mat-icon>
+              </div>
+              {{ p.id }}
+              <span class="col-subtitle">{{ p.name }}</span>
+            </div>
+            <span class="col-count">{{ getFilteredByPersona(p.id).length }}</span>
+          </div>
+          <div class="column-body">
+            <div class="lead-card" *ngFor="let lead of getFilteredByPersona(p.id)"
+                 [style.border-left-color]="p.color"
+                 (click)="openLead(lead)">
+              <ng-container *ngTemplateOutlet="leadCardTpl; context: { $implicit: lead }"></ng-container>
+            </div>
+            <div class="empty-column" *ngIf="getFilteredByPersona(p.id).length === 0">
+              <mat-icon>inbox</mat-icon><span>暂无线索</span>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- ===== STAGE VIEW ===== -->
+      <div class="kanban-board stage-board" *ngIf="viewMode === 'stage'">
+        <div class="kanban-column" *ngFor="let stage of stageColumns">
+          <div class="column-header" [style.border-bottom-color]="stage.color">
+            <div class="col-title">
+              <span class="stage-dot" [style.background]="stage.color"></span>
+              {{ stage.label }}
+            </div>
+            <span class="col-count">{{ getFilteredByStage(stage.key).length }}</span>
+          </div>
+          <div class="column-body">
+            <div class="lead-card" *ngFor="let lead of getFilteredByStage(stage.key)"
+                 [style.border-left-color]="getPersonaColor(lead.persona)"
+                 (click)="openLead(lead)">
+              <ng-container *ngTemplateOutlet="leadCardTpl; context: { $implicit: lead }"></ng-container>
+            </div>
+            <div class="empty-column" *ngIf="getFilteredByStage(stage.key).length === 0">
+              <mat-icon>inbox</mat-icon><span>暂无线索</span>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- Shared Lead Card Template -->
+      <ng-template #leadCardTpl let-lead>
+        <div class="lead-card-top">
+          <span class="company-name">{{ lead.companyName }}</span>
+          <span class="country-flag">{{ getFlag(lead.country) }}</span>
+        </div>
+        <div class="lead-card-tags">
+          <span class="tag persona-tag" [style.background]="getPersonaBg(lead.persona)" [style.color]="getPersonaColor(lead.persona)">
+            {{ lead.persona }}
+          </span>
+          <span class="tag" [class]="'cat-' + lead.customerCategory.toLowerCase()">
+            {{ lead.categoryLabel }}
+          </span>
+          <span class="tag source-tag">{{ lead.sourceLabel }}</span>
+        </div>
+        <div class="lead-card-meta">
+          <span class="meta"><mat-icon>person</mat-icon> {{ lead.contactName }}</span>
+        </div>
+        <div class="lead-card-bottom">
+          <span class="stage-badge" [class]="'stage-' + lead.followUpStage">
+            {{ getStageLabel(lead.followUpStage) }}
+          </span>
+          <span class="next-date" [class.overdue]="isOverdue(lead.nextFollowUpDate)">
+            <mat-icon>event</mat-icon>
+            {{ lead.nextFollowUpDate | date:'MM/dd' }}
+          </span>
+        </div>
+        <div class="lead-card-verify" *ngIf="!lead.personaVerified">
+          <mat-icon>pending</mat-icon> 待验证
+        </div>
+      </ng-template>
+    </div>
+  `,
+    styles: [`
+    .page-header {
+      display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 20px;
+    }
+    .page-header h1 { display: flex; align-items: center; gap: 8px; font-size: 24px; font-weight: 600; margin: 0; }
+    .page-header h1 mat-icon { color: #1976d2; }
+    .subtitle { font-size: 14px; color: #666; margin: 4px 0 0; }
+
+    .header-stats { display: flex; gap: 20px; }
+    .stat-item { text-align: center; padding: 8px 16px; background: #fff; border-radius: 10px; box-shadow: 0 1px 4px rgba(0,0,0,0.06); }
+    .stat-item.highlight { background: #ffebee; }
+    .stat-value { display: block; font-size: 22px; font-weight: 700; color: #1a1a2e; }
+    .stat-label { font-size: 11px; color: #888; }
+
+    .view-bar { padding: 12px 16px; margin-bottom: 20px; display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
+    .view-toggle { display: flex; align-items: center; gap: 8px; }
+    .toggle-label { font-size: 13px; color: #888; font-weight: 500; }
+
+    .kanban-board { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; min-height: calc(100vh - 360px); }
+    .persona-board { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
+    .stage-board { grid-template-columns: repeat(6, 1fr); }
+
+    .kanban-column { background: #f8f9fb; border-radius: 12px; display: flex; flex-direction: column; min-height: 300px; }
+    .column-header {
+      display: flex; justify-content: space-between; align-items: center;
+      padding: 14px 16px; border-radius: 12px 12px 0 0; border-bottom: 2px solid transparent;
+    }
+    .col-header-s { background: #fff5f5; border-bottom-color: #c62828; }
+    .col-header-a { background: #fff8f0; border-bottom-color: #e65100; }
+    .col-header-b { background: #fffef5; border-bottom-color: #f9a825; }
+    .col-header-c { background: #fafafa; border-bottom-color: #bdbdbd; }
+    .persona-col-header { background: #fafbfc; }
+
+    .col-title { display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: 15px; }
+    .col-subtitle { font-size: 11px; color: #888; font-weight: 400; }
+    .grade-dot { width: 10px; height: 10px; border-radius: 50%; }
+    .dot-s { background: #c62828; }
+    .dot-a { background: #e65100; }
+    .dot-b { background: #f9a825; }
+    .dot-c { background: #bdbdbd; }
+    .stage-dot { width: 10px; height: 10px; border-radius: 50%; }
+    .persona-dot {
+      width: 24px; height: 24px; border-radius: 6px;
+      display: flex; align-items: center; justify-content: center;
+    }
+    .persona-dot mat-icon { font-size: 14px; width: 14px; height: 14px; color: #fff; }
+    .col-count { background: rgba(0,0,0,0.08); padding: 2px 10px; border-radius: 10px; font-size: 12px; font-weight: 600; }
+
+    .column-body { flex: 1; padding: 12px; overflow-y: auto; display: flex; flex-direction: column; gap: 10px; }
+
+    .lead-card {
+      background: #fff; border-radius: 10px; padding: 14px;
+      box-shadow: 0 1px 4px rgba(0,0,0,0.06); cursor: pointer;
+      transition: all 0.2s; border-left: 3px solid #ccc;
+    }
+    .lead-card:hover { box-shadow: 0 4px 12px rgba(0,0,0,0.12); transform: translateY(-1px); }
+
+    .lead-card-top { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; }
+    .company-name { font-size: 14px; font-weight: 600; color: #1a1a2e; }
+    .country-flag { font-size: 16px; }
+
+    .lead-card-tags { display: flex; gap: 4px; margin-bottom: 8px; flex-wrap: wrap; }
+    .tag { font-size: 10px; padding: 1px 7px; border-radius: 8px; font-weight: 600; }
+    .persona-tag { font-weight: 700; }
+    .cat-a { background: #e3f2fd; color: #1565c0; }
+    .cat-b { background: #e8f5e9; color: #2e7d32; }
+    .cat-c { background: #f3e5f5; color: #6a1b9a; }
+    .cat-d { background: #fff3e0; color: #e65100; }
+    .source-tag { background: #f5f5f5; color: #777; }
+
+    .lead-card-meta { display: flex; justify-content: space-between; margin-bottom: 8px; }
+    .meta { display: flex; align-items: center; gap: 3px; font-size: 12px; color: #666; }
+    .meta mat-icon { font-size: 14px; width: 14px; height: 14px; color: #999; }
+
+    .lead-card-bottom { display: flex; justify-content: space-between; align-items: center; }
+    .stage-badge { font-size: 10px; padding: 2px 8px; border-radius: 10px; font-weight: 500; }
+    .stage-screened { background: #e3f2fd; color: #1565c0; }
+    .stage-contacted { background: #e8f5e9; color: #2e7d32; }
+    .stage-replied { background: #fff3e0; color: #e65100; }
+    .stage-sample { background: #f3e5f5; color: #6a1b9a; }
+    .stage-quote { background: #e1f5fe; color: #0277bd; }
+    .stage-order { background: #e8f5e9; color: #1b5e20; }
+
+    .next-date { display: flex; align-items: center; gap: 3px; font-size: 11px; color: #888; }
+    .next-date mat-icon { font-size: 13px; width: 13px; height: 13px; }
+    .next-date.overdue { color: #c62828; font-weight: 600; }
+
+    .lead-card-verify {
+      display: flex; align-items: center; gap: 4px;
+      margin-top: 6px; font-size: 11px; color: #e65100;
+      background: #fff3e0; padding: 2px 8px; border-radius: 6px;
+      width: fit-content;
+    }
+    .lead-card-verify mat-icon { font-size: 13px; width: 13px; height: 13px; }
+
+    .empty-column {
+      display: flex; flex-direction: column; align-items: center; justify-content: center;
+      padding: 40px 10px; color: #ccc; font-size: 13px;
+    }
+    .empty-column mat-icon { font-size: 32px; width: 32px; height: 32px; margin-bottom: 8px; }
+
+    @media (max-width: 1100px) { .kanban-board { grid-template-columns: repeat(2, 1fr); } .stage-board { grid-template-columns: repeat(3, 1fr); } }
+    @media (max-width: 600px) { .kanban-board { grid-template-columns: 1fr; } .header-stats { display: none; } }
+  `]
+})
+export class KanbanComponent implements OnInit {
+  leads: Lead[] = [];
+  filteredLeads: Lead[] = [];
+  selectedCategory = 'all';
+  viewMode: 'grade' | 'persona' | 'stage' = 'grade';
+  grades: ValueGrade[] = ['S', 'A', 'B', 'C'];
+  gradeLabels = GRADE_LABELS;
+  activePersonas = PERSONA_LIST.filter(p => p.id !== 'P6');
+
+  stageColumns = [
+    { key: 'screened', label: '已筛选', color: '#1976d2' },
+    { key: 'contacted', label: '已触达', color: '#43a047' },
+    { key: 'replied', label: '已回复', color: '#ef6c00' },
+    { key: 'sample', label: '寄样中', color: '#8e24aa' },
+    { key: 'quote', label: '报价中', color: '#0277bd' },
+    { key: 'order', label: '已下单', color: '#1b5e20' },
+  ];
+
+  constructor(
+    private mockData: MockDataService,
+    private router: Router,
+  ) {}
+
+  ngOnInit() {
+    this.leads = [...this.mockData.leads];
+    this.filteredLeads = this.leads;
+  }
+
+  onViewChange() { /* view mode changed via binding */ }
+
+  filterLeads() {
+    if (this.selectedCategory === 'all') {
+      this.filteredLeads = this.leads;
+    } else {
+      this.filteredLeads = this.leads.filter(l => l.customerCategory === this.selectedCategory);
+    }
+  }
+
+  getFilteredByGrade(grade: ValueGrade): Lead[] {
+    return this.filteredLeads.filter(l => l.valueGrade === grade);
+  }
+
+  getFilteredByPersona(persona: CustomerPersona): Lead[] {
+    return this.filteredLeads.filter(l => l.persona === persona);
+  }
+
+  getFilteredByStage(stage: string): Lead[] {
+    return this.filteredLeads.filter(l => l.followUpStage === stage);
+  }
+
+  countByCategory(cat: CustomerCategory): number {
+    return this.leads.filter(l => l.customerCategory === cat).length;
+  }
+
+  getSGradeCount(): number { return this.leads.filter(l => l.valueGrade === 'S').length; }
+
+  getTotalValue(): number { return this.leads.reduce((sum, l) => sum + l.estimatedOrderValue, 0); }
+
+  getStageLabel(stage: string): string {
+    const labels: Record<string, string> = { screened: '已筛选', contacted: '已触达', replied: '已回复', sample: '寄样中', quote: '报价中', order: '已下单' };
+    return labels[stage] || stage;
+  }
+
+  getFlag(country: string): string {
+    const flags: Record<string, string> = { US: '🇺🇸', GB: '🇬🇧', DE: '🇩🇪', PL: '🇵🇱', CA: '🇨🇦', AU: '🇦🇺', SE: '🇸🇪', CN: '🇨🇳', Unknown: '🌍' };
+    return flags[country] || '🌍';
+  }
+
+  getPersonaColor(p: CustomerPersona): string { return PERSONA_DEFINITIONS[p]?.color || '#999'; }
+  getPersonaBg(p: CustomerPersona): string { return PERSONA_DEFINITIONS[p]?.bgColor || '#fafafa'; }
+
+  isOverdue(date: Date): boolean { return new Date(date) < new Date(); }
+
+  openLead(lead: Lead) { this.router.navigate(['/leads', lead.id]); }
+}

+ 678 - 0
lead-discovery/src/app/pages/lead-detail/lead-detail.component.ts

@@ -0,0 +1,678 @@
+import { Component, OnInit } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+import { ActivatedRoute, Router } from '@angular/router';
+import { Location } from '@angular/common';
+import { MatCardModule } from '@angular/material/card';
+import { MatIconModule } from '@angular/material/icon';
+import { MatButtonModule } from '@angular/material/button';
+import { MatChipsModule } from '@angular/material/chips';
+import { MatDividerModule } from '@angular/material/divider';
+import { MatTabsModule } from '@angular/material/tabs';
+import { MatProgressBarModule } from '@angular/material/progress-bar';
+import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatInputModule } from '@angular/material/input';
+import { MatSelectModule } from '@angular/material/select';
+import { MockDataService } from '../../services/mock-data.service';
+import {
+  Lead, Email, CATEGORY_ICONS, GRADE_LABELS, Product,
+  CustomerPersona, PERSONA_DEFINITIONS, PERSONA_LIST
+} from '../../models/lead.model';
+
+@Component({
+    selector: 'app-lead-detail',
+    imports: [
+        CommonModule, FormsModule,
+        MatCardModule, MatIconModule, MatButtonModule, MatChipsModule,
+        MatDividerModule, MatTabsModule, MatProgressBarModule, MatSnackBarModule,
+        MatFormFieldModule, MatInputModule, MatSelectModule,
+    ],
+    template: `
+    <div class="page-container" *ngIf="lead">
+      <!-- Back -->
+      <a class="back-link" (click)="goBack()">
+        <mat-icon>arrow_back</mat-icon> 返回上一页
+      </a>
+
+      <!-- Header Card -->
+      <div class="header-card card">
+        <div class="header-top">
+          <div class="header-left">
+            <div class="company-avatar" [style.background]="getPersonaColor(lead.persona)">
+              <mat-icon>{{ getPersonaIcon(lead.persona) }}</mat-icon>
+            </div>
+            <div>
+              <h1>{{ lead.companyName }}</h1>
+              <div class="header-tags">
+                <span class="persona-badge" [style.background]="getPersonaBg(lead.persona)" [style.color]="getPersonaColor(lead.persona)">
+                  <mat-icon class="badge-sm-icon">{{ getPersonaIcon(lead.persona) }}</mat-icon>
+                  {{ lead.persona }}-{{ lead.personaLabel }}
+                </span>
+                <span class="badge" [class]="'grade-' + lead.valueGrade.toLowerCase()">
+                  {{ lead.valueGrade }}级
+                </span>
+                <span class="badge stage-badge" [class]="'stage-' + lead.followUpStage">
+                  {{ getStageLabel(lead.followUpStage) }}
+                </span>
+                <span class="verify-badge" [class.verified]="lead.personaVerified">
+                  <mat-icon>{{ lead.personaVerified ? 'verified' : 'pending' }}</mat-icon>
+                  {{ lead.personaVerified ? '已验证' : '待验证' }}
+                </span>
+              </div>
+            </div>
+          </div>
+          <div class="header-right">
+            <div class="value-display">
+            </div>
+            <button mat-raised-button color="primary" (click)="startDeepAnalysis()">
+              <mat-icon>search</mat-icon> 启动深度分析
+            </button>
+          </div>
+        </div>
+      </div>
+
+      <!-- Content Grid -->
+      <div class="content-grid">
+        <!-- Left Column -->
+        <div class="left-col">
+          <!-- Persona Card (NEW) -->
+          <div class="section-card card persona-insight-card"
+               [style.border-left-color]="getPersonaColor(lead.persona)">
+            <div class="section-header">
+              <mat-icon [style.color]="getPersonaColor(lead.persona)">psychology</mat-icon>
+              <h3>客户画像分析</h3>
+              <span class="confidence-badge">置信度 {{ lead.personaConfidence }}%</span>
+            </div>
+
+            <div class="persona-insight-body">
+              <div class="insight-row">
+                <span class="insight-label">画像类型</span>
+                <span class="persona-badge lg" [style.background]="getPersonaBg(lead.persona)" [style.color]="getPersonaColor(lead.persona)">
+                  <mat-icon class="badge-sm-icon">{{ getPersonaIcon(lead.persona) }}</mat-icon>
+                  {{ lead.persona }}-{{ lead.personaLabel }}
+                </span>
+              </div>
+
+              <div class="insight-row">
+                <span class="insight-label">AI 判断依据</span>
+                <div class="insight-keywords">
+                  <span class="kw-chip" *ngFor="let kw of lead.quickScreenResult.matchedKeywords">{{ kw }}</span>
+                </div>
+              </div>
+
+              <div class="insight-row">
+                <span class="insight-label">信息获取策略</span>
+                <span class="insight-value">
+                  <mat-icon>{{ getPersonaStrategyIcon(lead.persona) }}</mat-icon>
+                  {{ getPersonaStrategyLabel(lead.persona) }}
+                </span>
+              </div>
+
+              <div class="insight-row">
+                <span class="insight-label">推荐首要动作</span>
+                <span class="insight-value highlight">{{ getPersonaFirstAction(lead.persona) }}</span>
+              </div>
+
+              <div class="insight-row">
+                <span class="insight-label">销售策略</span>
+                <span class="insight-value">{{ getPersonaSalesStrategy(lead.persona) }}</span>
+              </div>
+            </div>
+          </div>
+
+          <!-- Quick Screen Result -->
+          <div class="section-card card">
+            <div class="section-header">
+              <mat-icon>bolt</mat-icon>
+              <h3>快速筛选结果</h3>
+              <span class="time-badge">{{ lead.quickScreenResult.processingTime / 1000 | number:'1.1-1' }}s</span>
+            </div>
+            <div class="info-grid">
+              <div class="info-item">
+                <span class="info-label">域名</span>
+                <span class="info-value">{{ lead.quickScreenResult.domain || '-' }}</span>
+              </div>
+              <div class="info-item">
+                <span class="info-label">国家</span>
+                <span class="info-value">{{ getFlag(lead.country) }} {{ lead.country }}</span>
+              </div>
+              <div class="info-item">
+                <span class="info-label">主营业务</span>
+                <span class="info-value">{{ lead.quickScreenResult.mainBusiness }}</span>
+              </div>
+              <div class="info-item">
+                <span class="info-label">预估规模</span>
+                <span class="info-value">{{ lead.quickScreenResult.estimatedScale }}</span>
+              </div>
+              <div class="info-item">
+                <span class="info-label">产品相关性</span>
+                <span class="info-value rel-tag" [class]="'rel-' + lead.quickScreenResult.productRelevance">
+                  {{ lead.quickScreenResult.productRelevance === 'high' ? '高' : lead.quickScreenResult.productRelevance === 'medium' ? '中' : '低' }}
+                </span>
+              </div>
+              <div class="info-item">
+                <span class="info-label">置信度</span>
+                <span class="info-value">{{ lead.quickScreenResult.confidence }}%</span>
+              </div>
+            </div>
+            <div class="certs-row" *ngIf="lead.quickScreenResult.certRequirements.length">
+              <span class="info-label">需要认证</span>
+              <div class="cert-chips">
+                <span class="cert-chip" *ngFor="let c of lead.quickScreenResult.certRequirements">{{ c }}</span>
+              </div>
+            </div>
+          </div>
+
+          <!-- Contact Info -->
+          <div class="section-card card">
+            <div class="section-header">
+              <mat-icon>person</mat-icon>
+              <h3>联系人信息</h3>
+            </div>
+            <div class="info-grid">
+              <div class="info-item"><span class="info-label">姓名</span><span class="info-value">{{ lead.contactName || '-' }}</span></div>
+              <div class="info-item"><span class="info-label">邮箱</span><span class="info-value email-link">{{ lead.contactEmail }}</span></div>
+              <div class="info-item"><span class="info-label">来源</span><span class="info-value">{{ lead.sourceLabel }}</span></div>
+              <div class="info-item"><span class="info-label">创建时间</span><span class="info-value">{{ lead.createdAt | date:'yyyy-MM-dd HH:mm' }}</span></div>
+            </div>
+          </div>
+
+          <!-- Original Email -->
+          <div class="section-card card email-card" *ngIf="getEmailForLead(lead) as email">
+            <div class="section-header">
+              <mat-icon>email</mat-icon>
+              <h3>原始邮件信息</h3>
+              <span class="time-badge">{{ email.receivedAt | date:'yyyy-MM-dd HH:mm' }}</span>
+            </div>
+
+            <div class="email-subject-row">
+              <mat-icon class="email-meta-icon">subject</mat-icon>
+              <span class="email-subject">{{ email.subject }}</span>
+            </div>
+
+            <div class="email-meta-grid">
+              <div class="email-meta-item">
+                <span class="email-meta-label">发件人</span>
+                <span class="email-meta-value">
+                  <strong>{{ email.fromName }}</strong>
+                  &lt;{{ email.from }}&gt;
+                </span>
+              </div>
+              <div class="email-meta-item">
+                <span class="email-meta-label">收件人</span>
+                <span class="email-meta-value">{{ email.to }}</span>
+              </div>
+              <div class="email-meta-item" *ngIf="email.cc">
+                <span class="email-meta-label">抄送</span>
+                <span class="email-meta-value">{{ email.cc }}</span>
+              </div>
+            </div>
+
+            <mat-divider style="margin: 12px 0;"></mat-divider>
+
+            <div class="email-body-section">
+              <div class="email-body" [class.collapsed]="!emailBodyExpanded">
+                <pre class="email-body-text">{{ email.body }}</pre>
+              </div>
+              <button mat-button class="expand-btn" (click)="emailBodyExpanded = !emailBodyExpanded">
+                <mat-icon>{{ emailBodyExpanded ? 'expand_less' : 'expand_more' }}</mat-icon>
+                {{ emailBodyExpanded ? '收起' : '展开全文' }}
+              </button>
+            </div>
+
+            <div class="email-attachments" *ngIf="email.attachments.length">
+              <mat-divider style="margin: 8px 0 12px;"></mat-divider>
+              <div class="attachments-header">
+                <mat-icon>attach_file</mat-icon>
+                <span>附件 ({{ email.attachments.length }})</span>
+              </div>
+              <div class="attachment-list">
+                <div class="attachment-chip" *ngFor="let att of email.attachments">
+                  <mat-icon class="att-icon">{{ att.icon }}</mat-icon>
+                  <span class="att-name">{{ att.fileName }}</span>
+                  <span class="att-size">{{ formatFileSize(att.fileSize) }}</span>
+                </div>
+              </div>
+            </div>
+          </div>
+
+          <!-- No Email Found -->
+          <div class="section-card card no-email-card" *ngIf="!getEmailForLead(lead)">
+            <div class="section-header">
+              <mat-icon>email</mat-icon>
+              <h3>原始邮件信息</h3>
+            </div>
+            <div class="no-email-placeholder">
+              <mat-icon class="placeholder-sm">mail_outline</mat-icon>
+              <span>该线索无关联邮件(来源:{{ lead.sourceLabel }})</span>
+            </div>
+          </div>
+        </div>
+
+        <!-- Right Column -->
+        <div class="right-col">
+          <!-- Sales Verification (NEW) -->
+          <div class="section-card card verify-section">
+            <div class="section-header">
+              <mat-icon>fact_check</mat-icon>
+              <h3>销售验证</h3>
+              <span class="verify-status-badge" [class.verified]="lead.personaVerified">
+                {{ lead.personaVerified ? '✅ 已验证' : '⏳ 待验证' }}
+              </span>
+            </div>
+
+            <div class="verify-form" *ngIf="!lead.personaVerified">
+              <p class="verify-prompt">请确认 AI 的判断结果:</p>
+
+              <div class="verify-row">
+                <span class="verify-label">画像分类</span>
+                <span class="verify-current">{{ lead.persona }}-{{ lead.personaLabel }}</span>
+                <button mat-stroked-button class="verify-btn correct" (click)="confirmPersona()">
+                  <mat-icon>check</mat-icon> 正确
+                </button>
+                <mat-form-field appearance="outline" class="verify-select">
+                  <mat-label>修改为</mat-label>
+                  <mat-select [(ngModel)]="correctedPersona">
+                    <mat-option *ngFor="let p of personaOptions" [value]="p.id">{{ p.id }}-{{ p.name }}</mat-option>
+                  </mat-select>
+                </mat-form-field>
+              </div>
+
+              <div class="verify-row">
+                <span class="verify-label">价值等级</span>
+                <span class="verify-current badge" [class]="'grade-' + lead.valueGrade.toLowerCase()">{{ lead.valueGrade }}级</span>
+                <button mat-stroked-button class="verify-btn correct" (click)="confirmGrade()">
+                  <mat-icon>check</mat-icon> 正确
+                </button>
+              </div>
+
+              <mat-form-field appearance="outline" class="verify-notes-field">
+                <mat-label>备注(可选)</mat-label>
+                <textarea matInput [(ngModel)]="verifyNotes" rows="2"
+                          placeholder="记录您的判断依据或补充信息..."></textarea>
+              </mat-form-field>
+
+              <button mat-raised-button color="primary" (click)="submitVerification()">
+                <mat-icon>save</mat-icon> 保存验证结果
+              </button>
+            </div>
+
+            <div class="verify-done" *ngIf="lead.personaVerified">
+              <mat-icon class="done-icon">verified</mat-icon>
+              <p>画像已验证为 <strong>{{ lead.persona }}-{{ lead.personaLabel }}</strong></p>
+              <p *ngIf="lead.salesFeedback?.notes" class="done-notes">
+                备注:{{ lead.salesFeedback!.notes }}
+              </p>
+            </div>
+          </div>
+
+          <!-- Product Recommendations -->
+          <div class="section-card card">
+            <div class="section-header">
+              <mat-icon>inventory_2</mat-icon>
+              <h3>推荐产品</h3>
+            </div>
+            <div class="product-list">
+              <div class="product-card" *ngFor="let p of lead.quickScreenResult.suggestedProducts; let i = index">
+                <div class="product-rank" [class]="'rank-' + (i < 3 ? i + 1 : 'other')">{{ i + 1 }}</div>
+                <div class="product-info">
+                  <div class="product-name">{{ p.name }}</div>
+                  <div class="product-en">{{ p.nameEn }}</div>
+                  <div class="product-sku-row">
+                    <span class="sku-tag">{{ p.sku }}</span>
+                    <span class="product-reason">{{ p.reason }}</span>
+                  </div>
+                </div>
+                <div class="product-pricing">
+                  <span class="wholesale-price">\${{ p.wholesalePrice }}</span>
+                  <span class="price-label">批发价</span>
+                </div>
+              </div>
+            </div>
+          </div>
+
+          <!-- AI Research Report -->
+          <div class="section-card card" *ngIf="lead.aiResearchReport">
+            <div class="section-header">
+              <mat-icon>analytics</mat-icon>
+              <h3>AI 调研报告</h3>
+              <span class="badge grade-a">已完成</span>
+            </div>
+            <div class="deep-report-preview">
+              <div class="report-item">
+                <mat-icon>business</mat-icon>
+                <div>
+                  <strong>官网分析</strong>
+                  <p>{{ lead.aiResearchReport.websiteAnalysis }}</p>
+                </div>
+              </div>
+              <div class="report-item" *ngIf="lead.aiResearchReport.productMatching.length">
+                <mat-icon>shopping_cart</mat-icon>
+                <div>
+                  <strong>产品匹配</strong>
+                  <div class="match-list">
+                    <div class="match-item" *ngFor="let m of lead.aiResearchReport.productMatching">
+                      <span>{{ m.ourProduct }} ({{ m.ourSku }}) → {{ m.matchesNeed }}</span>
+                      <span class="match-margin">{{ m.profitMargin }}</span>
+                    </div>
+                  </div>
+                </div>
+              </div>
+              <div class="report-item">
+                <mat-icon>groups</mat-icon>
+                <div>
+                  <strong>竞品分析</strong>
+                  <p>{{ lead.aiResearchReport.competitorAnalysis }}</p>
+                </div>
+              </div>
+            </div>
+          </div>
+
+          <!-- Deep Analysis Placeholder -->
+          <div class="section-card card deep-analysis-placeholder" *ngIf="!lead.aiResearchReport">
+            <div class="placeholder-content">
+              <mat-icon class="placeholder-icon">search</mat-icon>
+              <h3>AI 调研报告</h3>
+              <p>启动深度分析后,AI 将根据画像类型执行差异化调研:</p>
+              <ul>
+                <li>🌐 {{ getPersonaStrategyLabel(lead.persona) }}</li>
+                <li>📦 产品匹配与利润分析</li>
+                <li>🏭 竞品与供应链分析</li>
+                <li>📋 销售策略与话术生成</li>
+              </ul>
+              <p class="estimate">预估耗时:3-5 分钟</p>
+              <button mat-raised-button color="primary" (click)="startDeepAnalysis()">
+                <mat-icon>play_arrow</mat-icon> 启动深度分析
+              </button>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <div class="page-container" *ngIf="!lead">
+      <div class="empty-state card">
+        <mat-icon>search_off</mat-icon>
+        <p>未找到该线索</p>
+        <a mat-button (click)="goBack()">返回上一页</a>
+      </div>
+    </div>
+  `,
+    styles: [`
+    .back-link {
+      display: inline-flex; align-items: center; gap: 4px;
+      color: #1976d2; text-decoration: none; font-size: 14px; margin-bottom: 16px; cursor: pointer;
+    }
+    .back-link:hover { text-decoration: underline; }
+
+    .header-card { padding: 24px; margin-bottom: 20px; }
+    .header-top { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 16px; }
+    .header-left { display: flex; gap: 16px; align-items: center; }
+    .company-avatar {
+      width: 56px; height: 56px; border-radius: 14px;
+      display: flex; align-items: center; justify-content: center;
+    }
+    .company-avatar mat-icon { font-size: 28px; width: 28px; height: 28px; color: #fff; }
+    .header-card h1 { margin: 0 0 8px; font-size: 22px; }
+    .header-tags { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
+
+    .persona-badge {
+      display: inline-flex; align-items: center; gap: 4px;
+      padding: 3px 10px; border-radius: 20px; font-size: 12px; font-weight: 600;
+    }
+    .persona-badge.lg { padding: 4px 14px; font-size: 13px; }
+    .badge-sm-icon { font-size: 14px; width: 14px; height: 14px; }
+    .badge { display: inline-block; padding: 3px 10px; border-radius: 20px; font-size: 12px; font-weight: 600; }
+    .grade-s { background: #ffebee; color: #c62828; }
+    .grade-a { background: #fff3e0; color: #e65100; }
+    .grade-b { background: #fffde7; color: #f9a825; }
+    .grade-c { background: #fafafa; color: #757575; }
+    .stage-badge { }
+    .stage-screened { background: #e3f2fd; color: #1565c0; }
+    .stage-contacted { background: #e8f5e9; color: #2e7d32; }
+    .stage-replied { background: #fff3e0; color: #e65100; }
+    .stage-sample { background: #f3e5f5; color: #6a1b9a; }
+    .stage-quote { background: #e1f5fe; color: #0277bd; }
+    .stage-order { background: #e8f5e9; color: #1b5e20; }
+
+    .verify-badge {
+      display: inline-flex; align-items: center; gap: 4px;
+      padding: 3px 10px; border-radius: 20px; font-size: 12px; font-weight: 600;
+      background: #fff3e0; color: #e65100;
+    }
+    .verify-badge mat-icon { font-size: 14px; width: 14px; height: 14px; }
+    .verify-badge.verified { background: #e8f5e9; color: #2e7d32; }
+
+    .header-right { text-align: right; }
+    .value-display { margin-bottom: 12px; }
+    .value-amount { font-size: 28px; font-weight: 700; color: #2e7d32; }
+    .value-label { display: block; font-size: 12px; color: #888; }
+
+    .content-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
+    .section-card { padding: 20px; margin-bottom: 0; }
+    .section-header { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; }
+    .section-header mat-icon { color: #1976d2; }
+    .section-header h3 { margin: 0; font-size: 16px; flex: 1; }
+    .time-badge { background: #e3f2fd; color: #1976d2; padding: 2px 8px; border-radius: 8px; font-size: 11px; font-weight: 600; }
+    .confidence-badge { background: #e8f5e9; color: #2e7d32; padding: 2px 8px; border-radius: 8px; font-size: 11px; font-weight: 600; }
+
+    /* Persona Insight Card */
+    .persona-insight-card { border-left: 4px solid #ccc; }
+    .persona-insight-body { display: flex; flex-direction: column; gap: 12px; }
+    .insight-row { display: flex; align-items: flex-start; gap: 10px; }
+    .insight-label { font-size: 12px; color: #888; min-width: 90px; flex-shrink: 0; padding-top: 4px; }
+    .insight-value { font-size: 14px; color: #333; display: flex; align-items: center; gap: 4px; }
+    .insight-value mat-icon { font-size: 16px; width: 16px; height: 16px; color: #999; }
+    .insight-value.highlight { color: #1565c0; font-weight: 600; }
+    .insight-keywords { display: flex; gap: 6px; flex-wrap: wrap; }
+    .kw-chip { font-size: 11px; padding: 2px 8px; background: #e8eaf6; color: #5c6bc0; border-radius: 6px; font-family: monospace; }
+
+    .info-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
+    .info-label { display: block; font-size: 11px; color: #888; margin-bottom: 2px; }
+    .info-value { font-size: 14px; color: #333; font-weight: 500; }
+    .email-link { color: #1976d2; }
+    .rel-tag { padding: 1px 6px; border-radius: 4px; font-size: 12px; }
+    .rel-high { background: #e8f5e9; color: #2e7d32; }
+    .rel-medium { background: #fff8e1; color: #f57f17; }
+    .rel-low { background: #fafafa; color: #999; }
+
+    .certs-row { margin-top: 12px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
+    .cert-chips { display: flex; gap: 6px; }
+    .cert-chip { background: #e3f2fd; color: #1565c0; padding: 2px 10px; border-radius: 12px; font-size: 12px; font-weight: 500; }
+
+    /* Email Card */
+    .email-card { border-left: 4px solid #1976d2; }
+    .email-subject-row {
+      display: flex; align-items: flex-start; gap: 8px; margin-bottom: 14px;
+      padding: 10px 14px; background: #f0f4ff; border-radius: 8px;
+    }
+    .email-meta-icon { font-size: 18px; width: 18px; height: 18px; color: #1976d2; flex-shrink: 0; margin-top: 2px; }
+    .email-subject { font-size: 15px; font-weight: 600; color: #1a237e; line-height: 1.4; }
+
+    .email-meta-grid { display: flex; flex-direction: column; gap: 8px; }
+    .email-meta-item { display: flex; align-items: flex-start; gap: 8px; }
+    .email-meta-label {
+      font-size: 12px; color: #888; min-width: 48px; flex-shrink: 0;
+      padding: 2px 8px; background: #f5f5f5; border-radius: 4px; text-align: center;
+    }
+    .email-meta-value { font-size: 13px; color: #444; word-break: break-all; line-height: 1.5; }
+    .email-meta-value strong { color: #333; }
+
+    .email-body-section { position: relative; }
+    .email-body { overflow: hidden; transition: max-height 0.3s ease; }
+    .email-body.collapsed { max-height: 120px; }
+    .email-body-text {
+      font-size: 13px; color: #555; line-height: 1.7; white-space: pre-wrap;
+      word-wrap: break-word; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+      margin: 0; padding: 0;
+    }
+    .expand-btn { display: flex; align-items: center; gap: 4px; margin: 4px auto 0; font-size: 13px; color: #1976d2; }
+
+    .attachments-header { display: flex; align-items: center; gap: 6px; font-size: 13px; color: #666; margin-bottom: 10px; }
+    .attachments-header mat-icon { font-size: 18px; width: 18px; height: 18px; color: #888; }
+    .attachment-list { display: flex; flex-direction: column; gap: 6px; }
+    .attachment-chip {
+      display: flex; align-items: center; gap: 8px; padding: 8px 12px;
+      background: #f8f9fa; border-radius: 8px; border: 1px solid #eee; transition: background 0.15s;
+    }
+    .attachment-chip:hover { background: #e3f2fd; border-color: #bbdefb; }
+    .att-icon { font-size: 20px; width: 20px; height: 20px; color: #e53935; flex-shrink: 0; }
+    .att-name { font-size: 13px; color: #333; font-weight: 500; flex: 1; word-break: break-all; }
+    .att-size { font-size: 11px; color: #999; flex-shrink: 0; }
+
+    .no-email-card { border-left: 4px solid #e0e0e0; }
+    .no-email-placeholder {
+      display: flex; align-items: center; gap: 10px; padding: 20px; color: #999; font-size: 14px;
+    }
+    .placeholder-sm { font-size: 32px; width: 32px; height: 32px; color: #ddd; }
+
+    /* Verify Section */
+    .verify-section { }
+    .verify-status-badge { font-size: 12px; padding: 2px 10px; border-radius: 10px; background: #fff3e0; color: #e65100; }
+    .verify-status-badge.verified { background: #e8f5e9; color: #2e7d32; }
+    .verify-prompt { font-size: 14px; color: #555; margin: 0 0 12px; }
+    .verify-row { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; flex-wrap: wrap; }
+    .verify-label { font-size: 13px; color: #888; min-width: 70px; }
+    .verify-current { font-size: 14px; font-weight: 600; color: #333; }
+    .verify-btn { font-size: 12px; }
+    .verify-btn.correct mat-icon { font-size: 16px; width: 16px; height: 16px; color: #2e7d32; }
+    .verify-select { max-width: 200px; }
+    .verify-notes-field { width: 100%; margin-top: 8px; }
+    .verify-done { text-align: center; padding: 20px; }
+    .done-icon { font-size: 48px; width: 48px; height: 48px; color: #2e7d32; }
+    .verify-done p { font-size: 14px; color: #555; margin: 8px 0 0; }
+    .done-notes { font-size: 13px; color: #888; font-style: italic; }
+
+    /* Products */
+    .product-list { display: flex; flex-direction: column; gap: 10px; }
+    .product-card { display: flex; gap: 12px; align-items: center; padding: 12px; background: #fafafa; border-radius: 10px; transition: background 0.15s; }
+    .product-card:hover { background: #f0f4ff; }
+    .product-rank { width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 700; flex-shrink: 0; }
+    .rank-1 { background: #fff3e0; color: #e65100; }
+    .rank-2 { background: #e3f2fd; color: #1565c0; }
+    .rank-3 { background: #e8f5e9; color: #2e7d32; }
+    .rank-other { background: #f5f5f5; color: #999; }
+    .product-info { flex: 1; }
+    .product-name { font-size: 14px; font-weight: 600; color: #333; }
+    .product-en { font-size: 11px; color: #999; }
+    .product-sku-row { display: flex; align-items: center; gap: 8px; margin-top: 4px; }
+    .sku-tag { font-size: 10px; padding: 1px 6px; background: #e8eaf6; color: #5c6bc0; border-radius: 4px; font-family: monospace; }
+    .product-reason { font-size: 11px; color: #888; }
+    .product-pricing { text-align: right; }
+    .wholesale-price { font-size: 18px; font-weight: 700; color: #2e7d32; display: block; }
+    .price-label { font-size: 10px; color: #999; }
+
+    /* Report */
+    .deep-report-preview { display: flex; flex-direction: column; gap: 14px; }
+    .report-item { display: flex; gap: 12px; padding: 12px; background: #f8f9fa; border-radius: 8px; }
+    .report-item mat-icon { color: #1976d2; flex-shrink: 0; margin-top: 2px; }
+    .report-item strong { font-size: 14px; }
+    .report-item p { font-size: 13px; color: #555; margin: 4px 0 0; }
+    .match-list { margin-top: 6px; }
+    .match-item { font-size: 13px; color: #555; padding: 4px 0; border-bottom: 1px solid #eee; display: flex; justify-content: space-between; }
+    .match-margin { font-size: 12px; color: #2e7d32; font-weight: 500; }
+
+    .deep-analysis-placeholder { border: 2px dashed #e0e0e0; background: #fafafa; }
+    .placeholder-content { text-align: center; padding: 20px; }
+    .placeholder-icon { font-size: 48px; width: 48px; height: 48px; color: #ccc; }
+    .placeholder-content h3 { margin: 8px 0; }
+    .placeholder-content p { font-size: 14px; color: #666; }
+    .placeholder-content ul { text-align: left; max-width: 300px; margin: 12px auto; font-size: 13px; color: #555; line-height: 1.8; }
+    .estimate { font-size: 12px; color: #999; margin-bottom: 16px !important; }
+
+    .empty-state { display: flex; flex-direction: column; align-items: center; padding: 60px 20px; color: #999; }
+    .empty-state mat-icon { font-size: 64px; width: 64px; height: 64px; color: #ddd; }
+
+    @media (max-width: 900px) { .content-grid { grid-template-columns: 1fr; } }
+  `]
+})
+export class LeadDetailComponent implements OnInit {
+  lead: Lead | null = null;
+  personaOptions = PERSONA_LIST;
+  correctedPersona: CustomerPersona | null = null;
+  verifyNotes = '';
+  emailBodyExpanded = false;
+
+  private emails: Email[] = [];
+
+  constructor(
+    private route: ActivatedRoute,
+    private router: Router,
+    private location: Location,
+    private mockData: MockDataService,
+    private snackBar: MatSnackBar,
+  ) {}
+
+  ngOnInit() {
+    const id = this.route.snapshot.paramMap.get('id');
+    this.lead = this.mockData.leads.find(l => l.id === id) || null;
+    this.emails = this.mockData.emails;
+  }
+
+  getPersonaColor(p: CustomerPersona): string { return PERSONA_DEFINITIONS[p]?.color || '#999'; }
+  getPersonaBg(p: CustomerPersona): string { return PERSONA_DEFINITIONS[p]?.bgColor || '#fafafa'; }
+  getPersonaIcon(p: CustomerPersona): string { return PERSONA_DEFINITIONS[p]?.icon || 'business'; }
+  getPersonaStrategyLabel(p: CustomerPersona): string { return PERSONA_DEFINITIONS[p]?.infoStrategyLabel || ''; }
+  getPersonaFirstAction(p: CustomerPersona): string { return PERSONA_DEFINITIONS[p]?.firstAction || ''; }
+  getPersonaSalesStrategy(p: CustomerPersona): string { return PERSONA_DEFINITIONS[p]?.salesStrategy || ''; }
+  getPersonaStrategyIcon(p: CustomerPersona): string {
+    const s = PERSONA_DEFINITIONS[p]?.infoStrategy;
+    return s === 'product_catalog' ? 'list_alt' : s === 'website' ? 'language' : 'block';
+  }
+
+  getCatIcon(cat: string): string { return CATEGORY_ICONS[cat as keyof typeof CATEGORY_ICONS] || 'business'; }
+
+  getStageLabel(stage: string): string {
+    const labels: Record<string, string> = { screened: '已筛选', contacted: '已触达', replied: '已回复', sample: '寄样中', quote: '报价中', order: '已下单' };
+    return labels[stage] || stage;
+  }
+
+  getFlag(country: string): string {
+    const flags: Record<string, string> = { US: '🇺🇸', GB: '🇬🇧', DE: '🇩🇪', PL: '🇵🇱', CA: '🇨🇦', AU: '🇦🇺', SE: '🇸🇪', CN: '🇨🇳' };
+    return flags[country] || '🌍';
+  }
+
+  getEmailForLead(lead: Lead): Email | undefined {
+    return this.emails.find(e => e.from === lead.contactEmail);
+  }
+
+  formatFileSize(bytes: number): string {
+    if (bytes < 1024) return bytes + ' B';
+    if (bytes < 1048576) return (bytes / 1024).toFixed(1) + ' KB';
+    return (bytes / 1048576).toFixed(1) + ' MB';
+  }
+
+  confirmPersona() {
+    this.snackBar.open('✅ 画像分类已确认', '', { duration: 1500 });
+  }
+
+  confirmGrade() {
+    this.snackBar.open('✅ 价值等级已确认', '', { duration: 1500 });
+  }
+
+  submitVerification() {
+    if (!this.lead) return;
+    this.lead.personaVerified = true;
+    if (this.correctedPersona) {
+      this.lead.persona = this.correctedPersona;
+      this.lead.personaLabel = PERSONA_DEFINITIONS[this.correctedPersona].name;
+    }
+    this.lead.salesFeedback = {
+      isPersonaCorrect: !this.correctedPersona,
+      correctedPersona: this.correctedPersona || undefined,
+      isGradeCorrect: true,
+      notes: this.verifyNotes,
+      feedbackAt: new Date(),
+    };
+    this.snackBar.open('💾 验证结果已保存', '', { duration: 2000 });
+  }
+
+  goBack() {
+    this.location.back();
+  }
+
+  startDeepAnalysis() {
+    this.snackBar.open('🔍 深度分析功能将在 Phase 3 上线(预估耗时 3-5 分钟)', '', { duration: 3000 });
+  }
+}

+ 477 - 0
lead-discovery/src/app/pages/lead-list/lead-list.component.ts

@@ -0,0 +1,477 @@
+import { Component, OnInit } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { Router } from '@angular/router';
+import { FormsModule } from '@angular/forms';
+import { MatTableModule } from '@angular/material/table';
+import { MatSortModule } from '@angular/material/sort';
+import { MatIconModule } from '@angular/material/icon';
+import { MatButtonModule } from '@angular/material/button';
+import { MatChipsModule } from '@angular/material/chips';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatInputModule } from '@angular/material/input';
+import { MatSelectModule } from '@angular/material/select';
+import { MatButtonToggleModule } from '@angular/material/button-toggle';
+import { MockDataService } from '../../services/mock-data.service';
+import {
+  Lead, CustomerCategory, ValueGrade, CustomerPersona,
+  PERSONA_DEFINITIONS, PERSONA_LIST
+} from '../../models/lead.model';
+
+@Component({
+    selector: 'app-lead-list',
+    imports: [
+        CommonModule, FormsModule,
+        MatTableModule, MatSortModule, MatIconModule, MatButtonModule,
+        MatChipsModule, MatFormFieldModule, MatInputModule, MatSelectModule,
+        MatButtonToggleModule,
+    ],
+    template: `
+    <div class="page-container">
+      <div class="page-header">
+        <h1><mat-icon>people</mat-icon> 线索管理</h1>
+        <p class="subtitle">所有线索的多维度视图,支持按画像分组管理</p>
+      </div>
+
+      <!-- View Toggle -->
+      <div class="view-toggle card">
+        <mat-button-toggle-group [(ngModel)]="viewMode" (change)="onViewChange()">
+          <mat-button-toggle value="list">
+            <mat-icon>list</mat-icon> 列表
+          </mat-button-toggle>
+          <mat-button-toggle value="persona">
+            <mat-icon>category</mat-icon> 按画像分组
+          </mat-button-toggle>
+          <mat-button-toggle value="stats">
+            <mat-icon>bar_chart</mat-icon> 统计
+          </mat-button-toggle>
+        </mat-button-toggle-group>
+
+        <!-- Filters (for list view) -->
+        <div class="inline-filters" *ngIf="viewMode === 'list'">
+          <mat-form-field appearance="outline" class="search-field">
+            <mat-label>搜索</mat-label>
+            <mat-icon matPrefix>search</mat-icon>
+            <input matInput [(ngModel)]="searchText" (ngModelChange)="applyFilters()">
+          </mat-form-field>
+          <mat-form-field appearance="outline">
+            <mat-label>画像</mat-label>
+            <mat-select [(ngModel)]="filterPersona" (selectionChange)="applyFilters()">
+              <mat-option value="">全部</mat-option>
+              <mat-option *ngFor="let p of personaList" [value]="p.id">{{ p.id }}-{{ p.name }}</mat-option>
+            </mat-select>
+          </mat-form-field>
+          <mat-form-field appearance="outline">
+            <mat-label>等级</mat-label>
+            <mat-select [(ngModel)]="filterGrade" (selectionChange)="applyFilters()">
+              <mat-option value="">全部</mat-option>
+              <mat-option value="S">S级</mat-option>
+              <mat-option value="A">A级</mat-option>
+              <mat-option value="B">B级</mat-option>
+              <mat-option value="C">C级</mat-option>
+            </mat-select>
+          </mat-form-field>
+        </div>
+      </div>
+
+      <!-- ===== LIST VIEW ===== -->
+      <div class="table-card card" *ngIf="viewMode === 'list'">
+        <table class="lead-table">
+          <thead>
+            <tr>
+              <th>公司名称</th>
+              <th>画像</th>
+              <th>等级</th>
+              <th>联系人</th>
+              <th>国家</th>
+              <th>跟进阶段</th>
+              <th>下次跟进</th>
+              <th>验证</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr *ngFor="let lead of filteredLeads" (click)="openLead(lead)" class="clickable-row">
+              <td class="company-cell">
+                <span class="company-name">{{ lead.companyName }}</span>
+              </td>
+              <td>
+                <span class="persona-badge" [style.background]="getPersonaBg(lead.persona)" [style.color]="getPersonaColor(lead.persona)">
+                  <mat-icon class="badge-icon">{{ getPersonaIcon(lead.persona) }}</mat-icon>
+                  {{ lead.persona }}
+                </span>
+              </td>
+              <td>
+                <span class="badge" [class]="'grade-' + lead.valueGrade.toLowerCase()">
+                  {{ lead.valueGrade }}级
+                </span>
+              </td>
+              <td>{{ lead.contactName }}</td>
+              <td>{{ getFlag(lead.country) }} {{ lead.country }}</td>
+              <td>
+                <span class="stage-badge" [class]="'stage-' + lead.followUpStage">
+                  {{ getStageLabel(lead.followUpStage) }}
+                </span>
+              </td>
+              <td [class.overdue]="isOverdue(lead.nextFollowUpDate)">
+                {{ lead.nextFollowUpDate | date:'MM/dd' }}
+              </td>
+              <td>
+                <mat-icon class="verify-icon" [class.verified]="lead.personaVerified">
+                  {{ lead.personaVerified ? 'verified' : 'pending' }}
+                </mat-icon>
+              </td>
+            </tr>
+          </tbody>
+        </table>
+        <div class="table-footer">
+          共 {{ filteredLeads.length }} 条线索
+        </div>
+      </div>
+
+      <!-- ===== PERSONA GROUP VIEW ===== -->
+      <div class="persona-groups" *ngIf="viewMode === 'persona'">
+        <div class="persona-group" *ngFor="let group of personaGroups"
+             [class.collapsed]="group.collapsed"
+             [class.low-quality]="group.persona === 'P6'">
+          <div class="group-header" (click)="group.collapsed = !group.collapsed"
+               [style.border-left-color]="getPersonaColor(group.persona)">
+            <mat-icon class="expand-icon">{{ group.collapsed ? 'chevron_right' : 'expand_more' }}</mat-icon>
+            <div class="group-avatar" [style.background]="getPersonaColor(group.persona)">
+              <mat-icon>{{ getPersonaIcon(group.persona) }}</mat-icon>
+            </div>
+            <div class="group-info">
+              <span class="group-name">{{ group.persona }}-{{ group.name }}</span>
+              <span class="group-strategy">{{ group.strategy }}</span>
+            </div>
+            <div class="group-stats">
+              <span class="group-count">{{ group.leads.length }} 条</span>
+            </div>
+          </div>
+
+          <div class="group-body" *ngIf="!group.collapsed">
+            <div class="group-lead" *ngFor="let lead of group.leads" (click)="openLead(lead)">
+              <span class="gl-company">{{ lead.companyName }}</span>
+              <span class="badge" [class]="'grade-' + lead.valueGrade.toLowerCase()">{{ lead.valueGrade }}级</span>
+              <span class="stage-badge" [class]="'stage-' + lead.followUpStage">{{ getStageLabel(lead.followUpStage) }}</span>
+              <span class="gl-date" [class.overdue]="isOverdue(lead.nextFollowUpDate)">{{ lead.nextFollowUpDate | date:'MM/dd' }}</span>
+              <span class="gl-flag">{{ getFlag(lead.country) }}</span>
+              <mat-icon class="verify-icon sm" [class.verified]="lead.personaVerified">
+                {{ lead.personaVerified ? 'verified' : 'pending' }}
+              </mat-icon>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- ===== STATS VIEW ===== -->
+      <div class="stats-view" *ngIf="viewMode === 'stats'">
+        <div class="stats-grid">
+          <!-- By Persona -->
+          <div class="stats-card card">
+            <h3><mat-icon>category</mat-icon> 按画像分布</h3>
+            <div class="chart-bars">
+              <div class="chart-row" *ngFor="let s of personaStats">
+                <span class="chart-label">{{ s.id }}-{{ s.name }}</span>
+                <div class="chart-bar-wrap">
+                  <div class="chart-bar" [style.width.%]="s.percent" [style.background]="s.color"></div>
+                </div>
+                <span class="chart-num">{{ s.count }} ({{ s.percent }}%)</span>
+              </div>
+            </div>
+          </div>
+          <!-- By Grade -->
+          <div class="stats-card card">
+            <h3><mat-icon>grade</mat-icon> 按等级分布</h3>
+            <div class="chart-bars">
+              <div class="chart-row" *ngFor="let g of gradeStats">
+                <span class="chart-label">{{ g.grade }}级</span>
+                <div class="chart-bar-wrap">
+                  <div class="chart-bar" [style.width.%]="g.percent" [style.background]="g.color"></div>
+                </div>
+                <span class="chart-num">{{ g.count }} (\${{ g.value | number:'1.0-0' }})</span>
+              </div>
+            </div>
+          </div>
+          <!-- By Stage -->
+          <div class="stats-card card">
+            <h3><mat-icon>linear_scale</mat-icon> 按跟进阶段</h3>
+            <div class="chart-bars">
+              <div class="chart-row" *ngFor="let st of stageStats">
+                <span class="chart-label">{{ st.label }}</span>
+                <div class="chart-bar-wrap">
+                  <div class="chart-bar" [style.width.%]="st.percent" [style.background]="st.color"></div>
+                </div>
+                <span class="chart-num">{{ st.count }}</span>
+              </div>
+            </div>
+          </div>
+          <!-- Summary -->
+          <div class="stats-card card summary-card">
+            <h3><mat-icon>insights</mat-icon> 汇总</h3>
+            <div class="summary-items">
+              <div class="summary-row"><span>总线索数</span><strong>{{ leads.length }}</strong></div>
+              <div class="summary-row"><span>已验证</span><strong>{{ leads.filter(verifiedFilter).length }}</strong></div>
+              <div class="summary-row"><span>待验证</span><strong>{{ leads.filter(pendingFilter).length }}</strong></div>
+              <div class="summary-row"><span>S级线索</span><strong>{{ leads.filter(sGradeFilter).length }}</strong></div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  `,
+    styles: [`
+    .page-header h1 {
+      display: flex; align-items: center; gap: 8px;
+      font-size: 24px; font-weight: 600; margin: 0;
+    }
+    .page-header h1 mat-icon { color: #1976d2; }
+    .subtitle { font-size: 14px; color: #666; margin: 4px 0 0; }
+
+    .view-toggle {
+      display: flex; align-items: center; gap: 16px;
+      padding: 12px 16px; margin: 20px 0 16px; flex-wrap: wrap;
+    }
+    .inline-filters { display: flex; gap: 12px; flex: 1; align-items: flex-start; }
+    .search-field { flex: 1; }
+
+    /* Table */
+    .table-card { overflow-x: auto; }
+    .lead-table { width: 100%; border-collapse: collapse; }
+    .lead-table th {
+      text-align: left; padding: 12px 16px; font-size: 12px; font-weight: 600;
+      color: #888; text-transform: uppercase; letter-spacing: 0.5px;
+      border-bottom: 2px solid #eee; background: #fafafa;
+    }
+    .lead-table td {
+      padding: 12px 16px; font-size: 13px;
+      border-bottom: 1px solid #f5f5f5; color: #444;
+    }
+    .clickable-row { cursor: pointer; transition: background 0.15s; }
+    .clickable-row:hover { background: #f8f9fa; }
+    .company-cell .company-name { font-weight: 600; color: #1a1a2e; }
+    .amount-cell { font-weight: 600; color: #2e7d32; }
+
+    .persona-badge {
+      display: inline-flex; align-items: center; gap: 4px;
+      padding: 2px 8px; border-radius: 8px; font-size: 11px; font-weight: 600;
+    }
+    .badge-icon { font-size: 14px; width: 14px; height: 14px; }
+    .badge {
+      display: inline-block; padding: 2px 8px; border-radius: 10px;
+      font-size: 11px; font-weight: 600;
+    }
+    .grade-s { background: #ffebee; color: #c62828; }
+    .grade-a { background: #fff3e0; color: #e65100; }
+    .grade-b { background: #fffde7; color: #f9a825; }
+    .grade-c { background: #fafafa; color: #757575; }
+
+    .stage-badge {
+      font-size: 11px; padding: 2px 8px; border-radius: 10px; font-weight: 500;
+    }
+    .stage-screened { background: #e3f2fd; color: #1565c0; }
+    .stage-contacted { background: #e8f5e9; color: #2e7d32; }
+    .stage-replied { background: #fff3e0; color: #e65100; }
+    .stage-sample { background: #f3e5f5; color: #6a1b9a; }
+    .stage-quote { background: #e1f5fe; color: #0277bd; }
+    .stage-order { background: #e8f5e9; color: #1b5e20; }
+    .overdue { color: #c62828; font-weight: 600; }
+
+    .verify-icon { font-size: 18px; width: 18px; height: 18px; color: #ccc; }
+    .verify-icon.verified { color: #2e7d32; }
+    .verify-icon.sm { font-size: 16px; width: 16px; height: 16px; }
+
+    .table-footer {
+      padding: 12px 16px; font-size: 12px; color: #888; border-top: 1px solid #eee;
+    }
+
+    /* Persona Group View */
+    .persona-groups { display: flex; flex-direction: column; gap: 12px; }
+    .persona-group {
+      background: #fff; border-radius: 12px;
+      box-shadow: 0 1px 4px rgba(0,0,0,0.06);
+      overflow: hidden;
+    }
+    .persona-group.low-quality { opacity: 0.7; }
+    .group-header {
+      display: flex; align-items: center; gap: 12px;
+      padding: 14px 20px; cursor: pointer;
+      border-left: 4px solid #ccc;
+      transition: background 0.15s;
+    }
+    .group-header:hover { background: #f8f9fa; }
+    .expand-icon { color: #999; font-size: 20px; width: 20px; height: 20px; }
+    .group-avatar {
+      width: 36px; height: 36px; border-radius: 10px;
+      display: flex; align-items: center; justify-content: center;
+      flex-shrink: 0;
+    }
+    .group-avatar mat-icon { font-size: 18px; width: 18px; height: 18px; color: #fff; }
+    .group-info { flex: 1; }
+    .group-name { display: block; font-size: 14px; font-weight: 600; color: #1a1a2e; }
+    .group-strategy { font-size: 12px; color: #888; }
+    .group-stats { display: flex; gap: 16px; align-items: center; }
+    .group-count {
+      font-size: 12px; padding: 2px 10px; background: #f0f0f0;
+      border-radius: 10px; font-weight: 600; color: #555;
+    }
+    .group-value { font-size: 14px; font-weight: 700; color: #2e7d32; }
+
+    .group-body { padding: 0 20px 12px 20px; }
+    .group-lead {
+      display: flex; align-items: center; gap: 12px;
+      padding: 10px 14px; border-bottom: 1px solid #f5f5f5;
+      cursor: pointer; transition: background 0.15s;
+    }
+    .group-lead:hover { background: #f8f9fa; }
+    .group-lead:last-child { border-bottom: none; }
+    .gl-company { flex: 1; font-size: 13px; font-weight: 600; color: #333; }
+    .gl-value { font-size: 13px; font-weight: 600; color: #2e7d32; min-width: 70px; text-align: right; }
+    .gl-date { font-size: 12px; color: #888; min-width: 40px; }
+    .gl-flag { font-size: 14px; }
+
+    /* Stats View */
+    .stats-grid {
+      display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px;
+    }
+    .stats-card { padding: 20px; }
+    .stats-card h3 {
+      display: flex; align-items: center; gap: 8px;
+      font-size: 16px; margin: 0 0 16px;
+    }
+    .stats-card h3 mat-icon { color: #1976d2; }
+    .chart-bars { display: flex; flex-direction: column; gap: 10px; }
+    .chart-row { display: flex; align-items: center; gap: 10px; }
+    .chart-label { font-size: 13px; min-width: 90px; color: #555; }
+    .chart-bar-wrap {
+      flex: 1; height: 10px; background: #f0f0f0; border-radius: 5px; overflow: hidden;
+    }
+    .chart-bar { height: 100%; border-radius: 5px; transition: width 0.5s; }
+    .chart-num { font-size: 12px; color: #888; min-width: 80px; text-align: right; }
+
+    .summary-items { display: flex; flex-direction: column; gap: 12px; }
+    .summary-row {
+      display: flex; justify-content: space-between; align-items: center;
+      padding: 8px 0; border-bottom: 1px solid #f5f5f5;
+      font-size: 14px; color: #555;
+    }
+    .summary-row strong { color: #1a1a2e; font-size: 16px; }
+
+    @media (max-width: 900px) {
+      .stats-grid { grid-template-columns: 1fr; }
+    }
+  `]
+})
+export class LeadListComponent implements OnInit {
+  leads: Lead[] = [];
+  filteredLeads: Lead[] = [];
+  searchText = '';
+  filterCategory = '';
+  filterPersona = '';
+  filterGrade = '';
+  viewMode: 'list' | 'persona' | 'stats' = 'list';
+  personaList = PERSONA_LIST;
+  totalValue = 0;
+
+  personaGroups: { persona: CustomerPersona; name: string; strategy: string; leads: Lead[]; totalValue: number; collapsed: boolean }[] = [];
+  personaStats: { id: string; name: string; color: string; count: number; percent: number }[] = [];
+  gradeStats: { grade: string; color: string; count: number; value: number; percent: number }[] = [];
+  stageStats: { key: string; label: string; color: string; count: number; percent: number }[] = [];
+
+  constructor(private mockData: MockDataService, private router: Router) {}
+
+  ngOnInit() {
+    this.leads = [...this.mockData.leads];
+    this.filteredLeads = this.leads;
+    this.totalValue = this.leads.reduce((s, l) => s + l.estimatedOrderValue, 0);
+    this.buildPersonaGroups();
+    this.buildStats();
+  }
+
+  applyFilters() {
+    this.filteredLeads = this.leads.filter(l => {
+      const matchSearch = !this.searchText ||
+        l.companyName.toLowerCase().includes(this.searchText.toLowerCase()) ||
+        l.contactName.toLowerCase().includes(this.searchText.toLowerCase());
+      const matchPersona = !this.filterPersona || l.persona === this.filterPersona;
+      const matchGrade = !this.filterGrade || l.valueGrade === this.filterGrade;
+      return matchSearch && matchPersona && matchGrade;
+    });
+  }
+
+  onViewChange() {
+    if (this.viewMode === 'persona') this.buildPersonaGroups();
+    if (this.viewMode === 'stats') this.buildStats();
+  }
+
+  private buildPersonaGroups() {
+    this.personaGroups = PERSONA_LIST.map(p => {
+      const pLeads = this.leads.filter(l => l.persona === p.id).sort((a, b) => b.estimatedOrderValue - a.estimatedOrderValue);
+      return {
+        persona: p.id,
+        name: p.name,
+        strategy: p.infoStrategyLabel,
+        leads: pLeads,
+        totalValue: pLeads.reduce((s, l) => s + l.estimatedOrderValue, 0),
+        collapsed: p.id === 'P6',
+      };
+    }).filter(g => g.leads.length > 0);
+  }
+
+  private buildStats() {
+    const total = this.leads.length || 1;
+    this.personaStats = PERSONA_LIST.map(p => {
+      const count = this.leads.filter(l => l.persona === p.id).length;
+      return { id: p.id, name: p.name, color: p.color, count, percent: Math.round((count / total) * 100) };
+    }).sort((a, b) => b.count - a.count);
+
+    const gradeColors: Record<string, string> = { S: '#c62828', A: '#e65100', B: '#f9a825', C: '#9e9e9e' };
+    this.gradeStats = (['S', 'A', 'B', 'C'] as ValueGrade[]).map(g => {
+      const gLeads = this.leads.filter(l => l.valueGrade === g);
+      return {
+        grade: g, color: gradeColors[g],
+        count: gLeads.length, value: gLeads.reduce((s, l) => s + l.estimatedOrderValue, 0),
+        percent: Math.round((gLeads.length / total) * 100),
+      };
+    });
+
+    const stageConfig = [
+      { key: 'screened', label: '已筛选', color: '#1976d2' },
+      { key: 'contacted', label: '已触达', color: '#43a047' },
+      { key: 'replied', label: '已回复', color: '#ef6c00' },
+      { key: 'sample', label: '寄样中', color: '#8e24aa' },
+      { key: 'quote', label: '报价中', color: '#0277bd' },
+      { key: 'order', label: '已下单', color: '#1b5e20' },
+    ];
+    this.stageStats = stageConfig.map(s => {
+      const count = this.leads.filter(l => l.followUpStage === s.key).length;
+      return { ...s, count, percent: Math.round((count / total) * 100) };
+    });
+  }
+
+  openLead(lead: Lead) { this.router.navigate(['/leads', lead.id]); }
+
+  getStageLabel(stage: string): string {
+    const labels: Record<string, string> = {
+      screened: '已筛选', contacted: '已触达', replied: '已回复',
+      sample: '寄样中', quote: '报价中', order: '已下单',
+    };
+    return labels[stage] || stage;
+  }
+
+  getFlag(country: string): string {
+    const flags: Record<string, string> = {
+      US: '🇺🇸', GB: '🇬🇧', DE: '🇩🇪', PL: '🇵🇱', CA: '🇨🇦',
+      AU: '🇦🇺', SE: '🇸🇪', CN: '🇨🇳',
+    };
+    return flags[country] || '🌍';
+  }
+
+  getPersonaColor(p: CustomerPersona): string { return PERSONA_DEFINITIONS[p]?.color || '#999'; }
+  getPersonaBg(p: CustomerPersona): string { return PERSONA_DEFINITIONS[p]?.bgColor || '#fafafa'; }
+  getPersonaIcon(p: CustomerPersona): string { return PERSONA_DEFINITIONS[p]?.icon || 'business'; }
+
+  isOverdue(date: Date): boolean { return new Date(date) < new Date(); }
+
+  verifiedFilter = (l: Lead) => l.personaVerified;
+  pendingFilter = (l: Lead) => !l.personaVerified;
+  sGradeFilter = (l: Lead) => l.valueGrade === 'S';
+}

+ 289 - 0
lead-discovery/src/app/pages/list/list.component.html

@@ -0,0 +1,289 @@
+<div class="page-container">
+  <!-- Header -->
+  <div class="page-header">
+    <div>
+      <h1><mat-icon>hub</mat-icon> 线索中心</h1>
+      <p class="subtitle">多维度视图,快速定位高优先级线索</p>
+    </div>
+    <div class="header-stats">
+      <div class="stat-item">
+        <span class="stat-value">{{ leads.length }}</span>
+        <span class="stat-label">总线索</span>
+      </div>
+      <div class="stat-item highlight">
+        <span class="stat-value">{{ sGradeCount }}</span>
+        <span class="stat-label">S级</span>
+      </div>
+    </div>
+  </div>
+
+  <!-- Toolbar -->
+  <div class="toolbar card">
+    <!-- Filters Row: toggle + filters on left, search on right -->
+    <div class="filters-row">
+      <!-- View Mode Toggle -->
+      <div class="view-toggle">
+        <mat-button-toggle-group [(ngModel)]="viewMode" (change)="onViewChange()">
+          <mat-button-toggle value="kanban-grade">
+            <mat-icon>grade</mat-icon> 按等级
+          </mat-button-toggle>
+          <mat-button-toggle value="kanban-persona">
+            <mat-icon>category</mat-icon> 按画像
+          </mat-button-toggle>
+          <mat-button-toggle value="kanban-stage">
+            <mat-icon>linear_scale</mat-icon> 按阶段
+          </mat-button-toggle>
+          <mat-button-toggle value="list">
+            <mat-icon>list</mat-icon> 列表
+          </mat-button-toggle>
+          <mat-button-toggle value="stats">
+            <mat-icon>bar_chart</mat-icon> 统计
+          </mat-button-toggle>
+        </mat-button-toggle-group>
+      </div>
+
+      <!-- Persona Filter -->
+      <mat-form-field appearance="outline" *ngIf="viewMode === 'list'">
+        <mat-label>画像</mat-label>
+        <mat-select [(ngModel)]="filterPersona" (selectionChange)="applyFilters()">
+          <mat-option value="">全部</mat-option>
+          <mat-option *ngFor="let p of personaList" [value]="p.id">{{ p.id }}-{{ p.name }}</mat-option>
+        </mat-select>
+      </mat-form-field>
+
+      <!-- Grade Filter -->
+      <mat-form-field appearance="outline" *ngIf="viewMode === 'list'">
+        <mat-label>等级</mat-label>
+        <mat-select [(ngModel)]="filterGrade" (selectionChange)="applyFilters()">
+          <mat-option value="">全部</mat-option>
+          <mat-option value="S">S级</mat-option>
+          <mat-option value="A">A级</mat-option>
+          <mat-option value="B">B级</mat-option>
+          <mat-option value="C">C级</mat-option>
+        </mat-select>
+      </mat-form-field>
+
+      <!-- Search (right side) -->
+      <mat-form-field appearance="outline" class="search-field" *ngIf="viewMode !== 'stats'">
+        <mat-label>搜索</mat-label>
+        <mat-icon matPrefix>search</mat-icon>
+        <input matInput [(ngModel)]="searchText" (ngModelChange)="applyFilters()" placeholder="公司名称 / 联系人">
+      </mat-form-field>
+    </div>
+  </div>
+
+  <!-- ===== KANBAN: GRADE VIEW ===== -->
+  <div class="kanban-board" *ngIf="viewMode === 'kanban-grade'">
+    <div class="kanban-column" *ngFor="let grade of grades">
+      <div class="column-header" [class]="'col-header-' + grade.toLowerCase()">
+        <div class="col-title">
+          <span class="grade-dot" [class]="'dot-' + grade.toLowerCase()"></span>
+          {{ grade }}级
+          <span class="col-subtitle">{{ gradeLabels[grade] }}</span>
+        </div>
+        <span class="col-count">{{ getFilteredByGrade(grade).length }}</span>
+      </div>
+      <div class="column-body">
+        <div class="lead-card" *ngFor="let lead of getFilteredByGrade(grade)"
+             [style.border-left-color]="getPersonaColor(lead.persona)"
+             (click)="openLead(lead)">
+          <ng-container *ngTemplateOutlet="leadCardTpl; context: { $implicit: lead }"></ng-container>
+        </div>
+        <div class="empty-column" *ngIf="getFilteredByGrade(grade).length === 0">
+          <mat-icon>inbox</mat-icon><span>暂无{{ grade }}级线索</span>
+        </div>
+      </div>
+    </div>
+  </div>
+
+  <!-- ===== KANBAN: PERSONA VIEW ===== -->
+  <div class="kanban-board persona-board" *ngIf="viewMode === 'kanban-persona'">
+    <div class="kanban-column" *ngFor="let p of personaList">
+      <div class="column-header persona-col-header" [style.border-bottom-color]="p.color">
+        <div class="col-title">
+          <div class="persona-dot" [style.background]="p.color">
+            <mat-icon>{{ p.icon }}</mat-icon>
+          </div>
+          {{ p.id }}
+          <span class="col-subtitle">{{ p.name }}</span>
+        </div>
+        <span class="col-count">{{ getFilteredByPersona(p.id).length }}</span>
+      </div>
+      <div class="column-body">
+        <div class="lead-card" *ngFor="let lead of getFilteredByPersona(p.id)"
+             [style.border-left-color]="p.color"
+             (click)="openLead(lead)">
+          <ng-container *ngTemplateOutlet="leadCardTpl; context: { $implicit: lead }"></ng-container>
+        </div>
+        <div class="empty-column" *ngIf="getFilteredByPersona(p.id).length === 0">
+          <mat-icon>inbox</mat-icon><span>暂无线索</span>
+        </div>
+      </div>
+    </div>
+  </div>
+
+  <!-- ===== KANBAN: STAGE VIEW ===== -->
+  <div class="kanban-board stage-board" *ngIf="viewMode === 'kanban-stage'">
+    <div class="kanban-column" *ngFor="let stage of stageColumns">
+      <div class="column-header" [style.border-bottom-color]="stage.color">
+        <div class="col-title">
+          <span class="stage-dot" [style.background]="stage.color"></span>
+          {{ stage.label }}
+        </div>
+        <span class="col-count">{{ getFilteredByStage(stage.key).length }}</span>
+      </div>
+      <div class="column-body">
+        <div class="lead-card" *ngFor="let lead of getFilteredByStage(stage.key)"
+             [style.border-left-color]="getPersonaColor(lead.persona)"
+             (click)="openLead(lead)">
+          <ng-container *ngTemplateOutlet="leadCardTpl; context: { $implicit: lead }"></ng-container>
+        </div>
+        <div class="empty-column" *ngIf="getFilteredByStage(stage.key).length === 0">
+          <mat-icon>inbox</mat-icon><span>暂无线索</span>
+        </div>
+      </div>
+    </div>
+  </div>
+
+  <!-- Shared Lead Card Template (for kanban views) -->
+  <ng-template #leadCardTpl let-lead>
+    <div class="lead-card-top">
+      <span class="kcard-company">{{ lead.companyName }}</span>
+      <span class="country-flag">{{ getFlag(lead.country) }}</span>
+    </div>
+    <div class="lead-card-tags">
+      <span class="tag persona-tag" [style.background]="getPersonaBg(lead.persona)" [style.color]="getPersonaColor(lead.persona)">
+        {{ lead.persona }}
+      </span>
+      <span class="tag" [class]="'cat-' + lead.customerCategory.toLowerCase()">
+        {{ lead.categoryLabel }}
+      </span>
+      <span class="tag source-tag">{{ lead.sourceLabel }}</span>
+    </div>
+    <div class="lead-card-meta">
+      <span class="meta"><mat-icon>person</mat-icon> {{ lead.contactName }}</span>
+    </div>
+    <div class="lead-card-bottom">
+      <span class="stage-badge" [class]="'stage-' + lead.followUpStage">
+        {{ getStageLabel(lead.followUpStage) }}
+      </span>
+      <span class="next-date" [class.overdue]="isOverdue(lead.nextFollowUpDate)">
+        <mat-icon>event</mat-icon>
+        {{ lead.nextFollowUpDate | date:'MM/dd' }}
+      </span>
+    </div>
+    <div class="lead-card-verify" *ngIf="!lead.personaVerified">
+      <mat-icon>pending</mat-icon> 待验证
+    </div>
+  </ng-template>
+
+  <!-- ===== LIST VIEW (table) ===== -->
+  <div class="table-card card" *ngIf="viewMode === 'list'">
+    <table class="lead-table">
+      <thead>
+        <tr>
+          <th>公司名称</th>
+          <th>画像</th>
+          <th>等级</th>
+          <th>联系人</th>
+          <th>国家</th>
+          <th>跟进阶段</th>
+          <th>下次跟进</th>
+          <th>验证</th>
+        </tr>
+      </thead>
+      <tbody>
+        <tr *ngFor="let lead of filteredLeads" (click)="openLead(lead)" class="clickable-row">
+          <td class="company-cell">
+            <span class="company-name">{{ lead.companyName }}</span>
+          </td>
+          <td>
+            <span class="persona-badge" [style.background]="getPersonaBg(lead.persona)" [style.color]="getPersonaColor(lead.persona)">
+              <mat-icon class="badge-icon">{{ getPersonaIcon(lead.persona) }}</mat-icon>
+              {{ lead.persona }}
+            </span>
+          </td>
+          <td>
+            <span class="badge" [class]="'grade-' + lead.valueGrade.toLowerCase()">
+              {{ lead.valueGrade }}级
+            </span>
+          </td>
+          <td>{{ lead.contactName }}</td>
+          <td>{{ getFlag(lead.country) }} {{ lead.country }}</td>
+          <td>
+            <span class="stage-badge" [class]="'stage-' + lead.followUpStage">
+              {{ getStageLabel(lead.followUpStage) }}
+            </span>
+          </td>
+          <td [class.overdue]="isOverdue(lead.nextFollowUpDate)">
+            {{ lead.nextFollowUpDate | date:'MM/dd' }}
+          </td>
+          <td>
+            <mat-icon class="verify-icon" [class.verified]="lead.personaVerified">
+              {{ lead.personaVerified ? 'verified' : 'pending' }}
+            </mat-icon>
+          </td>
+        </tr>
+      </tbody>
+    </table>
+    <div class="table-footer">
+      共 {{ filteredLeads.length }} 条线索
+    </div>
+  </div>
+
+
+  <!-- ===== STATS VIEW ===== -->
+  <div class="stats-view" *ngIf="viewMode === 'stats'">
+    <div class="stats-grid">
+      <!-- By Persona -->
+      <div class="stats-card card">
+        <h3><mat-icon>category</mat-icon> 按画像分布</h3>
+        <div class="chart-bars">
+          <div class="chart-row" *ngFor="let s of personaStats">
+            <span class="chart-label">{{ s.id }}-{{ s.name }}</span>
+            <div class="chart-bar-wrap">
+              <div class="chart-bar" [style.width.%]="s.percent" [style.background]="s.color"></div>
+            </div>
+            <span class="chart-num">{{ s.count }} ({{ s.percent }}%)</span>
+          </div>
+        </div>
+      </div>
+      <!-- By Grade -->
+      <div class="stats-card card">
+        <h3><mat-icon>grade</mat-icon> 按等级分布</h3>
+        <div class="chart-bars">
+          <div class="chart-row" *ngFor="let g of gradeStats">
+            <span class="chart-label">{{ g.grade }}级</span>
+            <div class="chart-bar-wrap">
+              <div class="chart-bar" [style.width.%]="g.percent" [style.background]="g.color"></div>
+            </div>
+            <span class="chart-num">{{ g.count }} (${{ g.value | number:'1.0-0' }})</span>
+          </div>
+        </div>
+      </div>
+      <!-- By Stage -->
+      <div class="stats-card card">
+        <h3><mat-icon>linear_scale</mat-icon> 按跟进阶段</h3>
+        <div class="chart-bars">
+          <div class="chart-row" *ngFor="let st of stageStats">
+            <span class="chart-label">{{ st.label }}</span>
+            <div class="chart-bar-wrap">
+              <div class="chart-bar" [style.width.%]="st.percent" [style.background]="st.color"></div>
+            </div>
+            <span class="chart-num">{{ st.count }}</span>
+          </div>
+        </div>
+      </div>
+      <!-- Summary -->
+      <div class="stats-card card summary-card">
+        <h3><mat-icon>insights</mat-icon> 汇总</h3>
+        <div class="summary-items">
+          <div class="summary-row"><span>总线索数</span><strong>{{ leads.length }}</strong></div>
+          <div class="summary-row"><span>已验证</span><strong>{{ verifiedCount }}</strong></div>
+          <div class="summary-row"><span>待验证</span><strong>{{ pendingCount }}</strong></div>
+          <div class="summary-row"><span>S级线索</span><strong>{{ sGradeCount }}</strong></div>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>

+ 278 - 0
lead-discovery/src/app/pages/list/list.component.scss

@@ -0,0 +1,278 @@
+/* ===== Page Header ===== */
+.page-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-start;
+  margin-bottom: 20px;
+}
+.page-header h1 {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  font-size: 24px;
+  font-weight: 600;
+  margin: 0;
+}
+.page-header h1 mat-icon { color: #1976d2; }
+.subtitle { font-size: 14px; color: #666; margin: 4px 0 0; }
+
+.header-stats { display: flex; gap: 20px; }
+.stat-item {
+  text-align: center;
+  padding: 8px 16px;
+  background: #fff;
+  border-radius: 10px;
+  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
+}
+.stat-item.highlight { background: #ffebee; }
+.stat-value { display: block; font-size: 22px; font-weight: 700; color: #1a1a2e; }
+.stat-label { font-size: 11px; color: #888; }
+
+/* ===== Toolbar ===== */
+.toolbar {
+  padding: 14px 16px;
+  margin-bottom: 20px;
+}
+.view-toggle {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+}
+.filters-row {
+  display: flex;
+  gap: 12px;
+  align-items: center;
+  flex-wrap: wrap;
+}
+.filters-row .view-toggle { margin-right: 4px; }
+.search-field { margin-left: auto; flex: 0 1 320px; min-width: 180px; }
+
+/* ===== Kanban Board ===== */
+.kanban-board {
+  display: flex;
+  gap: 16px;
+  min-height: calc(100vh - 360px);
+  overflow-x: auto;
+  padding-bottom: 8px;
+
+  /* Custom scrollbar */
+  &::-webkit-scrollbar { height: 6px; }
+  &::-webkit-scrollbar-track { background: #f0f0f0; border-radius: 3px; }
+  &::-webkit-scrollbar-thumb { background: #c0c0c0; border-radius: 3px; }
+  &::-webkit-scrollbar-thumb:hover { background: #a0a0a0; }
+}
+.kanban-board > .kanban-column {
+  min-width: 260px;
+  flex: 1 0 0;
+}
+
+.kanban-column {
+  background: #f8f9fb;
+  border-radius: 12px;
+  display: flex;
+  flex-direction: column;
+  min-height: 300px;
+}
+.column-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 14px 16px;
+  border-radius: 12px 12px 0 0;
+  border-bottom: 2px solid transparent;
+}
+.col-header-s { background: #fff5f5; border-bottom-color: #c62828; }
+.col-header-a { background: #fff8f0; border-bottom-color: #e65100; }
+.col-header-b { background: #fffef5; border-bottom-color: #f9a825; }
+.col-header-c { background: #fafafa; border-bottom-color: #bdbdbd; }
+.persona-col-header { background: #fafbfc; }
+
+.col-title { display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: 15px; }
+.col-subtitle { font-size: 11px; color: #888; font-weight: 400; }
+.grade-dot { width: 10px; height: 10px; border-radius: 50%; }
+.dot-s { background: #c62828; }
+.dot-a { background: #e65100; }
+.dot-b { background: #f9a825; }
+.dot-c { background: #bdbdbd; }
+.stage-dot { width: 10px; height: 10px; border-radius: 50%; }
+.persona-dot {
+  width: 24px; height: 24px; border-radius: 6px;
+  display: flex; align-items: center; justify-content: center;
+}
+.persona-dot mat-icon { font-size: 14px; width: 14px; height: 14px; color: #fff; }
+.col-count {
+  background: rgba(0, 0, 0, 0.08);
+  padding: 2px 10px;
+  border-radius: 10px;
+  font-size: 12px;
+  font-weight: 600;
+}
+
+.column-body {
+  flex: 1;
+  padding: 12px;
+  overflow-y: auto;
+  display: flex;
+  flex-direction: column;
+  gap: 10px;
+}
+
+/* ===== Lead Card (kanban) ===== */
+.lead-card {
+  background: #fff;
+  border-radius: 10px;
+  padding: 14px;
+  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
+  cursor: pointer;
+  transition: all 0.2s;
+  border-left: 3px solid #ccc;
+}
+.lead-card:hover {
+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
+  transform: translateY(-1px);
+}
+
+.lead-card-top { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; }
+.kcard-company { font-size: 14px; font-weight: 600; color: #1a1a2e; }
+.country-flag { font-size: 16px; }
+
+.lead-card-tags { display: flex; gap: 4px; margin-bottom: 8px; flex-wrap: wrap; }
+.tag { font-size: 10px; padding: 1px 7px; border-radius: 8px; font-weight: 600; }
+.persona-tag { font-weight: 700; }
+.cat-a { background: #e3f2fd; color: #1565c0; }
+.cat-b { background: #e8f5e9; color: #2e7d32; }
+.cat-c { background: #f3e5f5; color: #6a1b9a; }
+.cat-d { background: #fff3e0; color: #e65100; }
+.source-tag { background: #f5f5f5; color: #777; }
+
+.lead-card-meta { display: flex; justify-content: space-between; margin-bottom: 8px; }
+.meta { display: flex; align-items: center; gap: 3px; font-size: 12px; color: #666; }
+.meta mat-icon { font-size: 14px; width: 14px; height: 14px; color: #999; }
+
+.lead-card-bottom { display: flex; justify-content: space-between; align-items: center; }
+
+.next-date { display: flex; align-items: center; gap: 3px; font-size: 11px; color: #888; }
+.next-date mat-icon { font-size: 13px; width: 13px; height: 13px; }
+.next-date.overdue { color: #c62828; font-weight: 600; }
+
+.lead-card-verify {
+  display: flex; align-items: center; gap: 4px;
+  margin-top: 6px; font-size: 11px; color: #e65100;
+  background: #fff3e0; padding: 2px 8px; border-radius: 6px;
+  width: fit-content;
+}
+.lead-card-verify mat-icon { font-size: 13px; width: 13px; height: 13px; }
+
+.empty-column {
+  display: flex; flex-direction: column; align-items: center; justify-content: center;
+  padding: 40px 10px; color: #ccc; font-size: 13px;
+}
+.empty-column mat-icon { font-size: 32px; width: 32px; height: 32px; margin-bottom: 8px; }
+
+/* ===== Shared Badges ===== */
+.badge {
+  display: inline-block;
+  padding: 2px 8px;
+  border-radius: 10px;
+  font-size: 11px;
+  font-weight: 600;
+}
+.grade-s { background: #ffebee; color: #c62828; }
+.grade-a { background: #fff3e0; color: #e65100; }
+.grade-b { background: #fffde7; color: #f9a825; }
+.grade-c { background: #fafafa; color: #757575; }
+
+.stage-badge { font-size: 11px; padding: 2px 8px; border-radius: 10px; font-weight: 500; }
+.stage-screened { background: #e3f2fd; color: #1565c0; }
+.stage-contacted { background: #e8f5e9; color: #2e7d32; }
+.stage-replied { background: #fff3e0; color: #e65100; }
+.stage-sample { background: #f3e5f5; color: #6a1b9a; }
+.stage-quote { background: #e1f5fe; color: #0277bd; }
+.stage-order { background: #e8f5e9; color: #1b5e20; }
+.overdue { color: #c62828; font-weight: 600; }
+
+.verify-icon { font-size: 18px; width: 18px; height: 18px; color: #ccc; }
+.verify-icon.verified { color: #2e7d32; }
+.verify-icon.sm { font-size: 16px; width: 16px; height: 16px; }
+
+/* ===== Table View ===== */
+.table-card { overflow-x: auto; }
+.lead-table { width: 100%; border-collapse: collapse; }
+.lead-table th {
+  text-align: left;
+  padding: 12px 16px;
+  font-size: 12px;
+  font-weight: 600;
+  color: #888;
+  text-transform: uppercase;
+  letter-spacing: 0.5px;
+  border-bottom: 2px solid #eee;
+  background: #fafafa;
+}
+.lead-table td {
+  padding: 12px 16px;
+  font-size: 13px;
+  border-bottom: 1px solid #f5f5f5;
+  color: #444;
+}
+.clickable-row { cursor: pointer; transition: background 0.15s; }
+.clickable-row:hover { background: #f8f9fa; }
+.company-cell .company-name { font-weight: 600; color: #1a1a2e; }
+.amount-cell { font-weight: 600; color: #2e7d32; }
+
+.persona-badge {
+  display: inline-flex; align-items: center; gap: 4px;
+  padding: 2px 8px; border-radius: 8px; font-size: 11px; font-weight: 600;
+}
+.badge-icon { font-size: 14px; width: 14px; height: 14px; }
+
+.table-footer {
+  padding: 12px 16px;
+  font-size: 12px;
+  color: #888;
+  border-top: 1px solid #eee;
+}
+
+/* ===== Stats View ===== */
+.stats-grid {
+  display: grid;
+  grid-template-columns: repeat(2, 1fr);
+  gap: 16px;
+}
+.stats-card { padding: 20px; }
+.stats-card h3 {
+  display: flex; align-items: center; gap: 8px;
+  font-size: 16px; margin: 0 0 16px;
+}
+.stats-card h3 mat-icon { color: #1976d2; }
+.chart-bars { display: flex; flex-direction: column; gap: 10px; }
+.chart-row { display: flex; align-items: center; gap: 10px; }
+.chart-label { font-size: 13px; min-width: 90px; color: #555; }
+.chart-bar-wrap {
+  flex: 1; height: 10px; background: #f0f0f0; border-radius: 5px; overflow: hidden;
+}
+.chart-bar { height: 100%; border-radius: 5px; transition: width 0.5s; }
+.chart-num { font-size: 12px; color: #888; min-width: 80px; text-align: right; }
+
+.summary-items { display: flex; flex-direction: column; gap: 12px; }
+.summary-row {
+  display: flex; justify-content: space-between; align-items: center;
+  padding: 8px 0; border-bottom: 1px solid #f5f5f5;
+  font-size: 14px; color: #555;
+}
+.summary-row strong { color: #1a1a2e; font-size: 16px; }
+
+/* ===== Responsive ===== */
+@media (max-width: 1100px) {
+  .kanban-board > .kanban-column { min-width: 240px; }
+}
+@media (max-width: 900px) {
+  .stats-grid { grid-template-columns: 1fr; }
+}
+@media (max-width: 600px) {
+  .kanban-board > .kanban-column { min-width: 220px; }
+  .header-stats { display: none; }
+  .filters-row { flex-wrap: wrap; }
+  .search-field { flex: 1 1 100%; }
+}
+

+ 198 - 0
lead-discovery/src/app/pages/list/list.component.ts

@@ -0,0 +1,198 @@
+import { Component, OnInit } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { Router } from '@angular/router';
+import { FormsModule } from '@angular/forms';
+import { MatIconModule } from '@angular/material/icon';
+import { MatButtonModule } from '@angular/material/button';
+import { MatButtonToggleModule } from '@angular/material/button-toggle';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatInputModule } from '@angular/material/input';
+import { MatSelectModule } from '@angular/material/select';
+import { MatTooltipModule } from '@angular/material/tooltip';
+import { MockDataService } from '../../services/mock-data.service';
+import {
+  Lead, CustomerCategory, ValueGrade, CustomerPersona,
+  GRADE_LABELS, PERSONA_DEFINITIONS, PERSONA_LIST
+} from '../../models/lead.model';
+
+type ViewMode = 'kanban-grade' | 'kanban-persona' | 'kanban-stage' | 'list' | 'stats';
+
+@Component({
+  selector: 'app-list',
+  imports: [
+    CommonModule, FormsModule,
+    MatIconModule, MatButtonModule, MatButtonToggleModule,
+    MatFormFieldModule, MatInputModule, MatSelectModule, MatTooltipModule,
+  ],
+  templateUrl: './list.component.html',
+  styleUrl: './list.component.scss',
+})
+export class ListComponent implements OnInit {
+
+  // ===== Data =====
+  leads: Lead[] = [];
+  filteredLeads: Lead[] = [];
+
+  // ===== View Mode =====
+  viewMode: ViewMode = 'kanban-grade';
+
+  // ===== Filters =====
+  searchText = '';
+  filterCategory = '';
+  filterPersona = '';
+  filterGrade = '';
+
+  // ===== Stats (pre-computed) =====
+  totalValue = 0;
+  sGradeCount = 0;
+  verifiedCount = 0;
+  pendingCount = 0;
+
+  // ===== Kanban Config =====
+  grades: ValueGrade[] = ['S', 'A', 'B', 'C'];
+  gradeLabels = GRADE_LABELS;
+  personaList = PERSONA_LIST;
+
+  stageColumns = [
+    { key: 'screened', label: '已筛选', color: '#1976d2' },
+    { key: 'contacted', label: '已触达', color: '#43a047' },
+    { key: 'replied', label: '已回复', color: '#ef6c00' },
+    { key: 'sample', label: '寄样中', color: '#8e24aa' },
+    { key: 'quote', label: '报价中', color: '#0277bd' },
+    { key: 'order', label: '已下单', color: '#1b5e20' },
+  ];
+
+  // ===== Stats View =====
+  personaStats: { id: string; name: string; color: string; count: number; percent: number }[] = [];
+  gradeStats: { grade: string; color: string; count: number; value: number; percent: number }[] = [];
+  stageStats: { key: string; label: string; color: string; count: number; percent: number }[] = [];
+
+  // ===== Computed =====
+  get isKanbanView(): boolean {
+    return this.viewMode.startsWith('kanban');
+  }
+
+  constructor(
+    private mockData: MockDataService,
+    private router: Router,
+  ) {}
+
+  ngOnInit() {
+    this.leads = [...this.mockData.leads];
+    this.filteredLeads = this.leads;
+    this.computeStats();
+    this.buildChartStats();
+  }
+
+  // ===== View Change =====
+
+  onViewChange() {
+    // Re-apply filters when switching views
+    this.applyFilters();
+    if (this.viewMode === 'stats') this.buildChartStats();
+  }
+
+  // ===== Filters =====
+
+  applyFilters() {
+    this.filteredLeads = this.leads.filter(l => {
+      const matchSearch = !this.searchText ||
+        l.companyName.toLowerCase().includes(this.searchText.toLowerCase()) ||
+        l.contactName.toLowerCase().includes(this.searchText.toLowerCase());
+      const matchCategory = !this.filterCategory || l.customerCategory === this.filterCategory;
+      const matchPersona = !this.filterPersona || l.persona === this.filterPersona;
+      const matchGrade = !this.filterGrade || l.valueGrade === this.filterGrade;
+      return matchSearch && matchCategory && matchPersona && matchGrade;
+    });
+  }
+
+  // ===== Kanban Helpers =====
+
+  getFilteredByGrade(grade: ValueGrade): Lead[] {
+    return this.filteredLeads.filter(l => l.valueGrade === grade);
+  }
+
+  getFilteredByPersona(persona: CustomerPersona): Lead[] {
+    return this.filteredLeads.filter(l => l.persona === persona);
+  }
+
+  getFilteredByStage(stage: string): Lead[] {
+    return this.filteredLeads.filter(l => l.followUpStage === stage);
+  }
+
+  countByCategory(cat: CustomerCategory): number {
+    return this.leads.filter(l => l.customerCategory === cat).length;
+  }
+
+  // ===== Stats Computation =====
+
+  private computeStats() {
+    this.totalValue = this.leads.reduce((s, l) => s + l.estimatedOrderValue, 0);
+    this.sGradeCount = this.leads.filter(l => l.valueGrade === 'S').length;
+    this.verifiedCount = this.leads.filter(l => l.personaVerified).length;
+    this.pendingCount = this.leads.filter(l => !l.personaVerified).length;
+  }
+
+  // ===== Chart Stats =====
+
+  private buildChartStats() {
+    const total = this.leads.length || 1;
+
+    this.personaStats = PERSONA_LIST.map(p => {
+      const count = this.leads.filter(l => l.persona === p.id).length;
+      return { id: p.id, name: p.name, color: p.color, count, percent: Math.round((count / total) * 100) };
+    }).sort((a, b) => b.count - a.count);
+
+    const gradeColors: Record<string, string> = { S: '#c62828', A: '#e65100', B: '#f9a825', C: '#9e9e9e' };
+    this.gradeStats = (['S', 'A', 'B', 'C'] as ValueGrade[]).map(g => {
+      const gLeads = this.leads.filter(l => l.valueGrade === g);
+      return {
+        grade: g, color: gradeColors[g],
+        count: gLeads.length,
+        value: gLeads.reduce((s, l) => s + l.estimatedOrderValue, 0),
+        percent: Math.round((gLeads.length / total) * 100),
+      };
+    });
+
+    const stageConfig = [
+      { key: 'screened', label: '已筛选', color: '#1976d2' },
+      { key: 'contacted', label: '已触达', color: '#43a047' },
+      { key: 'replied', label: '已回复', color: '#ef6c00' },
+      { key: 'sample', label: '寄样中', color: '#8e24aa' },
+      { key: 'quote', label: '报价中', color: '#0277bd' },
+      { key: 'order', label: '已下单', color: '#1b5e20' },
+    ];
+    this.stageStats = stageConfig.map(s => {
+      const count = this.leads.filter(l => l.followUpStage === s.key).length;
+      return { ...s, count, percent: Math.round((count / total) * 100) };
+    });
+  }
+
+  // ===== Shared Helpers =====
+
+  openLead(lead: Lead) {
+    this.router.navigate(['/leads', lead.id]);
+  }
+
+  getStageLabel(stage: string): string {
+    const labels: Record<string, string> = {
+      screened: '已筛选', contacted: '已触达', replied: '已回复',
+      sample: '寄样中', quote: '报价中', order: '已下单',
+    };
+    return labels[stage] || stage;
+  }
+
+  getFlag(country: string): string {
+    const flags: Record<string, string> = {
+      US: '🇺🇸', GB: '🇬🇧', DE: '🇩🇪', PL: '🇵🇱', CA: '🇨🇦',
+      AU: '🇦🇺', SE: '🇸🇪', CN: '🇨🇳',
+    };
+    return flags[country] || '🌍';
+  }
+
+  getPersonaColor(p: CustomerPersona): string { return PERSONA_DEFINITIONS[p]?.color || '#999'; }
+  getPersonaBg(p: CustomerPersona): string { return PERSONA_DEFINITIONS[p]?.bgColor || '#fafafa'; }
+  getPersonaIcon(p: CustomerPersona): string { return PERSONA_DEFINITIONS[p]?.icon || 'business'; }
+
+  isOverdue(date: Date): boolean { return new Date(date) < new Date(); }
+}

+ 394 - 0
lead-discovery/src/app/pages/personas/personas.component.ts

@@ -0,0 +1,394 @@
+import { Component, OnInit } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+import { MatCardModule } from '@angular/material/card';
+import { MatIconModule } from '@angular/material/icon';
+import { MatButtonModule } from '@angular/material/button';
+import { MatChipsModule } from '@angular/material/chips';
+import { MatExpansionModule } from '@angular/material/expansion';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatInputModule } from '@angular/material/input';
+import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
+import { MockDataService } from '../../services/mock-data.service';
+import {
+  CustomerPersona, PersonaDefinition, PERSONA_LIST, PERSONA_DEFINITIONS, Lead
+} from '../../models/lead.model';
+
+@Component({
+    selector: 'app-personas',
+    imports: [
+        CommonModule, FormsModule,
+        MatCardModule, MatIconModule, MatButtonModule, MatChipsModule,
+        MatExpansionModule, MatFormFieldModule, MatInputModule, MatSnackBarModule,
+    ],
+    template: `
+    <div class="page-container">
+      <div class="page-header">
+        <div>
+          <h1><mat-icon>psychology</mat-icon> 客户画像知识库</h1>
+          <p class="subtitle">定义客户画像、识别规则和销售策略 · AI 根据知识库自动分类线索</p>
+        </div>
+        <div class="header-stats">
+          <div class="stat-chip">
+            <mat-icon>people</mat-icon>
+            <span>{{ totalLeads }} 条线索</span>
+          </div>
+          <div class="stat-chip">
+            <mat-icon>category</mat-icon>
+            <span>{{ personas.length }} 个画像</span>
+          </div>
+        </div>
+      </div>
+
+      <!-- Summary Cards -->
+      <div class="summary-grid">
+        <div class="summary-card" *ngFor="let p of personas"
+             [style.border-left-color]="p.color"
+             (click)="scrollToPersona(p.id)">
+          <div class="summary-icon" [style.background]="p.color">
+            <mat-icon>{{ p.icon }}</mat-icon>
+          </div>
+          <div class="summary-info">
+            <span class="summary-name">{{ p.id }} · {{ p.name }}</span>
+            <span class="summary-count">{{ getLeadCount(p.id) }} 条线索</span>
+          </div>
+          <div class="summary-rate">{{ p.conversionRate }}%</div>
+        </div>
+      </div>
+
+      <!-- Persona Detail Cards -->
+      <div class="persona-cards">
+        <div class="persona-card card" *ngFor="let p of personas; let i = index"
+             [id]="'persona-' + p.id">
+          <!-- Card Header -->
+          <div class="persona-header" [style.border-left-color]="p.color">
+            <div class="persona-header-left">
+              <div class="persona-avatar" [style.background]="p.color">
+                <mat-icon>{{ p.icon }}</mat-icon>
+              </div>
+              <div>
+                <h2>{{ p.id }} · {{ p.name }}</h2>
+                <p class="persona-desc">{{ p.description }}</p>
+              </div>
+            </div>
+            <div class="persona-header-right">
+              <div class="persona-stat">
+                <span class="stat-num">{{ getLeadCount(p.id) }}</span>
+                <span class="stat-txt">线索</span>
+              </div>
+              <div class="persona-stat">
+                <span class="stat-num">{{ p.conversionRate }}%</span>
+                <span class="stat-txt">转化率</span>
+              </div>
+            </div>
+          </div>
+
+          <!-- Keywords -->
+          <div class="persona-section">
+            <div class="section-title">
+              <mat-icon>key</mat-icon>
+              <span>识别关键词</span>
+            </div>
+            <div class="keyword-grid">
+              <span class="keyword-chip" *ngFor="let kw of p.identifyKeywords"
+                    [style.border-color]="p.color" [style.color]="p.color">
+                {{ kw }}
+              </span>
+            </div>
+          </div>
+
+          <!-- AI Rules -->
+          <div class="persona-section">
+            <div class="section-title">
+              <mat-icon>smart_toy</mat-icon>
+              <span>AI 行动规则</span>
+            </div>
+            <div class="rules-grid">
+              <div class="rule-item">
+                <div class="rule-step" [style.background]="p.color">1</div>
+                <div class="rule-content">
+                  <span class="rule-label">信息获取</span>
+                  <span class="rule-value">
+                    <mat-icon *ngIf="p.infoStrategy === 'product_catalog'">list_alt</mat-icon>
+                    <mat-icon *ngIf="p.infoStrategy === 'website'">language</mat-icon>
+                    <mat-icon *ngIf="p.infoStrategy === 'none'">block</mat-icon>
+                    {{ p.infoStrategyLabel }}
+                  </span>
+                </div>
+              </div>
+              <div class="rule-item">
+                <div class="rule-step" [style.background]="p.color">2</div>
+                <div class="rule-content">
+                  <span class="rule-label">首要动作</span>
+                  <span class="rule-value">{{ p.firstAction }}</span>
+                </div>
+              </div>
+              <div class="rule-item">
+                <div class="rule-step" [style.background]="p.color">3</div>
+                <div class="rule-content">
+                  <span class="rule-label">深度挖掘</span>
+                  <span class="rule-value">{{ p.deepDiveDirection }}</span>
+                </div>
+              </div>
+              <div class="rule-item">
+                <div class="rule-step" [style.background]="p.color">4</div>
+                <div class="rule-content">
+                  <span class="rule-label">销售策略</span>
+                  <span class="rule-value highlight">{{ p.salesStrategy }}</span>
+                </div>
+              </div>
+            </div>
+          </div>
+
+          <!-- Sales Experience Notes -->
+          <div class="persona-section">
+            <div class="section-title">
+              <mat-icon>lightbulb</mat-icon>
+              <span>销售经验备注</span>
+              <button mat-icon-button class="add-note-btn" (click)="addNote(p)">
+                <mat-icon>add</mat-icon>
+              </button>
+            </div>
+            <div class="notes-list">
+              <div class="note-item" *ngFor="let note of p.salesExperienceNotes; let j = index">
+                <mat-icon class="note-icon" [style.color]="p.color">format_quote</mat-icon>
+                <span class="note-text">{{ note }}</span>
+              </div>
+              <div class="note-empty" *ngIf="p.salesExperienceNotes.length === 0">
+                暂无经验备注,点击 + 添加
+              </div>
+            </div>
+            <!-- Add Note Input -->
+            <div class="add-note-form" *ngIf="editingPersona === p.id">
+              <input class="note-input" [(ngModel)]="newNote"
+                     placeholder="输入销售经验备注..."
+                     (keyup.enter)="saveNote(p)">
+              <button mat-raised-button color="primary" (click)="saveNote(p)" [disabled]="!newNote.trim()">
+                <mat-icon>save</mat-icon> 保存
+              </button>
+              <button mat-button (click)="editingPersona = null; newNote = ''">取消</button>
+            </div>
+          </div>
+
+          <!-- Top Leads Preview -->
+          <div class="persona-section" *ngIf="getTopLeads(p.id).length > 0">
+            <div class="section-title">
+              <mat-icon>trending_up</mat-icon>
+              <span>代表线索</span>
+            </div>
+            <div class="top-leads-grid">
+              <div class="top-lead" *ngFor="let lead of getTopLeads(p.id)">
+                <span class="tl-company">{{ lead.companyName }}</span>
+                <span class="tl-grade" [class]="'grade-' + lead.valueGrade.toLowerCase()">{{ lead.valueGrade }}级</span>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  `,
+    styles: [`
+    .page-header {
+      display: flex; justify-content: space-between; align-items: flex-start;
+      margin-bottom: 24px;
+    }
+    .page-header h1 {
+      display: flex; align-items: center; gap: 8px;
+      font-size: 24px; font-weight: 600; margin: 0;
+    }
+    .page-header h1 mat-icon { color: #1976d2; }
+    .subtitle { font-size: 14px; color: #666; margin: 4px 0 0; }
+    .header-stats { display: flex; gap: 12px; }
+    .stat-chip {
+      display: flex; align-items: center; gap: 6px;
+      padding: 8px 14px; background: #fff; border-radius: 10px;
+      font-size: 13px; color: #555;
+      box-shadow: 0 1px 4px rgba(0,0,0,0.06);
+    }
+    .stat-chip mat-icon { font-size: 18px; width: 18px; height: 18px; color: #1976d2; }
+
+    /* Summary Grid */
+    .summary-grid {
+      display: grid;
+      grid-template-columns: repeat(6, 1fr);
+      gap: 12px;
+      margin-bottom: 24px;
+    }
+    .summary-card {
+      display: flex; align-items: center; gap: 10px;
+      padding: 12px 14px;
+      background: #fff; border-radius: 12px;
+      border-left: 4px solid #ccc;
+      box-shadow: 0 1px 4px rgba(0,0,0,0.06);
+      cursor: pointer;
+      transition: all 0.2s;
+    }
+    .summary-card:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
+    .summary-icon {
+      width: 36px; height: 36px; border-radius: 10px;
+      display: flex; align-items: center; justify-content: center;
+      flex-shrink: 0;
+    }
+    .summary-icon mat-icon { font-size: 18px; width: 18px; height: 18px; color: #fff; }
+    .summary-info { flex: 1; min-width: 0; }
+    .summary-name { display: block; font-size: 12px; font-weight: 600; color: #333; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
+    .summary-count { font-size: 11px; color: #999; }
+    .summary-rate { font-size: 14px; font-weight: 700; color: #2e7d32; }
+
+    /* Persona Cards */
+    .persona-cards { display: flex; flex-direction: column; gap: 20px; }
+    .persona-card { padding: 0; overflow: visible; }
+
+    .persona-header {
+      display: flex; justify-content: space-between; align-items: center;
+      padding: 20px 24px;
+      border-left: 5px solid #ccc;
+      border-radius: 12px 12px 0 0;
+      background: #fafbfc;
+    }
+    .persona-header-left { display: flex; gap: 14px; align-items: center; }
+    .persona-avatar {
+      width: 48px; height: 48px; border-radius: 14px;
+      display: flex; align-items: center; justify-content: center;
+    }
+    .persona-avatar mat-icon { font-size: 24px; width: 24px; height: 24px; color: #fff; }
+    .persona-header h2 { margin: 0; font-size: 18px; }
+    .persona-desc { margin: 4px 0 0; font-size: 13px; color: #666; }
+    .persona-header-right { display: flex; gap: 20px; }
+    .persona-stat { text-align: center; }
+    .stat-num { display: block; font-size: 20px; font-weight: 700; color: #1a1a2e; }
+    .stat-txt { font-size: 11px; color: #888; }
+
+    .persona-section { padding: 16px 24px; border-top: 1px solid #f0f0f0; }
+    .section-title {
+      display: flex; align-items: center; gap: 8px;
+      font-size: 14px; font-weight: 600; color: #555;
+      margin-bottom: 12px;
+    }
+    .section-title mat-icon { font-size: 18px; width: 18px; height: 18px; color: #1976d2; }
+    .add-note-btn { margin-left: auto; }
+    .add-note-btn mat-icon { font-size: 18px; }
+
+    /* Keywords */
+    .keyword-grid { display: flex; gap: 8px; flex-wrap: wrap; }
+    .keyword-chip {
+      font-size: 12px; padding: 4px 12px;
+      border: 1.5px solid #ccc; border-radius: 20px;
+      font-weight: 500; background: #fff;
+      transition: all 0.15s;
+    }
+    .keyword-chip:hover { background: #f0f4ff; }
+
+    /* Rules */
+    .rules-grid { display: flex; flex-direction: column; gap: 10px; }
+    .rule-item { display: flex; gap: 12px; align-items: flex-start; }
+    .rule-step {
+      width: 24px; height: 24px; border-radius: 50%;
+      display: flex; align-items: center; justify-content: center;
+      font-size: 12px; font-weight: 700; color: #fff;
+      flex-shrink: 0; margin-top: 2px;
+    }
+    .rule-content { flex: 1; }
+    .rule-label { font-size: 11px; color: #888; display: block; }
+    .rule-value {
+      font-size: 14px; color: #333; display: flex; align-items: center; gap: 4px;
+    }
+    .rule-value mat-icon { font-size: 16px; width: 16px; height: 16px; color: #999; }
+    .rule-value.highlight { color: #1565c0; font-weight: 500; }
+
+    /* Notes */
+    .notes-list { display: flex; flex-direction: column; gap: 8px; }
+    .note-item {
+      display: flex; gap: 8px; align-items: flex-start;
+      padding: 10px 14px;
+      background: #fffde7; border-radius: 8px;
+      font-size: 13px; color: #555;
+    }
+    .note-icon { font-size: 18px; width: 18px; height: 18px; flex-shrink: 0; margin-top: 1px; }
+    .note-text { flex: 1; line-height: 1.5; }
+    .note-empty { font-size: 13px; color: #ccc; padding: 8px 0; }
+
+    .add-note-form {
+      display: flex; gap: 10px; align-items: center; margin-top: 10px;
+    }
+    .note-input {
+      flex: 1; padding: 10px 14px; border: 1px solid #e0e0e0;
+      border-radius: 8px; font-size: 14px;
+      outline: none;
+    }
+    .note-input:focus { border-color: #1976d2; box-shadow: 0 0 0 3px rgba(25,118,210,0.1); }
+
+    /* Top Leads */
+    .top-leads-grid { display: flex; flex-direction: column; gap: 6px; }
+    .top-lead {
+      display: flex; align-items: center; gap: 10px;
+      padding: 8px 12px; background: #fafafa; border-radius: 8px;
+      font-size: 13px;
+    }
+    .tl-company { flex: 1; font-weight: 500; color: #333; }
+    .tl-grade {
+      font-size: 11px; padding: 2px 8px; border-radius: 8px; font-weight: 600;
+    }
+    .grade-s { background: #ffebee; color: #c62828; }
+    .grade-a { background: #fff3e0; color: #e65100; }
+    .grade-b { background: #fffde7; color: #f9a825; }
+    .grade-c { background: #fafafa; color: #757575; }
+    .tl-value { font-weight: 600; color: #2e7d32; }
+
+    @media (max-width: 1200px) {
+      .summary-grid { grid-template-columns: repeat(3, 1fr); }
+    }
+    @media (max-width: 768px) {
+      .summary-grid { grid-template-columns: repeat(2, 1fr); }
+    }
+  `]
+})
+export class PersonasComponent implements OnInit {
+  personas: PersonaDefinition[] = [];
+  leads: Lead[] = [];
+  totalLeads = 0;
+
+  editingPersona: CustomerPersona | null = null;
+  newNote = '';
+
+  constructor(
+    private mockData: MockDataService,
+    private snackBar: MatSnackBar,
+  ) {}
+
+  ngOnInit() {
+    this.personas = [...PERSONA_LIST];
+    this.leads = [...this.mockData.leads];
+    this.totalLeads = this.leads.length;
+  }
+
+  getLeadCount(personaId: CustomerPersona): number {
+    return this.leads.filter(l => l.persona === personaId).length;
+  }
+
+  getTopLeads(personaId: CustomerPersona): Lead[] {
+    return this.leads
+      .filter(l => l.persona === personaId)
+      .sort((a, b) => b.estimatedOrderValue - a.estimatedOrderValue)
+      .slice(0, 3);
+  }
+
+  scrollToPersona(id: CustomerPersona) {
+    const el = document.getElementById('persona-' + id);
+    if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
+  }
+
+  addNote(p: PersonaDefinition) {
+    this.editingPersona = p.id;
+    this.newNote = '';
+  }
+
+  saveNote(p: PersonaDefinition) {
+    if (!this.newNote.trim()) return;
+    p.salesExperienceNotes.push(this.newNote.trim());
+    this.snackBar.open(`💡 经验备注已保存到 ${p.name}`, '', { duration: 2000 });
+    this.newNote = '';
+    this.editingPersona = null;
+  }
+}
+

+ 190 - 0
lead-discovery/src/app/pages/product-catalog/product-catalog.component.ts

@@ -0,0 +1,190 @@
+import { Component, OnInit } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+import { MatCardModule } from '@angular/material/card';
+import { MatIconModule } from '@angular/material/icon';
+import { MatButtonModule } from '@angular/material/button';
+import { MatChipsModule } from '@angular/material/chips';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatInputModule } from '@angular/material/input';
+import { MatSelectModule } from '@angular/material/select';
+import { MockDataService } from '../../services/mock-data.service';
+import { Product, CATEGORY_LABELS, CustomerCategory } from '../../models/lead.model';
+
+@Component({
+    selector: 'app-product-catalog',
+    imports: [
+        CommonModule, FormsModule,
+        MatCardModule, MatIconModule, MatButtonModule, MatChipsModule,
+        MatFormFieldModule, MatInputModule, MatSelectModule,
+    ],
+    template: `
+    <div class="page-container">
+      <div class="page-header">
+        <h1><mat-icon>inventory_2</mat-icon> 产品目录</h1>
+        <p class="subtitle">犀牛急救产品线概览 · 来自价盘 4.1({{ products.length }} 个核心 SKU)</p>
+      </div>
+
+      <!-- Filter -->
+      <div class="filter-bar card">
+        <mat-form-field appearance="outline" class="search-field">
+          <mat-label>搜索产品</mat-label>
+          <mat-icon matPrefix>search</mat-icon>
+          <input matInput [(ngModel)]="searchText" (ngModelChange)="applyFilter()">
+        </mat-form-field>
+        <mat-form-field appearance="outline">
+          <mat-label>适配客户类型</mat-label>
+          <mat-select [(ngModel)]="filterCat" (selectionChange)="applyFilter()">
+            <mat-option value="">全部</mat-option>
+            <mat-option value="A">A-医疗渠道</mat-option>
+            <mat-option value="B">B-工业安全</mat-option>
+            <mat-option value="C">C-应急政府</mat-option>
+            <mat-option value="D">D-品牌OEM</mat-option>
+          </mat-select>
+        </mat-form-field>
+      </div>
+
+      <!-- Product Grid -->
+      <div class="product-grid">
+        <div class="product-card card" *ngFor="let p of filteredProducts">
+          <div class="product-header">
+            <div class="product-icon-wrap">
+              <mat-icon>medical_services</mat-icon>
+            </div>
+            <div class="product-price-wrap">
+              <span class="wholesale">\${{ p.wholesalePrice }}</span>
+              <span class="retail">零售 \${{ p.retailPrice }}</span>
+            </div>
+          </div>
+          <h3 class="product-name">{{ p.name }}</h3>
+          <p class="product-en">{{ p.nameEn }}</p>
+          <div class="product-meta">
+            <span class="sku-tag">{{ p.sku }}</span>
+            <span class="series-tag">{{ p.series }}</span>
+          </div>
+          <p class="product-desc">{{ p.description }}</p>
+          <div class="target-customers">
+            <span class="target-label">适配客户:</span>
+            <span class="target-chip" *ngFor="let cat of p.targetCustomers"
+                  [class]="'cat-' + cat.toLowerCase()">
+              {{ getCatLabel(cat) }}
+            </span>
+          </div>
+        </div>
+      </div>
+
+      <div class="results-count">
+        显示 {{ filteredProducts.length }} / {{ products.length }} 个产品
+      </div>
+    </div>
+  `,
+    styles: [`
+    .page-header h1 {
+      display: flex; align-items: center; gap: 8px;
+      font-size: 24px; font-weight: 600; margin: 0;
+    }
+    .page-header h1 mat-icon { color: #1976d2; }
+    .subtitle { font-size: 14px; color: #666; margin: 4px 0 0; }
+
+    .filter-bar {
+      display: flex; gap: 12px; padding: 16px;
+      margin: 20px 0 16px; align-items: flex-start;
+    }
+    .search-field { flex: 1; }
+
+    .product-grid {
+      display: grid;
+      grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
+      gap: 16px;
+    }
+
+    .product-card {
+      padding: 20px;
+      transition: transform 0.2s, box-shadow 0.2s;
+    }
+    .product-card:hover {
+      transform: translateY(-2px);
+      box-shadow: 0 6px 20px rgba(0,0,0,0.1);
+    }
+
+    .product-header {
+      display: flex; justify-content: space-between; align-items: center;
+      margin-bottom: 12px;
+    }
+    .product-icon-wrap {
+      width: 44px; height: 44px; border-radius: 12px;
+      background: linear-gradient(135deg, #e3f2fd, #bbdefb);
+      display: flex; align-items: center; justify-content: center;
+    }
+    .product-icon-wrap mat-icon { color: #1565c0; }
+
+    .product-price-wrap { text-align: right; }
+    .wholesale {
+      display: block; font-size: 22px; font-weight: 700; color: #2e7d32;
+    }
+    .retail { font-size: 11px; color: #999; }
+
+    .product-name { font-size: 16px; font-weight: 600; margin: 0 0 2px; color: #1a1a2e; }
+    .product-en { font-size: 12px; color: #999; margin: 0 0 8px; }
+
+    .product-meta { display: flex; gap: 8px; margin-bottom: 8px; }
+    .sku-tag {
+      font-size: 11px; padding: 2px 8px; background: #e8eaf6;
+      color: #5c6bc0; border-radius: 4px; font-family: monospace;
+    }
+    .series-tag {
+      font-size: 11px; padding: 2px 8px; background: #f5f5f5;
+      color: #777; border-radius: 4px;
+    }
+
+    .product-desc {
+      font-size: 13px; color: #555; margin: 0 0 10px; line-height: 1.5;
+    }
+
+    .target-customers {
+      display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
+    }
+    .target-label { font-size: 11px; color: #888; }
+    .target-chip {
+      font-size: 10px; padding: 1px 7px; border-radius: 8px; font-weight: 600;
+    }
+    .cat-a { background: #e3f2fd; color: #1565c0; }
+    .cat-b { background: #e8f5e9; color: #2e7d32; }
+    .cat-c { background: #f3e5f5; color: #6a1b9a; }
+    .cat-d { background: #fff3e0; color: #e65100; }
+
+    .results-count {
+      text-align: center; padding: 20px; font-size: 13px; color: #999;
+    }
+  `]
+})
+export class ProductCatalogComponent implements OnInit {
+  products: Product[] = [];
+  filteredProducts: Product[] = [];
+  searchText = '';
+  filterCat = '';
+
+  constructor(private mockData: MockDataService) {}
+
+  ngOnInit() {
+    this.products = this.mockData.products;
+    this.filteredProducts = this.products;
+  }
+
+  applyFilter() {
+    this.filteredProducts = this.products.filter(p => {
+      const matchSearch = !this.searchText ||
+        p.name.toLowerCase().includes(this.searchText.toLowerCase()) ||
+        p.nameEn.toLowerCase().includes(this.searchText.toLowerCase()) ||
+        p.sku.toLowerCase().includes(this.searchText.toLowerCase());
+      const matchCat = !this.filterCat ||
+        p.targetCustomers.includes(this.filterCat as CustomerCategory);
+      return matchSearch && matchCat;
+    });
+  }
+
+  getCatLabel(cat: CustomerCategory): string {
+    return CATEGORY_LABELS[cat] || cat;
+  }
+}
+

+ 465 - 0
lead-discovery/src/app/services/mock-data.service.ts

@@ -0,0 +1,465 @@
+import { Injectable } from '@angular/core';
+import {
+  Lead, Email, Product, CustomerCategory, ValueGrade, CustomerPersona,
+  QuickScreenResult, ProductRecommendation, AiDiscoveryBatch,
+  PERSONA_DEFINITIONS, categoryToPersona, ProductMatch
+} from '../models/lead.model';
+
+@Injectable({ providedIn: 'root' })
+export class MockDataService {
+
+  // ===== 产品目录(来自价盘 4.1) =====
+  readonly products: Product[] = [
+    { sku: 'CPIK0501', name: 'SE包高配(迷彩)', nameEn: 'SE IFAK Pro (Camo)', series: 'SE系列', wholesalePrice: 30, retailPrice: 60, category: 'IFAK', targetCustomers: ['A', 'B', 'D'], description: '260+配件,多场景适用,CE/FDA认证' },
+    { sku: 'CPIK0503', name: 'SE包高配(黑色)', nameEn: 'SE IFAK Pro (Black)', series: 'SE系列', wholesalePrice: 30, retailPrice: 60, category: 'IFAK', targetCustomers: ['A', 'B', 'D'], description: '260+配件,专业黑色款' },
+    { sku: 'CPTK0301', name: '17A套件袋', nameEn: '17pcs Refill Kit A', series: '补充套件', wholesalePrice: 25, retailPrice: 50, category: 'Refill', targetCustomers: ['A', 'B'], description: '塑料止血带+快拔盒,复购率高' },
+    { sku: 'CPTK0302', name: '17B套件袋', nameEn: '17pcs Refill Kit B', series: '补充套件', wholesalePrice: 25, retailPrice: 50, category: 'Refill', targetCustomers: ['A', 'B'], description: '金属止血带+软包' },
+    { sku: 'CPIK0901', name: 'R9背包(黑色)', nameEn: 'R9 Trauma Backpack (Black)', series: 'R系列大包', wholesalePrice: 175, retailPrice: 350, category: 'Backpack', targetCustomers: ['A', 'C'], description: 'MARCH-P协议,大容量专业级' },
+    { sku: 'CPIK0018', name: 'R40背包(绿色)', nameEn: 'R40 Medical Backpack (Green)', series: 'R系列大包', wholesalePrice: 250, retailPrice: 500, category: 'Backpack', targetCustomers: ['C'], description: '最大容量,救灾级别' },
+    { sku: 'CPIK0139', name: '常规急救箱50人', nameEn: 'All-Purpose First Aid Kit 50P', series: '常规急救箱', wholesalePrice: 18, retailPrice: 36, category: 'Kit', targetCustomers: ['A', 'B'], description: '50人规格,OSHA合规' },
+    { sku: 'CPIK0063', name: '常规急救箱100人', nameEn: 'All-Purpose First Aid Kit 100P', series: '常规急救箱', wholesalePrice: 28, retailPrice: 56, category: 'Kit', targetCustomers: ['A', 'B'], description: '100人规格,OSHA合规' },
+    { sku: 'CPHW0056', name: '壁挂式急救箱', nameEn: 'Wall-Mount First Aid Cabinet', series: '壁挂系列', wholesalePrice: 35, retailPrice: 70, category: 'Cabinet', targetCustomers: ['B'], description: 'OSHA合规,透明盖,壁挂安装' },
+    { sku: 'CPIK0021', name: 'EVA急救包', nameEn: 'EVA First Aid Case', series: '户外系列', wholesalePrice: 15, retailPrice: 30, category: 'Outdoor', targetCustomers: ['D'], description: '防水EVA外壳,轻量便携' },
+    { sku: 'CPCM0010', name: 'CMS IFAK MINI(黑色)', nameEn: 'CMS IFAK Mini (Black)', series: '战术IFAK', wholesalePrice: 20, retailPrice: 40, category: 'IFAK', targetCustomers: ['A', 'C'], description: 'MOLLE挂载,快拆设计' },
+    { sku: 'CPPZZX0010', name: '金属止血带(卡其)', nameEn: 'Metal Tourniquet (Khaki)', series: '单品', wholesalePrice: 5, retailPrice: 10, category: 'Single', targetCustomers: ['A', 'B', 'C', 'D'], description: '金属旋钮,单手操作' },
+  ];
+
+  // ===== 产品匹配规则(必须在 leads 之前初始化) =====
+  readonly categoryProductMap: Record<CustomerCategory, string[]> = {
+    A: ['CPTK0301', 'CPIK0501', 'CPIK0063', 'CPIK0139', 'CPCM0010', 'CPIK0901'],
+    B: ['CPHW0056', 'CPIK0139', 'CPIK0063', 'CPIK0501', 'CPTK0301'],
+    C: ['CPIK0901', 'CPIK0018', 'CPTK0301', 'CPCM0010'],
+    D: ['CPIK0021', 'CPIK0501', 'CPIK0503', 'CPPZZX0010'],
+  };
+
+  // ===== 模拟邮件 =====
+  readonly emails: Email[] = [
+    {
+      id: 'e1', from: 'john.smith@acmemedical.com', fromName: 'John Smith',
+      to: 'sales@rhinorescue.com', cc: 'purchasing@acmemedical.com',
+      subject: 'Inquiry: Bulk IFAK Kits for Hospital Network',
+      preview: 'Dear Sir/Madam, We are a medical supply distributor based in Ohio, USA. We are looking for a reliable manufacturer of IFAK kits for our hospital network clients...',
+      body: `Dear Sir/Madam,
+
+I hope this email finds you well. My name is John Smith, and I am the Head of Procurement at Acme Medical Supplies, a medical supply distributor based in Columbus, Ohio, USA.
+
+We are currently looking for a reliable manufacturer of Individual First Aid Kit (IFAK) products to supply our hospital network clients across the Midwest region. Our network includes over 120 hospitals and 350 urgent care clinics.
+
+Specifically, we are interested in the following:
+
+1. Tactical IFAK kits (MOLLE compatible) — estimated quantity: 5,000 units/year
+2. Refill kits for existing IFAK pouches — estimated quantity: 10,000 units/year
+3. Wall-mounted first aid cabinets (OSHA compliant) — estimated quantity: 800 units
+
+We require all products to be FDA registered and carry relevant certifications (ISO 13485, CE marking preferred).
+
+Could you please provide:
+• Product catalog with specifications
+• FOB pricing for the above quantities
+• Lead time and MOQ information
+• Certification documents (FDA 510k, ISO 13485, CE)
+
+We are also open to scheduling a video call to discuss potential long-term partnership opportunities.
+
+Looking forward to your prompt reply.
+
+Best regards,
+John Smith
+Head of Procurement
+Acme Medical Supplies
+Tel: +1 (614) 555-0182
+Email: john.smith@acmemedical.com`,
+      attachments: [
+        { id: 'a1-1', fileName: 'Acme_Medical_Company_Profile.pdf', fileSize: 2458624, mimeType: 'application/pdf', icon: 'picture_as_pdf' },
+        { id: 'a1-2', fileName: 'Product_Requirements_Spec.xlsx', fileSize: 185320, mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', icon: 'table_chart' },
+        { id: 'a1-3', fileName: 'Hospital_Network_List.pdf', fileSize: 1024000, mimeType: 'application/pdf', icon: 'picture_as_pdf' },
+      ],
+      receivedAt: new Date('2026-02-11T08:30:00'), hasScreened: false,
+    },
+    {
+      id: 'e2', from: 'procurement@safetyfirst-uk.co.uk', fromName: 'Sarah Johnson',
+      to: 'sales@rhinorescue.com',
+      subject: 'RE: OSHA Compliant First Aid Cabinets - Quote Request',
+      preview: 'Hi, Following our conversation at the Birmingham Safety Expo, we would like to request a formal quotation for wall-mounted first aid cabinets...',
+      body: `Hi,
+
+Following our conversation at the Birmingham Safety Expo last week, I wanted to formally reach out regarding wall-mounted first aid cabinets for our UK distribution network.
+
+SafetyFirst UK is one of the leading workplace safety equipment distributors in the United Kingdom, serving over 5,000 commercial and industrial clients. We currently supply first aid solutions to manufacturing plants, construction sites, and office buildings across England, Scotland, and Wales.
+
+We are specifically looking for:
+
+1. Wall-Mount First Aid Cabinets (transparent door, lockable)
+   - OSHA/ANSI Z308.1 compliant
+   - 50-person capacity: 1,200 units
+   - 100-person capacity: 600 units
+
+2. Cabinet refill kits (matching the above cabinets)
+   - 50-person refills: 3,000 units/year
+   - 100-person refills: 1,500 units/year
+
+Key requirements:
+• CE marking mandatory for UK market
+• HSE (Health and Safety Executive) compliance documentation
+• Custom labeling with SafetyFirst branding (white-label option)
+• Delivery to our Birmingham warehouse (DDP terms preferred)
+
+Please provide a detailed quotation including:
+- Unit pricing at the above volumes
+- Sample availability and cost
+- Production lead time
+- Minimum order quantities for reorders
+
+We would also appreciate receiving your full product catalog, as we may be interested in expanding our first aid product range.
+
+Kind regards,
+Sarah Johnson
+Procurement Manager
+SafetyFirst UK Ltd
+Unit 7, Aston Business Park
+Birmingham, B6 4RJ, United Kingdom
+Tel: +44 121 555 0234
+Email: procurement@safetyfirst-uk.co.uk`,
+      attachments: [
+        { id: 'a2-1', fileName: 'SafetyFirst_Vendor_Application.pdf', fileSize: 892416, mimeType: 'application/pdf', icon: 'picture_as_pdf' },
+        { id: 'a2-2', fileName: 'Birmingham_Expo_Meeting_Notes.docx', fileSize: 45200, mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', icon: 'description' },
+      ],
+      receivedAt: new Date('2026-02-11T06:15:00'), hasScreened: false,
+    },
+    {
+      id: 'e3', from: 'tender@redcross-pl.org', fromName: 'Marek Kowalski',
+      to: 'sales@rhinorescue.com', cc: 'logistics@redcross-pl.org, legal@redcross-pl.org',
+      subject: 'Tender Notice: Emergency Medical Backpacks - Ref#2026/RC/045',
+      preview: 'Dear Supplier, Polish Red Cross is inviting tenders for the supply of 500 emergency medical backpacks for disaster relief operations...',
+      body: `Dear Supplier,
+
+TENDER NOTICE — Reference: 2026/RC/045
+Subject: Supply of Emergency Medical Backpacks for Disaster Relief Operations
+
+The Polish Red Cross (Polski Czerwony Krzyż) hereby invites qualified suppliers to submit tenders for the supply of emergency medical backpacks as detailed below.
+
+PROJECT BACKGROUND:
+This procurement is part of the EU-funded "European Emergency Preparedness Initiative 2026" aimed at strengthening disaster relief capabilities across Central and Eastern Europe. The equipment will be pre-positioned at 12 regional emergency response centers.
+
+REQUIREMENTS:
+
+Lot 1 — Trauma Backpacks (Large)
+• Quantity: 500 units
+• Specifications: MARCH-P protocol compliant, minimum 40L capacity
+• Contents: Full trauma kit including tourniquets, hemostatic agents, chest seals, airway management tools
+• Color: International orange or red with reflective strips
+• Marking: Red Cross emblem + EU flag (templates attached)
+
+Lot 2 — IFAK Pouches (Individual)
+• Quantity: 2,000 units
+• Specifications: MOLLE compatible, compact tactical design
+• Contents: Basic trauma supplies (tourniquet, bandage, chest seal, gloves)
+
+Lot 3 — Refill Kits
+• Quantity: 3,000 sets (matching Lot 1 and Lot 2)
+
+MANDATORY REQUIREMENTS:
+✓ CE marking (Medical Device Regulation 2017/745)
+✓ ISO 13485 certification
+✓ Shelf life minimum 3 years from delivery
+✓ All items individually sealed in sterile packaging where applicable
+
+SUBMISSION DEADLINE: March 15, 2026, 17:00 CET
+DELIVERY DEADLINE: June 30, 2026
+DELIVERY LOCATION: Warsaw Central Warehouse, Poland
+
+Please find the complete tender documentation attached. All questions should be directed to tender@redcross-pl.org before March 1, 2026.
+
+Best regards,
+Marek Kowalski
+Senior Procurement Officer
+Polish Red Cross — Disaster Relief Division
+ul. Mokotowska 14, 00-561 Warszawa, Poland
+Tel: +48 22 555 0891
+Email: tender@redcross-pl.org`,
+      attachments: [
+        { id: 'a3-1', fileName: 'Tender_2026_RC_045_Full_Document.pdf', fileSize: 5242880, mimeType: 'application/pdf', icon: 'picture_as_pdf' },
+        { id: 'a3-2', fileName: 'Technical_Specifications_Lot1-3.pdf', fileSize: 3145728, mimeType: 'application/pdf', icon: 'picture_as_pdf' },
+        { id: 'a3-3', fileName: 'Branding_Templates.zip', fileSize: 8912000, mimeType: 'application/zip', icon: 'folder_zip' },
+        { id: 'a3-4', fileName: 'Vendor_Qualification_Form.xlsx', fileSize: 124800, mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', icon: 'table_chart' },
+      ],
+      receivedAt: new Date('2026-02-10T14:00:00'), hasScreened: false,
+    },
+    {
+      id: 'e4', from: 'alex@wildgear.de', fromName: 'Alexander Müller',
+      to: 'sales@rhinorescue.com',
+      subject: 'Custom First Aid Kits for Outdoor Brand - OEM Inquiry',
+      preview: 'Hello, We are WildGear, a German outdoor sports brand. We are looking for a manufacturer to produce private label first aid kits with our branding...',
+      body: `Hello,
+
+My name is Alexander Müller, and I am the Product Development Manager at WildGear GmbH, a German outdoor sports and adventure brand. We have been in the market for 12 years and sell through 200+ retail partners across DACH region (Germany, Austria, Switzerland) as well as our own e-commerce platform.
+
+We are currently expanding our product line to include first aid and safety equipment, and we are looking for an experienced OEM manufacturer to produce private-label first aid kits under the WildGear brand.
+
+Here is what we have in mind:
+
+1. Compact Outdoor First Aid Kit (EVA case)
+   - Custom WildGear branding (logo, colors, packaging)
+   - Waterproof EVA shell in our signature "Forest Green" color
+   - Target retail price: €29.99
+   - Initial order: 3,000 units
+   - Annual forecast: 10,000-15,000 units
+
+2. Hiking First Aid Pouch (lightweight)
+   - Belt/backpack clip mount
+   - Minimalist design, under 200g
+   - Initial order: 5,000 units
+   - Annual forecast: 20,000 units
+
+3. Vehicle Emergency Kit
+   - Hard case with WildGear branding
+   - DIN 13164 compliant (German vehicle first aid standard)
+   - Initial order: 2,000 units
+
+Design requirements:
+• All packaging and inserts in German and English
+• Pantone colors: 7483 C (Forest Green), 7401 C (Sand)
+• Custom insert card with WildGear QR code linking to our first aid tutorial app
+
+I have attached our brand guidelines and a mood board for reference. Could we schedule a call next week to discuss capabilities, pricing, and timelines?
+
+Best regards,
+Alexander Müller
+Product Development Manager
+WildGear GmbH
+Leopoldstraße 42, 80802 München, Germany
+Tel: +49 89 555 0347
+Email: alex@wildgear.de
+Web: www.wildgear.de`,
+      attachments: [
+        { id: 'a4-1', fileName: 'WildGear_Brand_Guidelines_2026.pdf', fileSize: 15728640, mimeType: 'application/pdf', icon: 'picture_as_pdf' },
+        { id: 'a4-2', fileName: 'OEM_Product_Mood_Board.pdf', fileSize: 4194304, mimeType: 'application/pdf', icon: 'picture_as_pdf' },
+        { id: 'a4-3', fileName: 'WildGear_Logo_Pack.zip', fileSize: 2097152, mimeType: 'application/zip', icon: 'folder_zip' },
+      ],
+      receivedAt: new Date('2026-02-10T10:45:00'), hasScreened: false,
+    },
+    {
+      id: 'e5', from: 'info@globaltrading88.com', fromName: 'Mike Chen',
+      to: 'sales@rhinorescue.com',
+      subject: 'Wholesale Various Products',
+      preview: 'Hello friend, we are looking for all kinds of products for wholesale. Can you send us your full catalog with best prices? We buy everything...',
+      body: `Hello friend,
+
+We are Global Trading 88 company. We are looking for all kinds of products for wholesale business. We buy everything — first aid kits, medical supplies, safety equipment, outdoor gear, etc.
+
+Can you send us your full catalog with best prices? We need lowest price for big quantity.
+
+Also interested in:
+- Any clearance or overstock items
+- B-grade products at discount
+- Mixed container deals
+
+Please send catalog and price list ASAP.
+
+Thanks,
+Mike Chen
+Global Trading 88
+info@globaltrading88.com`,
+      attachments: [],
+      receivedAt: new Date('2026-02-09T16:20:00'), hasScreened: false,
+    },
+    {
+      id: 'e6', from: 'lisa@meditechsupply.ca', fromName: 'Lisa Wang',
+      to: 'sales@rhinorescue.com', cc: 'bd@meditechsupply.ca',
+      subject: 'Partnership Inquiry - Canadian Medical Distributor',
+      preview: 'Dear Rhino Rescue Team, MediTech Supply is a leading medical equipment distributor in Canada with 15 years of experience. We are interested in becoming your authorized distributor...',
+      body: `Dear Rhino Rescue Team,
+
+I am Lisa Wang, Business Development Director at MediTech Supply Inc., a leading medical equipment distributor headquartered in Toronto, Canada. We have been in the medical supply industry for 15 years and currently serve over 800 healthcare facilities across Canada, including hospitals, long-term care homes, and emergency medical services.
+
+We have been following your product line with great interest, particularly your tactical IFAK kits and trauma backpacks. After reviewing your products at the MEDICA trade show in Düsseldorf last November, we believe there is a strong market fit for Rhino Rescue products in the Canadian healthcare market.
+
+We are writing to express our interest in becoming your authorized distributor for Canada. Here is what we bring to the table:
+
+Company Highlights:
+• 15 years in Canadian medical distribution
+• 800+ active healthcare facility accounts
+• Nationwide logistics network (warehouses in Toronto, Vancouver, Calgary)
+• Health Canada licensed medical device importer (License #: MD-2019-0847)
+• Annual revenue: CAD $45M (2025)
+• Dedicated sales team of 28 representatives
+
+Products of Interest:
+1. SE IFAK Pro series — for hospital emergency departments
+2. Refill Kit A & B — for ongoing replenishment contracts
+3. R9 Trauma Backpack — for EMS and paramedic services
+4. CMS IFAK Mini — for law enforcement partnerships
+5. Metal Tourniquets — as standalone accessories
+
+Proposed Partnership Structure:
+• Exclusive distribution rights for Canada (or Ontario + BC initially)
+• Annual minimum purchase commitment: USD $200,000 (Year 1)
+• Marketing co-investment for Canadian market launch
+• Joint participation in Canadian healthcare trade shows
+
+I have attached our company profile, distribution network map, and a draft partnership proposal for your review.
+
+Would it be possible to arrange a video conference next week to discuss this opportunity in detail?
+
+Warm regards,
+Lisa Wang
+Business Development Director
+MediTech Supply Inc.
+100 King Street West, Suite 5600
+Toronto, ON M5X 1C9, Canada
+Tel: +1 (416) 555-0298
+Email: lisa@meditechsupply.ca
+Web: www.meditechsupply.ca`,
+      attachments: [
+        { id: 'a6-1', fileName: 'MediTech_Company_Profile_2026.pdf', fileSize: 3670016, mimeType: 'application/pdf', icon: 'picture_as_pdf' },
+        { id: 'a6-2', fileName: 'Canada_Distribution_Network_Map.pdf', fileSize: 1572864, mimeType: 'application/pdf', icon: 'picture_as_pdf' },
+        { id: 'a6-3', fileName: 'Partnership_Proposal_Draft.docx', fileSize: 256000, mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', icon: 'description' },
+        { id: 'a6-4', fileName: 'Health_Canada_Import_License.pdf', fileSize: 524288, mimeType: 'application/pdf', icon: 'picture_as_pdf' },
+        { id: 'a6-5', fileName: 'MEDICA_2025_Product_Photos.zip', fileSize: 12582912, mimeType: 'application/zip', icon: 'folder_zip' },
+      ],
+      receivedAt: new Date('2026-02-09T09:00:00'), hasScreened: false,
+    },
+  ];
+
+  // ===== 模拟已有线索 =====
+  readonly leads: Lead[] = [
+    this.createLead('l1', 'Acme Medical Supplies', 'john.smith@acmemedical.com', 'John Smith', 'US', 'A', 'S', 'P1', 'email', 'screened', 120000, new Date('2026-02-11')),
+    this.createLead('l2', 'SafetyFirst UK', 'procurement@safetyfirst-uk.co.uk', 'Sarah Johnson', 'GB', 'B', 'A', 'P2', 'exhibition', 'contacted', 45000, new Date('2026-02-13')),
+    this.createLead('l3', 'Polish Red Cross', 'tender@redcross-pl.org', 'Marek Kowalski', 'PL', 'C', 'S', 'P3', 'email', 'screened', 200000, new Date('2026-02-12')),
+    this.createLead('l4', 'WildGear Outdoor', 'alex@wildgear.de', 'Alexander Müller', 'DE', 'D', 'A', 'P4', 'email', 'replied', 35000, new Date('2026-02-15')),
+    this.createLead('l5', 'MediTech Supply Canada', 'lisa@meditechsupply.ca', 'Lisa Wang', 'CA', 'A', 'A', 'P1', 'email', 'sample', 85000, new Date('2026-02-14')),
+    this.createLead('l6', 'BuildSafe Australia', 'orders@buildsafe.com.au', 'Tom Richards', 'AU', 'B', 'B', 'P2', 'platform', 'screened', 20000, new Date('2026-02-18')),
+    this.createLead('l7', 'Global Trading 88', 'info@globaltrading88.com', 'Mike Chen', 'CN', 'D', 'C', 'P6', 'email', 'screened', 5000, new Date('2026-03-01')),
+    this.createLead('l8', 'Bundeswehr Procurement', 'beschaffung@bwb.de', 'Hans Weber', 'DE', 'C', 'A', 'P3', 'exhibition', 'quote', 350000, new Date('2026-02-16')),
+    this.createLead('l9', 'TrailBlazer Gear', 'buying@trailblazer.com', 'Emma Davis', 'US', 'D', 'B', 'P5', 'platform', 'contacted', 15000, new Date('2026-02-20')),
+    this.createLead('l10', 'NordicMed AB', 'supply@nordicmed.se', 'Erik Lindgren', 'SE', 'A', 'S', 'P1', 'email', 'contacted', 95000, new Date('2026-02-12')),
+  ];
+
+  // ===== AI 挖掘批次(模拟) =====
+  readonly discoveryBatches: AiDiscoveryBatch[] = [
+    {
+      id: 'batch-1', runAt: new Date('2026-02-11T08:00:00'), triggerType: 'daily',
+      totalProcessed: 47, newLeadsFound: 12,
+      personaBreakdown: { P1: 5, P2: 2, P3: 1, P4: 2, P5: 1, P6: 1 },
+      gradeBreakdown: { S: 2, A: 4, B: 4, C: 2 },
+      pendingVerification: 5, verified: 7, status: 'completed',
+    },
+    {
+      id: 'batch-2', runAt: new Date('2026-02-10T08:00:00'), triggerType: 'daily',
+      totalProcessed: 35, newLeadsFound: 8,
+      personaBreakdown: { P1: 3, P2: 1, P3: 2, P4: 1, P5: 0, P6: 1 },
+      gradeBreakdown: { S: 1, A: 3, B: 3, C: 1 },
+      pendingVerification: 2, verified: 6, status: 'completed',
+    },
+  ];
+
+  getProductsBySKUs(skus: string[]): Product[] {
+    return skus.map(sku => this.products.find(p => p.sku === sku)).filter(Boolean) as Product[];
+  }
+
+  getRecommendedProducts(category: CustomerCategory): ProductRecommendation[] {
+    const skus = this.categoryProductMap[category] || [];
+    return skus.slice(0, 4).map(sku => {
+      const p = this.products.find(pr => pr.sku === sku);
+      if (!p) return null;
+      return {
+        sku: p.sku,
+        name: p.name,
+        nameEn: p.nameEn,
+        wholesalePrice: p.wholesalePrice,
+        retailPrice: p.retailPrice,
+        reason: p.description,
+      } as ProductRecommendation;
+    }).filter(Boolean) as ProductRecommendation[];
+  }
+
+  private createLead(
+    id: string, company: string, email: string, contact: string,
+    country: string, cat: CustomerCategory, grade: ValueGrade,
+    persona: CustomerPersona,
+    source: 'email' | 'manual' | 'exhibition' | 'platform' | 'ai_discovery',
+    stage: Lead['followUpStage'], orderValue: number, nextDate: Date
+  ): Lead {
+    const catLabels: Record<CustomerCategory, string> = { A: '医疗渠道', B: '工业安全', C: '应急政府', D: '品牌OEM' };
+    const sourceLabels: Record<string, string> = { email: '邮件', manual: '手动录入', exhibition: '展会', platform: '平台', ai_discovery: 'AI发现' };
+    const products = this.getRecommendedProducts(cat);
+    const personaDef = PERSONA_DEFINITIONS[persona];
+    const personaConf = grade === 'S' ? 92 : grade === 'A' ? 85 : grade === 'B' ? 70 : 55;
+
+    const aiReport = (stage === 'sample' || stage === 'quote' || stage === 'order') ? {
+      websiteAnalysis: `${company} 是一家位于${country}的${personaDef.name}企业,规模约${grade === 'S' ? '200-500人' : grade === 'A' ? '50-200人' : '10-50人'}。主营业务包括${personaDef.description}。`,
+      productMatching: products.slice(0, 2).map(p => ({
+        ourProduct: p.name, ourSku: p.sku,
+        matchesNeed: `匹配其${catLabels[cat]}需求`,
+        profitMargin: `批发$${p.wholesalePrice} vs 零售$${p.retailPrice} (${Math.round((1 - p.wholesalePrice / p.retailPrice) * 100)}%)`,
+      } as ProductMatch)),
+      competitorAnalysis: `当前可能供应商为行业头部品牌,我方优势:价格低30-40%、交期快2周、认证齐全`,
+      generatedAt: new Date(Date.now() - Math.random() * 3 * 86400000),
+    } : undefined;
+
+    return {
+      id, leadNumber: `LD-${Date.now()}-${id}`,
+      contactName: contact, contactEmail: email, companyName: company,
+      country, source, sourceLabel: sourceLabels[source],
+      customerCategory: cat, categoryLabel: catLabels[cat], valueGrade: grade,
+      persona, personaLabel: personaDef.name, personaConfidence: personaConf,
+      personaVerified: stage !== 'screened',
+      quickScreenResult: {
+        companyName: company, domain: email.split('@')[1], country,
+        customerCategory: cat, categoryLabel: catLabels[cat],
+        valueGrade: grade, productRelevance: grade === 'S' || grade === 'A' ? 'high' : 'medium',
+        mainBusiness: this.getMainBusiness(cat),
+        estimatedScale: this.getScale(grade),
+        certRequirements: this.getCerts(cat, country),
+        recommendedAction: this.getAction(grade),
+        suggestedProducts: products,
+        socialLinks: {},
+        confidence: personaConf,
+        processingTime: Math.floor(Math.random() * 5000) + 3000,
+        persona, personaLabel: personaDef.name, personaConfidence: personaConf,
+        matchedKeywords: personaDef.identifyKeywords.slice(0, 3),
+      },
+      quickScreenAt: new Date(),
+      hasDeepAnalysis: stage === 'sample' || stage === 'quote' || stage === 'order',
+      aiResearchReport: aiReport,
+      followUpStage: stage,
+      nextFollowUpDate: nextDate,
+      followUpNotes: '',
+      matchedProductSKUs: products.map(p => p.sku),
+      estimatedOrderValue: orderValue,
+      createdAt: new Date(Date.now() - Math.random() * 7 * 86400000),
+    };
+  }
+
+  private getMainBusiness(cat: CustomerCategory): string {
+    const m: Record<CustomerCategory, string> = {
+      A: '医疗耗材批发分销', B: '工业安全设备供应', C: '应急物资采购', D: '户外品牌产品定制'
+    };
+    return m[cat];
+  }
+
+  private getScale(grade: ValueGrade): string {
+    const m: Record<ValueGrade, string> = { S: '200-500人', A: '50-200人', B: '10-50人', C: '<10人' };
+    return m[grade];
+  }
+
+  private getCerts(cat: CustomerCategory, country: string): string[] {
+    const base: string[] = [];
+    if (['US'].includes(country)) base.push('FDA');
+    if (['GB', 'DE', 'PL', 'SE'].includes(country)) base.push('CE', 'MDR');
+    if (cat === 'B') base.push('OSHA', 'ANSI');
+    if (cat === 'A') base.push('ISO13485');
+    if (cat === 'C') base.push('ISO13485');
+    return [...new Set(base)];
+  }
+
+  private getAction(grade: ValueGrade): string {
+    const m: Record<ValueGrade, string> = {
+      S: '立即跟进,24h内发送开发信',
+      A: '3天内发送开发信,附资质文件+目录',
+      B: '7天内跟进,先发目录探需求',
+      C: '归档观察,定期群发营销邮件',
+    };
+    return m[grade];
+  }
+}

+ 210 - 0
lead-discovery/src/app/services/quick-screen.service.ts

@@ -0,0 +1,210 @@
+import { Injectable } from '@angular/core';
+import { MockDataService } from './mock-data.service';
+import {
+  QuickScreenResult, CustomerCategory, ValueGrade, CustomerPersona,
+  Lead, Email, PERSONA_DEFINITIONS
+} from '../models/lead.model';
+
+/**
+ * 第一阶段:快速筛选服务
+ * 模拟 域名提取 → 首页快照 → AI分类 的流程
+ */
+@Injectable({ providedIn: 'root' })
+export class QuickScreenService {
+
+  constructor(private mockData: MockDataService) {}
+
+  /**
+   * 执行快速筛选(模拟)
+   */
+  async screenEmail(email: Email): Promise<QuickScreenResult> {
+    const start = Date.now();
+    const domain = this.extractDomain(email.from);
+    await this.simulateDelay(1500);
+    const result = this.classifyByDomain(domain, email.subject, email.preview);
+    result.processingTime = Date.now() - start;
+    return result;
+  }
+
+  /**
+   * 手动录入快速筛选
+   */
+  async screenManual(companyName: string, emailAddress: string): Promise<QuickScreenResult> {
+    const start = Date.now();
+    const domain = emailAddress ? this.extractDomain(emailAddress) : '';
+    await this.simulateDelay(1200);
+    const result = this.classifyByDomain(domain, companyName, '');
+    result.companyName = companyName;
+    result.processingTime = Date.now() - start;
+    return result;
+  }
+
+  /**
+   * 从筛选结果创建Lead
+   */
+  createLeadFromScreen(screen: QuickScreenResult, email?: Email): Lead {
+    const now = new Date();
+    const nextDate = new Date();
+
+    switch (screen.valueGrade) {
+      case 'S': nextDate.setDate(now.getDate() + 1); break;
+      case 'A': nextDate.setDate(now.getDate() + 3); break;
+      case 'B': nextDate.setDate(now.getDate() + 7); break;
+      case 'C': nextDate.setDate(now.getDate() + 30); break;
+    }
+
+    const personaDef = PERSONA_DEFINITIONS[screen.persona];
+
+    return {
+      id: 'l-' + Date.now(),
+      leadNumber: 'LD-' + Date.now(),
+      contactName: email?.fromName || '',
+      contactEmail: email?.from || '',
+      companyName: screen.companyName,
+      country: screen.country,
+      source: email ? 'email' : 'manual',
+      sourceLabel: email ? '邮件' : '手动录入',
+      customerCategory: screen.customerCategory,
+      categoryLabel: screen.categoryLabel,
+      valueGrade: screen.valueGrade,
+      persona: screen.persona,
+      personaLabel: personaDef.name,
+      personaConfidence: screen.personaConfidence,
+      personaVerified: false,
+      quickScreenResult: screen,
+      quickScreenAt: now,
+      hasDeepAnalysis: false,
+      followUpStage: 'screened',
+      nextFollowUpDate: nextDate,
+      followUpNotes: '',
+      matchedProductSKUs: screen.suggestedProducts.map(p => p.sku),
+      estimatedOrderValue: this.estimateOrderValue(screen.valueGrade, screen.customerCategory),
+      createdAt: now,
+    };
+  }
+
+  // ===== 内部方法 =====
+
+  private extractDomain(email: string): string {
+    const parts = email.split('@');
+    if (parts.length !== 2) return '';
+    const domain = parts[1].toLowerCase();
+    const freeProviders = ['gmail.com', 'yahoo.com', 'outlook.com', 'hotmail.com', 'qq.com', '163.com'];
+    return freeProviders.includes(domain) ? '' : domain;
+  }
+
+  /**
+   * 模拟AI分类逻辑(真实场景由LLM完成)
+   * 现在同时输出 CustomerCategory + CustomerPersona
+   */
+  private classifyByDomain(domain: string, title: string, content: string): QuickScreenResult {
+    const text = `${domain} ${title} ${content}`.toLowerCase();
+
+    let category: CustomerCategory = 'D';
+    let persona: CustomerPersona = 'P4';
+    let grade: ValueGrade = 'B';
+    let country = 'Unknown';
+    let mainBusiness = '待分析';
+    let confidence = 60;
+    const matchedKeywords: string[] = [];
+
+    // 国家推断
+    if (domain.endsWith('.com')) country = 'US';
+    else if (domain.endsWith('.co.uk')) country = 'GB';
+    else if (domain.endsWith('.de')) country = 'DE';
+    else if (domain.endsWith('.org')) country = 'PL';
+    else if (domain.endsWith('.ca')) country = 'CA';
+    else if (domain.endsWith('.au')) country = 'AU';
+    else if (domain.endsWith('.se')) country = 'SE';
+
+    // 画像分类规则(优先级:P6 > P3 > P1 > P2 > P5 > P4)
+    if (text.includes('everything') || text.includes('all kinds') || text.includes('lowest price') ||
+        (text.includes('wholesale') && text.includes('various'))) {
+      category = 'D'; persona = 'P6'; mainBusiness = '综合贸易(低质量)'; confidence = 55;
+      matchedKeywords.push(...['everything', 'lowest price', 'all kinds'].filter(k => text.includes(k)));
+    } else if (text.includes('tender') || text.includes('government') || text.includes('emergency') ||
+               text.includes('red cross') || text.includes('military') || text.includes('disaster')) {
+      category = 'C'; persona = 'P3'; mainBusiness = '应急物资政府采购'; confidence = 90;
+      matchedKeywords.push(...['tender', 'government', 'emergency', 'red cross', 'military'].filter(k => text.includes(k)));
+    } else if (text.includes('medical') || text.includes('hospital') || text.includes('ifak') ||
+               text.includes('distributor') || text.includes('pharmacy') || text.includes('fda')) {
+      category = 'A'; persona = 'P1'; mainBusiness = '医疗耗材批发分销'; confidence = 88;
+      matchedKeywords.push(...['medical', 'hospital', 'distributor', 'IFAK', 'FDA'].filter(k => text.includes(k.toLowerCase())));
+    } else if (text.includes('safety') || text.includes('osha') || text.includes('workplace') ||
+               text.includes('industrial') || text.includes('cabinet')) {
+      category = 'B'; persona = 'P2'; mainBusiness = '工业安全设备供应'; confidence = 85;
+      matchedKeywords.push(...['safety', 'OSHA', 'workplace', 'industrial'].filter(k => text.includes(k.toLowerCase())));
+    } else if (text.includes('amazon') || text.includes('shopify') || text.includes('fba') ||
+               text.includes('dropship') || text.includes('e-commerce')) {
+      category = 'D'; persona = 'P5'; mainBusiness = '电商零售'; confidence = 82;
+      matchedKeywords.push(...['amazon', 'shopify', 'FBA', 'dropship'].filter(k => text.includes(k.toLowerCase())));
+    } else if (text.includes('outdoor') || text.includes('oem') || text.includes('custom') ||
+               text.includes('brand') || text.includes('private label') || text.includes('gear')) {
+      category = 'D'; persona = 'P4'; mainBusiness = '户外品牌产品定制'; confidence = 82;
+      matchedKeywords.push(...['outdoor', 'OEM', 'custom', 'brand', 'private label'].filter(k => text.includes(k.toLowerCase())));
+    }
+
+    // 等级推断
+    if (text.includes('bulk') || text.includes('tender') || text.includes('500') ||
+        text.includes('network') || text.includes('authorized')) {
+      grade = 'S'; confidence = Math.min(confidence + 5, 95);
+    } else if (text.includes('quote') || text.includes('partnership') || text.includes('distributor')) {
+      grade = 'A';
+    } else if (text.includes('wholesale') || text.includes('various') || text.includes('catalog')) {
+      grade = text.includes('everything') ? 'C' : 'B';
+      if (grade === 'C') confidence = 55;
+    }
+
+    const categoryLabels: Record<CustomerCategory, string> = {
+      A: '医疗渠道', B: '工业安全', C: '应急政府', D: '品牌OEM'
+    };
+
+    const gradeActions: Record<ValueGrade, string> = {
+      S: '立即跟进,24h内发送开发信',
+      A: '3天内发送开发信,附资质文件+目录',
+      B: '7天内跟进,先发目录探需求',
+      C: '归档观察,定期群发营销邮件',
+    };
+
+    const personaDef = PERSONA_DEFINITIONS[persona];
+    const products = this.mockData.getRecommendedProducts(category);
+
+    const certs: string[] = [];
+    if (['US'].includes(country)) certs.push('FDA');
+    if (['GB', 'DE', 'PL', 'SE'].includes(country)) certs.push('CE', 'MDR');
+    if (category === 'B') certs.push('OSHA');
+    if (category === 'A' || category === 'C') certs.push('ISO13485');
+
+    return {
+      companyName: domain ? domain.split('.')[0].charAt(0).toUpperCase() + domain.split('.')[0].slice(1) : title.split(' ')[0],
+      domain,
+      country,
+      customerCategory: category,
+      categoryLabel: categoryLabels[category],
+      valueGrade: grade,
+      productRelevance: grade === 'S' || grade === 'A' ? 'high' : grade === 'B' ? 'medium' : 'low',
+      mainBusiness,
+      estimatedScale: grade === 'S' ? '200-500人' : grade === 'A' ? '50-200人' : grade === 'B' ? '10-50人' : '<10人',
+      certRequirements: [...new Set(certs)],
+      recommendedAction: gradeActions[grade],
+      suggestedProducts: products,
+      socialLinks: {},
+      confidence,
+      processingTime: 0,
+      persona,
+      personaLabel: personaDef.name,
+      personaConfidence: confidence,
+      matchedKeywords,
+    };
+  }
+
+  private estimateOrderValue(grade: ValueGrade, cat: CustomerCategory): number {
+    const base: Record<ValueGrade, number> = { S: 100000, A: 50000, B: 15000, C: 3000 };
+    const multiplier: Record<CustomerCategory, number> = { A: 1.2, B: 0.8, C: 2.0, D: 0.6 };
+    return Math.round(base[grade] * multiplier[cat]);
+  }
+
+  private simulateDelay(ms: number): Promise<void> {
+    return new Promise(resolve => setTimeout(resolve, ms));
+  }
+}

+ 15 - 0
lead-discovery/src/index.html

@@ -0,0 +1,15 @@
+<!doctype html>
+<html lang="zh-CN">
+<head>
+  <meta charset="utf-8">
+  <title>线索管理demo</title>
+  <base href="/">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <link rel="icon" type="image/x-icon" href="favicon.ico">
+  <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">
+  <link href="https://fonts.googleapis.com/icon?family=Material+Icons|Material+Icons+Outlined" rel="stylesheet">
+</head>
+<body class="mat-typography">
+  <app-root></app-root>
+</body>
+</html>

+ 6 - 0
lead-discovery/src/main.ts

@@ -0,0 +1,6 @@
+import { bootstrapApplication } from '@angular/platform-browser';
+import { appConfig } from './app/app.config';
+import { AppComponent } from './app/app.component';
+
+bootstrapApplication(AppComponent, appConfig)
+  .catch((err) => console.error(err));

+ 135 - 0
lead-discovery/src/styles.scss

@@ -0,0 +1,135 @@
+@use '@angular/material' as mat;
+
+@include mat.elevation-classes();
+@include mat.app-background();
+
+$lead-discovery-theme: mat.define-theme((
+  color: (
+    theme-type: light,
+    primary: mat.$azure-palette,
+    tertiary: mat.$blue-palette,
+  ),
+  density: (
+    scale: 0,
+  )
+));
+
+:root {
+  @include mat.all-component-themes($lead-discovery-theme);
+}
+
+/* ===== Global Styles ===== */
+html, body {
+  height: 100%;
+  margin: 0;
+  padding: 0;
+  font-family: 'Roboto', 'Helvetica Neue', sans-serif;
+  background: #f5f7fa;
+  color: #1a1a2e;
+  overflow: hidden;
+}
+
+/* Fix mat-sidenav-container height */
+.mat-sidenav-container {
+  height: 100% !important;
+}
+
+.mat-sidenav-content {
+  overflow: auto !important;
+}
+
+
+/* ===== CSS Variables ===== */
+:root {
+  --primary: #1976d2;
+  --primary-light: #e3f2fd;
+  --accent: #ff6f00;
+  --success: #2e7d32;
+  --success-light: #e8f5e9;
+  --warning: #f57f17;
+  --warning-light: #fff8e1;
+  --danger: #c62828;
+  --danger-light: #ffebee;
+  --info: #0277bd;
+  --info-light: #e1f5fe;
+
+  --grade-s: #c62828;
+  --grade-s-bg: #ffebee;
+  --grade-a: #e65100;
+  --grade-a-bg: #fff3e0;
+  --grade-b: #f9a825;
+  --grade-b-bg: #fffde7;
+  --grade-c: #757575;
+  --grade-c-bg: #fafafa;
+
+  --cat-a: #1565c0;
+  --cat-a-bg: #e3f2fd;
+  --cat-b: #2e7d32;
+  --cat-b-bg: #e8f5e9;
+  --cat-c: #6a1b9a;
+  --cat-c-bg: #f3e5f5;
+  --cat-d: #e65100;
+  --cat-d-bg: #fff3e0;
+
+  --shadow-sm: 0 1px 3px rgba(0,0,0,0.08);
+  --shadow-md: 0 4px 12px rgba(0,0,0,0.1);
+  --shadow-lg: 0 8px 24px rgba(0,0,0,0.12);
+  --radius: 12px;
+  --radius-sm: 8px;
+}
+
+/* ===== Utility classes ===== */
+.page-container {
+  max-width: 1400px;
+  margin: 0 auto;
+  padding: 24px;
+}
+
+.card {
+  background: #fff;
+  border-radius: var(--radius);
+  box-shadow: var(--shadow-sm);
+  overflow: hidden;
+  transition: box-shadow 0.2s;
+
+  &:hover {
+    box-shadow: var(--shadow-md);
+  }
+}
+
+.badge {
+  display: inline-flex;
+  align-items: center;
+  gap: 4px;
+  padding: 3px 10px;
+  border-radius: 20px;
+  font-size: 12px;
+  font-weight: 500;
+  line-height: 1.4;
+
+  &.grade-s { background: var(--grade-s-bg); color: var(--grade-s); }
+  &.grade-a { background: var(--grade-a-bg); color: var(--grade-a); }
+  &.grade-b { background: var(--grade-b-bg); color: var(--grade-b); }
+  &.grade-c { background: var(--grade-c-bg); color: var(--grade-c); }
+
+  &.cat-a { background: var(--cat-a-bg); color: var(--cat-a); }
+  &.cat-b { background: var(--cat-b-bg); color: var(--cat-b); }
+  &.cat-c { background: var(--cat-c-bg); color: var(--cat-c); }
+  &.cat-d { background: var(--cat-d-bg); color: var(--cat-d); }
+}
+
+/* Scrollbar */
+::-webkit-scrollbar {
+  width: 6px;
+  height: 6px;
+}
+::-webkit-scrollbar-track {
+  background: transparent;
+}
+::-webkit-scrollbar-thumb {
+  background: #ccc;
+  border-radius: 3px;
+}
+::-webkit-scrollbar-thumb:hover {
+  background: #aaa;
+}

+ 15 - 0
lead-discovery/tsconfig.app.json

@@ -0,0 +1,15 @@
+/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
+/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
+{
+  "extends": "./tsconfig.json",
+  "compilerOptions": {
+    "outDir": "./out-tsc/app",
+    "types": []
+  },
+  "files": [
+    "src/main.ts"
+  ],
+  "include": [
+    "src/**/*.d.ts"
+  ]
+}

+ 33 - 0
lead-discovery/tsconfig.json

@@ -0,0 +1,33 @@
+/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
+/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
+{
+  "compileOnSave": false,
+  "compilerOptions": {
+    "outDir": "./dist/out-tsc",
+    "strict": true,
+    "noImplicitOverride": true,
+    "noPropertyAccessFromIndexSignature": true,
+    "noImplicitReturns": true,
+    "noFallthroughCasesInSwitch": true,
+    "skipLibCheck": true,
+    "isolatedModules": true,
+    "esModuleInterop": true,
+    "sourceMap": true,
+    "declaration": false,
+    "experimentalDecorators": true,
+    "moduleResolution": "bundler",
+    "importHelpers": true,
+    "target": "ES2022",
+    "module": "ES2022",
+    "lib": [
+      "ES2022",
+      "dom"
+    ]
+  },
+  "angularCompilerOptions": {
+    "enableI18nLegacyMessageIdFormat": false,
+    "strictInjectionParameters": true,
+    "strictInputAccessModifiers": true,
+    "strictTemplates": true
+  }
+}

+ 15 - 0
lead-discovery/tsconfig.spec.json

@@ -0,0 +1,15 @@
+/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
+/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
+{
+  "extends": "./tsconfig.json",
+  "compilerOptions": {
+    "outDir": "./out-tsc/spec",
+    "types": [
+      "jasmine"
+    ]
+  },
+  "include": [
+    "src/**/*.spec.ts",
+    "src/**/*.d.ts"
+  ]
+}